Skip to content

Commit 441f552

Browse files
MaxGhenisclaude
andauthored
Migrate from changelog_entry.yaml to towncrier fragments (#284)
* Migrate from changelog_entry.yaml to towncrier fragments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update CI workflows for towncrier and format bump_version.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Delete old changelog files --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c118c06 commit 441f552

File tree

8 files changed

+138
-618
lines changed

8 files changed

+138
-618
lines changed

.github/bump_version.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"""Infer semver bump from towncrier fragment types and update version."""
2+
3+
import re
4+
import sys
5+
from pathlib import Path
6+
7+
8+
def get_current_version(pyproject_path: Path) -> str:
9+
text = pyproject_path.read_text()
10+
match = re.search(r'^version\s*=\s*"(\d+\.\d+\.\d+)"', text, re.MULTILINE)
11+
if not match:
12+
print(
13+
"Could not find version in pyproject.toml",
14+
file=sys.stderr,
15+
)
16+
sys.exit(1)
17+
return match.group(1)
18+
19+
20+
def infer_bump(changelog_dir: Path) -> str:
21+
fragments = [
22+
f
23+
for f in changelog_dir.iterdir()
24+
if f.is_file() and f.name != ".gitkeep"
25+
]
26+
if not fragments:
27+
print("No changelog fragments found", file=sys.stderr)
28+
sys.exit(1)
29+
30+
categories = {f.suffix.lstrip(".") for f in fragments}
31+
for f in fragments:
32+
parts = f.stem.split(".")
33+
if len(parts) >= 2:
34+
categories.add(parts[-1])
35+
36+
if "breaking" in categories:
37+
return "major"
38+
if "added" in categories or "removed" in categories:
39+
return "minor"
40+
return "patch"
41+
42+
43+
def bump_version(version: str, bump: str) -> str:
44+
major, minor, patch = (int(x) for x in version.split("."))
45+
if bump == "major":
46+
return f"{major + 1}.0.0"
47+
elif bump == "minor":
48+
return f"{major}.{minor + 1}.0"
49+
else:
50+
return f"{major}.{minor}.{patch + 1}"
51+
52+
53+
def update_file(path: Path, old_version: str, new_version: str):
54+
text = path.read_text()
55+
updated = text.replace(
56+
f'version = "{old_version}"',
57+
f'version = "{new_version}"',
58+
)
59+
if updated != text:
60+
path.write_text(updated)
61+
print(f" Updated {path}")
62+
63+
64+
def main():
65+
root = Path(__file__).resolve().parent.parent
66+
pyproject = root / "pyproject.toml"
67+
changelog_dir = root / "changelog.d"
68+
69+
current = get_current_version(pyproject)
70+
bump = infer_bump(changelog_dir)
71+
new = bump_version(current, bump)
72+
73+
print(f"Version: {current} -> {new} ({bump})")
74+
75+
update_file(pyproject, current, new)
76+
77+
78+
if __name__ == "__main__":
79+
main()
Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,21 @@
1-
name: Versioning
1+
name: Changelog entry
22

33
on:
44
pull_request:
5-
branches: [ main ]
5+
branches: [main]
66

77
jobs:
8-
check-changelog-entry:
9-
name: Changelog entry check
8+
check-changelog:
9+
name: Check changelog fragment
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v3
13-
14-
- name: Check for changelog entry
12+
- uses: actions/checkout@v4
13+
- name: Check for changelog fragment
1514
run: |
16-
if [ ! -f "changelog_entry.yaml" ]; then
17-
echo "Error: changelog_entry.yaml file is missing."
18-
echo "Please add a changelog_entry.yaml file at the root of the repository."
15+
FRAGMENTS=$(find changelog.d -type f ! -name '.gitkeep' | wc -l)
16+
if [ "$FRAGMENTS" -eq 0 ]; then
17+
echo "::error::No changelog fragment found in changelog.d/"
18+
echo "Add one with: echo 'Description.' > changelog.d/\$(git branch --show-current).<type>.md"
19+
echo "Types: added, changed, fixed, removed, breaking"
1920
exit 1
2021
fi
21-
22-
# Check if the file is empty
23-
if [ ! -s "changelog_entry.yaml" ]; then
24-
echo "Error: changelog_entry.yaml file is empty."
25-
echo "Please add content to the changelog_entry.yaml file."
26-
exit 1
27-
fi
28-
29-
echo "Changelog entry found and is not empty."

.github/workflows/versioning.yaml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
- main
88

99
paths:
10-
- changelog_entry.yaml
10+
- changelog.d/**
1111
- "!pyproject.toml"
1212

1313
jobs:
@@ -19,19 +19,20 @@ jobs:
1919
- name: Checkout repo
2020
uses: actions/checkout@v4
2121
with:
22-
repository: ${{ github.event.pull_request.head.repo.full_name }}
23-
ref: ${{ github.event.pull_request.head.ref }}
2422
token: ${{ secrets.POLICYENGINE_GITHUB }}
23+
fetch-depth: 0
2524
- name: Setup Python
2625
uses: actions/setup-python@v5
2726
with:
2827
python-version: 3.12
29-
- name: Build changelog
30-
run: pip install yaml-changelog && make changelog
31-
- name: Preview changelog update
32-
run: ".github/get-changelog-diff.sh"
28+
- name: Install towncrier
29+
run: pip install towncrier
30+
- name: Bump version and build changelog
31+
run: |
32+
python .github/bump_version.py
33+
towncrier build --yes --version $(python -c "import re; print(re.search(r'version = \"(.+?)\"', open('pyproject.toml').read()).group(1))")
3334
- name: Update changelog
3435
uses: EndBug/add-and-commit@v9
3536
with:
3637
add: "."
37-
message: Update package version
38+
message: Update package version

Makefile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,5 @@ publish:
3030
twine upload dist/*
3131

3232
changelog:
33-
build-changelog changelog.yaml --output changelog.yaml --update-last-date --start-from 1.0.0 --append-file changelog_entry.yaml
34-
build-changelog changelog.yaml --org PolicyEngine --repo policyengine-us-data --output CHANGELOG.md --template .github/changelog_template.md
35-
bump-version changelog.yaml pyproject.toml
36-
rm changelog_entry.yaml || true
37-
touch changelog_entry.yaml
33+
python .github/bump_version.py
34+
towncrier build --yes --version $$(python -c "import re; print(re.search(r'version = \"(.+?)\"', open('pyproject.toml').read()).group(1))")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Migrated from changelog_entry.yaml to towncrier fragments to eliminate merge conflicts.

0 commit comments

Comments
 (0)