bug(release): v0.62.4's post-cut manifest bookkeeping never landed — main's release gate is blocked #1444
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#1444
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Every push to main has failed the release gate since 19:02 because v0.62.4's post-cut bookkeeping never landed, and the repo now reads as a prepared-but-uncut release that has in fact shipped.
Measured — 2026-09-07 20:0x, against
origin/main3c8687c2Consequence:
release / decide + act (push)is red on45312fa6,4aade268,0c7f4d4e,3c8687c2— four consecutive main pushes. No cut can be decided while this stands.Likely cause, stated as a hypothesis
rt post-cutdirect-pushes the manifest to main under path α. Threerelease-cutruns failed at 18:53:35, 18:54:47 and 18:57:49 — inside a window where four unrelated merges landed on main (18:51:47, 18:53:53, 18:57:28). A lost push race fits the timing. This forge exposes no job log through the API, so the cause is not established — only the residue is.AC
rt decideleavesblockedprepared-uncut-checkreturns rc=0 on mainPushAuthedis a baregit pushwith no retry and no rebase (internal/prep/git.go:387), the job commits on top of its own checkoute45075a1, andmerge-base --is-ancestor e45075a1 596ce1e4is TRUE, so the push could not fast-forward. Established from code and graph; no log was readable. Original text: is answered — or this tracker says it could not be, naming what was triedAnchor
@bosun, diagnosing the CI red the operator reported. Second instance:
#1356(v0.61.1, same residue, 2026-09-06).bosun referenced this issue2026-09-07 20:14:29 +02:00
AC3 answered — from the CODE and the commit graph, because this forge exposes no job log
The hypothesis on the body said "a lost push race fits the timing" and called the cause unestablished. It is now established well enough to act on, without a log.
①
post-cut's push has no retry and no rebaseA bare
git push.post_cut.go:176calls it withorigin <baseBranch>; a non-fast-forward is returned as an error andrunPostCutaborts beforeverifyPostCutManifest.It does fetch — twice — and neither fetch rebases.
postCutPrecheck(:344) fetches to READ the remote manifest;verifyPostCutManifest(:595) fetches to CHECK the push landed. There is no fetch-then-rebase between the commit and the push.② The commit graph makes the rejection unavoidable, not merely likely
The job commits the manifest on top of its own checkout, which is the triggering commit
e45075a1.git merge-base --is-ancestor e45075a1 596ce1e4→ true. Main moved past the checkout before any of the three runs could reach the push, so a bare push of a commit parented one45075a1could not fast-forward. No log is needed to know that.③ The residue is exactly what that failure leaves
Tag and release are created by
rt release, which runs BEFORE the bookkeeping. So the observable state — tag present, release published with assets, manifest untouched — is the signature of an abort at the push and at no other step.And it predicts the second instance:
v0.61.1has the same signature (tag on the prepare commit, nopin action imagecommit, no manifest write). Two for two.What is NOT established
Nobody read a
! [rejected]line. If the push failed for another reason the remedy is unchanged, but the diagnosis would be. Recorded as an inference from code plus graph, not as a log reading.The gap this opens, which is bigger than the fix
There is no verb that completes an interrupted cut.
rt recover-pending-cutmoves the section back under[Unreleased]and is destructive once the release has published —prepared-uncut-checksays so in its own refusal. So the only path is a hand-written manifest commit, twice now.Closing.
#1446merged at70911562. All three ACs re-derived on mergedmain, not on the branch.AC3 was answered before the merge, from the code and the commit graph —
PushAuthedis a baregit pushwith no retry and no rebase, the job commits on top of its own checkoute45075a1, andmerge-base --is-ancestor e45075a1 596ce1e4is TRUE, so the push could not fast-forward. Nobody read a! [rejected]line and the tracker says so.The repair is
#1447, with @carpenter — bounded retry with rebase, plus the arm that lands a commit on the base branch between the checkout and the push and watches the unfixed code fail. Without that arm a retry loop cannot be shown to work.📌 What this incident cost, for whoever reads
#1447: four consecutive main pushes red, no cut possible for 78 minutes, and a hand-written manifest commit — the second in two days.