fix(ci): make changelog promotion idempotent and structure-preserving #68

Merged
jmiller merged 1 commits from fix/changelog-promote-structure into dev 2026-07-18 21:45:49 +00:00
+27 -6
View File
@@ -349,13 +349,34 @@ jobs:
if [ -n "$VERSION" ] && [ -f "CHANGELOG.md" ]; then
DATE=$(date +%Y-%m-%d)
python3 -c "
import sys
import sys, re
version, date = sys.argv[1], sys.argv[2]
content = open('CHANGELOG.md').read()
old = '## [Unreleased]'
new = f'## [Unreleased]\n\n## [{version}] --- {date}'
content = content.replace(old, new, 1)
open('CHANGELOG.md', 'w').write(content)
with open('CHANGELOG.md', 'r', newline='') as f:
raw = f.read()
eol = '\r\n' if '\r\n' in raw else '\n'
content = raw.replace('\r\n', '\n')
m = re.search(r'(?m)^## \[', content)
if not m:
sys.exit(0)
head, rest = content[:m.start()], content[m.start():]
tokens = re.split(r'(?m)(^## \[.*)', rest)
sections, i = [], 1
while i < len(tokens):
sections.append([tokens[i], tokens[i+1] if i+1 < len(tokens) else ''])
i += 2
out, promoted = head, False
for header, body in sections:
if header.strip() == '## [Unreleased]' and re.search(r'(?m)^\s*(###\s|[-*]\s)\S', body):
out += '## [Unreleased]\n\n' + f'## [{version}] --- {date}' + body
promoted = True
else:
out += header + body
if not promoted:
sys.exit(0)
if eol != '\n':
out = out.replace('\n', eol)
with open('CHANGELOG.md', 'w', newline='') as f:
f.write(out)
" "$VERSION" "$DATE"
git add CHANGELOG.md
git commit -m "chore: promote changelog [Unreleased] → [${VERSION}]" || true