@@ -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