33Update CHANGELOG.md after a release PR is merged.
44
55Usage:
6- python scripts/update-changelog.py <version> <commit> <pr_number> <prev_commit>
6+ python scripts/update-changelog.py <version> <commit> <prev_commit>
7+ python scripts/update-changelog.py --extract-section <version>
78
89Example:
9- python scripts/update-changelog.py 2025-11-26 6bc34f1 326 2be0cff
10+ python scripts/update-changelog.py 2025-11-26 6bc34f1 2be0cff
11+ python scripts/update-changelog.py --extract-section 2025-11-26
1012
1113This script:
12141. Creates a new dated release section with the content from "Unreleased"
13152. Updates the "Unreleased" diff link to start from the new release commit
16+ 3. Links the version header to the GitHub Release page
17+ 4. Can extract a specific version's section for use in release notes
1418"""
1519
1620import re
1721import sys
1822
1923
20- def update_changelog (version : str , commit : str , pr_number : str , prev_commit : str ) -> bool :
24+ def extract_unreleased_content () -> str :
25+ """Extract content from the Unreleased section (for use before update)."""
26+ with open ('CHANGELOG.md' , 'r' ) as f :
27+ content = f .read ()
28+
29+ # Pattern to match the Unreleased section header and metadata
30+ unreleased_header = r'## Unreleased\n\n- Commit: \[`HEAD`\]\(https://github\.com/aviatesk/JETLS\.jl/commit/HEAD\)\n- Diff: \[`[a-f0-9]+\.\.\.HEAD`\]\(https://github\.com/aviatesk/JETLS\.jl/compare/[a-f0-9]+\.\.\.HEAD\)\n'
31+
32+ # Find everything between the Unreleased header and the next release section
33+ pattern = f'({ unreleased_header } )(.*?)(## \\ d{{4}}-\\ d{{2}}-\\ d{{2}})'
34+ match = re .search (pattern , content , re .DOTALL )
35+
36+ if not match :
37+ return ""
38+
39+ return match .group (2 ).strip ()
40+
41+
42+ def update_changelog (version : str , commit : str , prev_commit : str ) -> bool :
2143 with open ('CHANGELOG.md' , 'r' ) as f :
2244 content = f .read ()
2345
2446 # Check if the release section already exists
25- if re .search (rf'^## \[ { re .escape (version )} \] ' , content , re .MULTILINE ):
47+ if re .search (rf'^## { re .escape (version )} $ ' , content , re .MULTILINE ):
2648 print (f"Release { version } already exists in CHANGELOG.md, skipping update" )
2749 return False
2850
2951 # Pattern to match the Unreleased section header and metadata
30- unreleased_header = r'## Unreleased\n\n> \[!note\]\n>\n> - Commit: \[`HEAD`\]\(https://github\.com/aviatesk/JETLS\.jl/commit/HEAD\)\n> - Diff: \[`[a-f0-9]+\.\.\.HEAD`\]\(https://github\.com/aviatesk/JETLS\.jl/compare/[a-f0-9]+\.\.\.HEAD\)\n'
52+ unreleased_header = r'## Unreleased\n\n- Commit: \[`HEAD`\]\(https://github\.com/aviatesk/JETLS\.jl/commit/HEAD\)\n- Diff: \[`[a-f0-9]+\.\.\.HEAD`\]\(https://github\.com/aviatesk/JETLS\.jl/compare/[a-f0-9]+\.\.\.HEAD\)\n'
3153
3254 # Find everything between the Unreleased header and the next release section
33- pattern = f'({ unreleased_header } )(.*?)(## \\ [ \\ d{{4}}-\\ d{{2}}-\\ d{{2}}\\ ] )'
55+ pattern = f'({ unreleased_header } )(.*?)(## \\ d{{4}}-\\ d{{2}}-\\ d{{2}})'
3456 match = re .search (pattern , content , re .DOTALL )
3557
3658 if not match :
@@ -43,22 +65,16 @@ def update_changelog(version: str, commit: str, pr_number: str, prev_commit: str
4365 # Build the new Unreleased header with updated commit
4466 new_unreleased_header = f"""## Unreleased
4567
46- > [!note]
47- >
48- > - Commit: [`HEAD`](https://github.com/aviatesk/JETLS.jl/commit/HEAD)
49- > - Diff: [`{ commit } ...HEAD`](https://github.com/aviatesk/JETLS.jl/compare/{ commit } ...HEAD)
68+ - Commit: [`HEAD`](https://github.com/aviatesk/JETLS.jl/commit/HEAD)
69+ - Diff: [`{ commit } ...HEAD`](https://github.com/aviatesk/JETLS.jl/compare/{ commit } ...HEAD)
5070
5171"""
5272
5373 # Build the new release section
54- new_release_section = f"""## [ { version } ]
74+ new_release_section = f"""## { version }
5575
56- [{ version } ]: https://github.com/aviatesk/JETLS.jl/pull/{ pr_number }
57-
58- > [!note]
59- >
60- > - Commit: [`{ commit } `](https://github.com/aviatesk/JETLS.jl/commit/{ commit } )
61- > - Diff: [`{ prev_commit } ...{ commit } `](https://github.com/aviatesk/JETLS.jl/compare/{ prev_commit } ...{ commit } )
76+ - Commit: [`{ commit } `](https://github.com/aviatesk/JETLS.jl/commit/{ commit } )
77+ - Diff: [`{ prev_commit } ...{ commit } `](https://github.com/aviatesk/JETLS.jl/compare/{ prev_commit } ...{ commit } )
6278
6379"""
6480
@@ -78,17 +94,24 @@ def update_changelog(version: str, commit: str, pr_number: str, prev_commit: str
7894
7995
8096def main () -> int :
81- if len (sys .argv ) != 5 :
82- print (f"Usage: { sys .argv [0 ]} <version> <commit> <pr_number> <prev_commit>" )
83- print (f"Example: { sys .argv [0 ]} 2025-11-26 6bc34f1 326 2be0cff" )
97+ if len (sys .argv ) >= 2 and sys .argv [1 ] == '--extract-unreleased' :
98+ content = extract_unreleased_content ()
99+ if content :
100+ print (content )
101+ return 0
102+ return 1
103+
104+ if len (sys .argv ) != 4 :
105+ print (f"Usage: { sys .argv [0 ]} <version> <commit> <prev_commit>" )
106+ print (f" { sys .argv [0 ]} --extract-unreleased" )
107+ print (f"Example: { sys .argv [0 ]} 2025-11-26 6bc34f1 2be0cff" )
84108 return 1
85109
86110 version = sys .argv [1 ]
87111 commit = sys .argv [2 ]
88- pr_number = sys .argv [3 ]
89- prev_commit = sys .argv [4 ]
112+ prev_commit = sys .argv [3 ]
90113
91- if update_changelog (version , commit , pr_number , prev_commit ):
114+ if update_changelog (version , commit , prev_commit ):
92115 return 0
93116 return 1
94117
0 commit comments