fix(release): harden tag-based publish workflow and document process - #62
Conversation
Align Release CI with vX.Y.Z tags: gate tag against pyproject version, require a matching CHANGELOG section, and add a maintainer release checklist without bumping the package version. Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7ee9cb7ba7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - name: Extract changelog for this version | ||
| run: | | ||
| awk '/## Release/{if (flag==1)exit;else;flag=1;next} flag' CHANGELOG.md > .changelog.md | ||
| set -euo pipefail |
There was a problem hiding this comment.
Validate changelog before publishing to PyPI
When a maintainer tags a matching version but forgets to build the Towncrier section, the missing/empty changelog checks in this step fail only after pypa/gh-action-pypi-publish has already uploaded immutable files. That leaves a partial release and a normal rerun will hit PyPI's duplicate version/file rejection, so the changelog extraction and validation need to run before the PyPI publish step.
Useful? React with 👍 / 👎.
| awk -v ver="$TAG_VERSION" ' | ||
| BEGIN { hdr = "## Release v" ver } | ||
| index($0, hdr) == 1 { |
There was a problem hiding this comment.
Match the changelog header exactly
When the tag version is a prefix of another release header, such as v0.9.1 with an existing ## Release v0.9.15 section or stable v0.10.0 with only v0.10.0a1, this prefix match selects the wrong section and the later grep check also passes. That can create a GitHub Release with another version's notes; require the header to match the version boundary, e.g. the following space/date separator, instead of any prefix.
Useful? React with 👍 / 👎.
| @@ -0,0 +1 @@ | |||
| Document the release checklist and harden the tag-based PyPI/GitHub Release workflow (version gate, ``v``-prefix tags, changelog extraction). | |||
There was a problem hiding this comment.
Use a numeric Towncrier fragment id
This fragment is named SHA-36.doc, but the repository's Towncrier guidance expects an issue number; with the configured GitHub issue URL format, building the changelog will render a #SHA-36 link to /issues/SHA-36 rather than a valid numeric issue. Please rename the fragment to the corresponding numeric issue id, or change the configured linking scheme first.
AGENTS.md reference: AGENTS.md:L129-L137
Useful? React with 👍 / 👎.
Validate the matching CHANGELOG section before PyPI publish, and match release headers on a version boundary so shorter prefixes cannot select another release's notes. Co-authored-by: multica-agent <github@multica.ai>
|
Addressed Codex review feedback:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9e42c3910c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| echo "Run: uv run towncrier build --version ${TAG_VERSION}" >&2 | ||
| exit 1 | ||
| fi | ||
| if [[ ! -s .changelog.md ]]; then |
There was a problem hiding this comment.
Check changelog content after the header
The fresh issue is that this new -s check counts the extracted header itself as content; when CHANGELOG.md contains the matching ## Release header but no release-note lines (for example a manually added header or otherwise empty release section), .changelog.md is still non-empty, so the workflow can publish to PyPI and create a GitHub Release with no user-facing notes. Validate that there is content after the header instead of checking only file size.
AGENTS.md reference: AGENTS.md:L129-L139
Useful? React with 👍 / 👎.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #62 +/- ##
=======================================
Coverage 92.72% 92.72%
=======================================
Files 36 36
Lines 2721 2721
Branches 461 461
=======================================
Hits 2523 2523
Misses 117 117
Partials 81 81 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Summary
Implements the SHA-36 P0/P1 release-process fixes discussed on the Multica issue (no version bump, no publish).
Workflow (
.github/workflows/publish.yml)v*tags (removed catch-all tags andworkflow_dispatch)vX.Y.Zstable vs PEP 440-style prereleases (v0.9.16a1, …)v) must equalpyproject.toml[project].versionuv build, assert wheel/sdist version matches the tag## Release vX.Y.Zsection (keep header); fail if missing/emptytag_nameand correctprereleaseflagDocs
docs/RELEASING.mdmaintainer checklistAGENTS.mdandREADME.mdnews/SHA-36.docPackage version remains 0.9.15. This PR does not push tags or publish to PyPI.
Test plan
v0.9.15matchespyprojectversion; bare0.9.15rejected0.9.15returns the expected section with headerv0.9.16a1docs/RELEASING.md(separate bump + tag)