Skip to content

Commit f9d84e2

Browse files
committed
ci(regen): seed changelog under [Unreleased], drop version bump
1 parent bd6cd72 commit f9d84e2

1 file changed

Lines changed: 40 additions & 31 deletions

File tree

.github/workflows/regenerate.yml

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -63,53 +63,62 @@ jobs:
6363
- name: Clean generated source
6464
run: rm -rf src/apis src/models docs
6565

66-
# Cargo.toml is ignore-protected, so the generator no longer rewrites the
67-
# version. We own the patch bump here via cargo-edit and feed the result
68-
# to the generator as packageVersion + user-agent for consistency.
69-
- name: Bump patch version
66+
# Read (do NOT bump) the current crate version. A regen is just a set of
67+
# changes; which release ships them — and the bump kind — is decided later
68+
# by the release tooling, not minted per regen. The version is still read
69+
# here because the generator bakes it into the default user-agent and
70+
# packageVersion below, so generated output reflects the committed crate
71+
# version (Cargo.toml is ignore-protected, so the generator never edits it).
72+
- name: Read package version
7073
id: pkg
7174
run: |
72-
cargo install cargo-edit --locked >/dev/null 2>&1 || cargo install cargo-edit
73-
cargo set-version --bump patch
7475
version=$(cargo metadata --no-deps --format-version 1 \
7576
| jq -r '.packages[] | select(.name=="hotdata") | .version')
7677
echo "version=$version" >> "$GITHUB_OUTPUT"
7778
78-
# check-release.yml gates merges on a `## [x.y.z]` CHANGELOG section
79-
# matching the bumped version, so without a seeded entry every regen PR
80-
# fails that check. Insert a stub (the spec-change title under ### Changed)
81-
# just above the most recent released section; the PR author refines the
82-
# wording before merge. Idempotent: skips if a section for this version
83-
# already exists.
84-
- name: Seed changelog entry
79+
# Seed the regen notes under [Unreleased] so they accumulate there until a
80+
# release rolls them into a version. check-release.py is a no-op when the
81+
# version is unchanged, so a non-bumping regen PR still passes; the regen
82+
# still touches CHANGELOG.md, so check-release.yml runs as before.
83+
- name: Seed changelog entry under [Unreleased]
8584
env:
86-
VERSION: ${{ steps.pkg.outputs.version }}
8785
TITLE: ${{ inputs.title }}
8886
run: |
89-
export CHANGELOG_DATE=$(date -u +%Y-%m-%d)
9087
python3 - <<'PY'
9188
import os, pathlib, re
92-
version = os.environ["VERSION"]
93-
date = os.environ["CHANGELOG_DATE"]
9489
title = (os.environ.get("TITLE") or "").strip() \
9590
or "Regenerate the client from the updated Hotdata OpenAPI spec"
91+
bullet = f"- {title}"
9692
path = pathlib.Path("CHANGELOG.md")
9793
text = path.read_text()
98-
if re.search(rf"^## \[{re.escape(version)}\]", text, re.M):
99-
print(f"CHANGELOG already has a [{version}] section; leaving it untouched.")
100-
raise SystemExit(0)
101-
unreleased = re.search(r"^## \[Unreleased\]", text, re.M)
102-
if not unreleased:
94+
95+
heading = re.search(r"^## \[Unreleased\][^\n]*\n", text, re.M)
96+
if not heading:
10397
raise SystemExit("CHANGELOG.md has no '## [Unreleased]' section to anchor the new entry")
104-
# Insert before the first released section after [Unreleased] (falling
105-
# back to end of file) so any pending entries under [Unreleased] stay
106-
# attributed to it rather than being absorbed by the new version.
107-
nxt = re.search(r"^## \[", text[unreleased.end():], re.M)
108-
insert_at = unreleased.end() + nxt.start() if nxt else len(text)
109-
entry = f"## [{version}] - {date}\n\n### Changed\n\n- {title}\n\n"
110-
text = text[:insert_at] + entry + text[insert_at:]
111-
path.write_text(text)
112-
print(f"Inserted CHANGELOG [{version}] section.")
98+
99+
# Scope edits to the [Unreleased] body (up to the next '## [' or EOF).
100+
start = heading.end()
101+
nxt = re.search(r"^## \[", text[start:], re.M)
102+
end = start + nxt.start() if nxt else len(text)
103+
body = text[start:end]
104+
105+
if bullet in body:
106+
print("CHANGELOG [Unreleased] already lists this entry; leaving it untouched.")
107+
raise SystemExit(0)
108+
109+
changed = re.search(r"^### Changed[ \t]*\n", body, re.M)
110+
if changed:
111+
# Prepend the bullet to the existing ### Changed list.
112+
i = changed.end()
113+
while i < len(body) and body[i] == "\n":
114+
i += 1
115+
body = body[:i] + bullet + "\n" + body[i:]
116+
else:
117+
# No ### Changed yet: open one right under the heading.
118+
body = "\n### Changed\n\n" + bullet + "\n\n" + body.lstrip("\n")
119+
120+
path.write_text(text[:start] + body + text[end:])
121+
print("Added regen entry under CHANGELOG [Unreleased].")
113122
PY
114123
115124
- name: Generate client

0 commit comments

Comments
 (0)