fix(ci): release-please squash-merge auto-tag + populate Release body#133
Merged
Conversation
Two long-standing release-flow bugs surfaced when v0.4.0 / v0.5.0 were cut from this repo's squash-merged release-please PRs: 1. **release-please-action skips the tag-push on squash-merge.** The action only fires tag-push when the release PR is merged via "Create a merge commit." Every release here is squash-merged (per CLAUDE.md), so the action's heuristic finds no merge commit matching its PR's tracked SHA and silently leaves the PR labelled `autorelease: pending`. Subsequent runs then see "untagged release PR outstanding — aborting" and refuse to open a new PR. Fix: a follow-up step in release-please.yml reads the post-merge `.release-please-manifest.json`, computes the expected tag, and pushes it if missing. Identifies the source PR by label + title search, swaps the label to `autorelease: tagged` after tagging so future runs ignore the now-closed loop. Idempotent — unrelated pushes see the tag exists and exit. 2. **GitHub Release body was empty.** `release.yml` used `generate_release_notes: false` and never passed a body, so even the v0.4.0 Release (built via the existing flow) had a blank description. release-please-action normally populates the Release itself, but the new squash-merge auto-tag path bypasses that. Fix: new `extract changelog section` step in release.yml awk's the matching `## [X.Y.Z]` section out of CHANGELOG.md and passes it as `body_path` to softprops/action-gh-release. After this lands, the v0.6.0 cycle should be hands-off: merge the release-please PR (squash is fine), the auto-tag step pushes `v0.6.0`, release.yml builds binaries and creates the Release with populated body — no manual intervention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round 1 findings: - `release.yml` `extract changelog section`: switch from regex `^## \[ver\]` to literal substring `index($0, "## [ver]") == 1`. Stable X.Y.Z values worked because they were unique, but pre-release tags like `0.5.0-rc.1` would mis-match through the regex `.` wildcards. Index-based scan can't be fooled. - `release-please.yml` `auto-tag` PR query: narrow from `--search "in:title chore release"` (any PR with those words in the title) to `--head "release-please--branches--master"` (the exact branch release-please-action publishes). A mis- labelled out-of-band PR with `autorelease: pending` can't be picked up by mistake any more. - `release-please.yml`: defensive `git cat-file -e` before `git tag` so a rebased/force-pushed merge SHA surfaces a clear error instead of `git tag: unknown revision`. Verified locally: the new awk extractor produces identical line counts (151 for 0.5.0, 58 for 0.4.0) as the regex version. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Subagent round 2 nit: `jq -r '.["."]' .release-please-manifest.json`
on a corrupt/empty manifest emits `null`, downstream `tag="v${ver}"`
becomes `vnull`, neither tag-exists check matches, and the script
then tag-pushes a real PR SHA as `vnull` — confusing failure mode.
Regex-check `ver` matches `X.Y.Z[-+rest]` semver before proceeding;
bail loudly with a clear error message otherwise.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Owner
Author
/review-loop complete — 3 rounds, subagent-only
Ready for merge. The PR fixes BOTH the squash-merge auto-tag gap AND the empty Release body — after this lands, v0.6.0 should cut hands-off. 🤖 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two long-standing release-flow bugs surfaced cutting v0.4.0 / v0.5.0:
1. release-please-action skips tag-push on squash-merge
The action only fires tag-push when the release PR is merged via "Create a merge commit." This repo squashes everything (per CLAUDE.md), so the action's heuristic finds no merge commit matching its PR's tracked SHA and silently leaves the PR labelled
autorelease: pending. Subsequent runs then seeuntagged release PR outstanding — abortingand refuse to open a new PR.PR #11 (v0.4.0) and PR #131 (v0.5.0) both required a manual
git tag && git push --tagsto unblock.Fix: follow-up step in
release-please.ymlreads the post-merge.release-please-manifest.json, computes the expected tag, and pushes it if missing. Identifies the source PR by label + title search, swaps the label toautorelease: taggedafter tagging. Idempotent — unrelated pushes see the tag exists and exit.2. GitHub Release body was empty
release.ymlusedgenerate_release_notes: falseand never passed a body, so even the v0.4.0 Release (built via the existing flow) had a blank description. release-please-action normally populates the Release itself when it tags, but the new squash-merge auto-tag path bypasses that.Fix: new
extract changelog sectionstep inrelease.ymlawks the matching## [X.Y.Z]section out of CHANGELOG.md and passes it asbody_pathtosoftprops/action-gh-release@v3.After this lands
The v0.6.0 cycle should be hands-off: merge the release-please PR (squash is fine), the auto-tag step pushes
v0.6.0,release.ymlbuilds binaries AND creates the Release with populated body — no manual intervention.Test plan
awkextraction works locally — extracted v0.4.0 (58 lines) and v0.5.0 (151 lines) sections from CHANGELOG.md.auto-tagstep's idempotency: when v0.5.0 tag already exists, the step's twoif-guards short-circuit out.gh pr list --state merged --label "autorelease: pending" --search "in:title chore release"correctly returns the most recent release PR.gh release edit).🤖 Generated with Claude Code