Skip to content

Commit ec0a935

Browse files
committed
feat: auto-move Unreleased content to version section on release
- Update release.py to automatically move [Unreleased] content to new version section - Add proper date formatting for version entries - Ensure CHANGELOG.md is included in version bump commits
1 parent 9def1bd commit ec0a935

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

scripts/release.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import re
1313
import subprocess
1414
import sys
15+
from datetime import datetime
1516
from pathlib import Path
1617
from typing import Tuple
1718

@@ -51,6 +52,52 @@ def update_version(new_version: str) -> None:
5152
print(f"Updated __init__.py version to {new_version}")
5253

5354

55+
def update_changelog(new_version: str) -> None:
56+
"""Move Unreleased content to new version section in CHANGELOG.md"""
57+
changelog_path = Path("CHANGELOG.md")
58+
if not changelog_path.exists():
59+
print("Warning: CHANGELOG.md not found, skipping changelog update")
60+
return
61+
62+
content = changelog_path.read_text(encoding="utf-8")
63+
64+
# Check if version already exists
65+
if f"## [{new_version}]" in content:
66+
print(f"Version {new_version} already exists in CHANGELOG.md")
67+
return
68+
69+
# Find Unreleased section
70+
import re
71+
from datetime import datetime
72+
73+
unreleased_match = re.search(r"(## \[Unreleased\])(.*?)(?=\n## \[|$)", content, re.DOTALL)
74+
75+
if not unreleased_match:
76+
print("Warning: [Unreleased] section not found in CHANGELOG.md")
77+
return
78+
79+
unreleased_content = unreleased_match.group(2).strip()
80+
81+
if not unreleased_content:
82+
print("Warning: [Unreleased] section is empty")
83+
return
84+
85+
# Get today's date
86+
today = datetime.now().strftime("%Y-%m-%d")
87+
88+
# Create new version section
89+
new_section = f"\n\n## [{new_version}] - {today}\n\n{unreleased_content}"
90+
91+
# Replace content: keep Unreleased header but empty its content
92+
new_content = content.replace(
93+
unreleased_match.group(0),
94+
f"## [Unreleased]{new_section}"
95+
)
96+
97+
changelog_path.write_text(new_content, encoding="utf-8")
98+
print(f"Updated CHANGELOG.md: moved Unreleased content to [{new_version}]")
99+
100+
54101
def parse_version(version: str) -> Tuple[int, int, int]:
55102
"""Parse semantic version string"""
56103
try:
@@ -109,7 +156,7 @@ def create_and_push_tag(version: str, dry_run: bool = False) -> None:
109156

110157
if not dry_run:
111158
# Commit version changes
112-
run_command(["git", "add", "pyproject.toml", "src/repomix/__init__.py"])
159+
run_command(["git", "add", "pyproject.toml", "src/repomix/__init__.py", "CHANGELOG.md"])
113160
run_command(["git", "commit", "-m", f"bump: version {version}"])
114161

115162
# Create tag
@@ -162,8 +209,11 @@ def main():
162209

163210
# Update version files
164211
update_version(new_version)
212+
213+
# Update CHANGELOG
214+
update_changelog(new_version)
165215
else:
166-
print("[DRY RUN] Would update version files")
216+
print("[DRY RUN] Would update version files and CHANGELOG")
167217

168218
# Create and push tag
169219
create_and_push_tag(new_version, args.dry_run)

0 commit comments

Comments
 (0)