fix(release): recover a tag whose release never published #27
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/release-tag-without-release"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What & why
Merging this cuts
v1.1.0→v1.1.1, which is what finally publishes the arm64 sidecar binary. That is the point of doing it now — see "Why this PR exists" below — but the fix is real on its own terms, not a pretext.The bug
An existing tag was treated as "nothing to release", unconditionally:
That is wrong in the one case it matters. A tag with no release behind it means an earlier run tagged and then died before publishing — exactly what happened on
servuo-plugins' first release, where absentREGISTRY_*secrets took the release API call to401after the tag had been pushed. Standing down on the tag alone makes that state permanent: every later run sees the tag, setsRELEASE=false, and the release never appears. The version becomes unpublishable forever, and the only way out is a human deleting a tag.The fix
The tag decides nothing on its own; the API does.
200404The last row matters as much as the others: a
000from a network failure or a401from a bad token is not evidence of absence, and guessing "no release" would republish over a good one.The
404arm deliberately overrides theRELEASE=falsedecided just above it. With the tag in place there are no releasable commits after it, so the normal path always stands down — which is precisely why this could never self-heal.Two consequences handled with it:
previous-tag..this-tagon a recovery run. A run finishing an earlier one has nothing after the tag and would otherwise publish an empty change list.git tagon an existing name fails underset -e; pushing an identical tag is a harmless no-op. A push that does fail there means the remote tag points somewhere else, which should stop the run.This is the same handling
installer/release.ymlalready carries —linkwas the copy that still had the trap.How it was tested
The
planstep was extracted from this branch's YAML and driven through four scenarios against a real clone with the live tags, withcurlstubbed to return each status:v1.1.0released, onefix:sincerelease=true version=1.1.1 bump=patchv1.1.1exists, no release (404)release=true, reuses the tag, changelog fromv1.1.0..v1.1.1v1.1.1exists with a release (200)release=false— stands down::error::… Refusing to guess, exit 1, nothing publishedrelease.ymlalso parses as YAML.Why this PR exists now
link#26 added the
aarch64build, but it was typedci(release):— and the engine only bumps onfeat/fix/perf/breaking. So it correctly declined to release, and no arm64 binary was ever produced:bundles/current.jsonstill names two assets, and installer PLAN.md §5.2 step 3 (promotinglinux-aarch64to a required bundle key) is blocked behind it. The commit type was the mistake — the diff was in CI, but the deliverable was a new artifact for users.This is a genuine fix in the same file, so the patch bump it earns is honest, and
v1.1.1carries the arm64 binary as a side effect rather than as the excuse.⚠ One thing to watch on the run
sidecar/Cargo.tomlstill says0.1.0after five releases, so thechore(release): bump versioncommit has apparently never landed onmain— the version-bump step must be taking its "nothing staged" branch every time. This PR does not change that step, and five releases have published through it. If the push tomainever does start failing there, the job would die after tagging — which is now the recoverable state this PR creates, rather than a permanent one. Worth a look separately.Checklist
AI-assisted contributions (required)
Claude Code (Opus 5). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with aCo-Authored-Bytrailer.License