fix: make minor version bump fully idempotent on retrigger#7276
Merged
Conversation
When Nina retriggered the centralized version-bump pipeline yesterday after our 9.5.0 bump had already succeeded, cloudbeat-version-bump #36 re-ran bump-minor.sh with the same env vars (NEW_VERSION=9.5.0). At that point main was at 9.6.0 (from #7268), and the sed inside update_version_beat happily rewrote version.go from 9.6.0 back to 9.5.0. The existing no_new_commits guard couldn't tell the difference between "advance forward" and "regress backward" — it only asks "did anything change vs main?" — so the regression commits passed the check and the script pushed the resulting PR #7275 (now closed). Two-layer fix: 1. bump-minor.sh: top-level guard. If main is already at next_minor_version(NEW_VERSION) (e.g. main=9.6.0 while NEW_VERSION=9.5.0), the entire bump has already completed. Exit 0 before touching any files. 2. common.sh: new is_downgrade() helper (using sort -V so 9.10.0 > 9.9.0 works correctly). update_version_beat and update_arm_templates now call it before writing: if the current value is >= the target, they refuse the write and log a clear message. Belt-and-suspenders — even if a caller forgets the top-level guard, no downgrade can escape the shared helper. bump-patch.sh and post-minor-merge.sh are unchanged; patch bumps only ever advance forward, and post-minor-merge is already idempotent via its branch-exists check plus no_new_commits. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
|
This pull request does not have a backport label. Could you fix it @gsarantid? 🙏
|
groman92
approved these changes
Jul 9, 2026
Contributor
|
Tick the box to add this pull request to the merge queue (same as
|
Defensive addition to branch_out() in post-minor-merge.sh: if main's
version.go doesn't match NEW_VERSION at the moment we're about to cut
the release branch, refuse and exit non-zero.
This closes a related idempotency gap: if main has been advanced (e.g.
via manual intervention outside the pipeline, or an out-of-order
run) but the release branch was never cut, the previous branch_out()
would silently cut ${BRANCH} from current main — producing a "9.5"
release branch pointing at 9.6.0 code. The new check catches this and
requires a human to create the branch manually from the correct
commit, matching the fail-fast philosophy already used by
fail_if_stale_remote_branch (from #7227).
Doesn't affect the normal flow — main == NEW_VERSION at cut time on
a clean pipeline run — and the pre-existing "branch already exists"
short-circuit still fires first when the branch is already cut.
Co-authored-by: Cursor <cursoragent@cursor.com>
groman92
approved these changes
Jul 9, 2026
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
When Nina retriggered unified-release-centralized-version-bump #35 yesterday after our
9.5.0minor bump had already succeeded, cloudbeat-version-bump #36 re-ranbump-minor.shwith the same env vars (WORKFLOW=minor BRANCH=9.5 NEW_VERSION=9.5.0). By thenmainwas at9.6.0(from merged #7268), and thesedinsideupdate_version_beatunconditionally rewroteversion.goback to9.5.0, opening the now-closed #7275 — a PR proposing to downgrademain(verified:defaultBeatVersionand 4 ARMdefaultValuefields all flipped9.6.0->9.5.0).The existing
no_new_commitsguard couldn't tell the difference between "advance forward" and "regress backward" — it only asks "did anything change vs main?" — so the regression commits passed the check and got pushed.This PR closes that gap and a related one in
post-minor-merge.sh, with defense in depth so no future retrigger can produce a bad PR or a wrong-content release branch.Fix — three layers
1. Top-level guard in
bump-minor.shIf
mainis already atnext_minor_version(NEW_VERSION)(e.g.main=9.6.0whileNEW_VERSION=9.5.0), the entire minor bump has completed. Exit0before touching any files.2. Hardened shared helpers in
common.shNew
is_downgrade()helper usingsort -V(so9.10.0 > 9.9.0sorts correctly).update_version_beatandupdate_arm_templatesnow call it before writing: if the current value is already>=the target, they refuse and log a clear message. Belt-and-suspenders — even if a future caller forgets the top-level guard, no downgrade can escape the shared helper.3. Sanity check in
post-minor-merge.sh'sbranch_out()If
mainhas drifted fromNEW_VERSIONat the moment we're about to cut the release branch, refuse and exit non-zero. Closes a related edge case (spotted during review): ifmainwas advanced (e.g. via manual intervention or an out-of-order run) but the release branch was never cut,branch_out()previously would have silently cut${BRANCH}from currentmain— producing a9.5release branch pointing at9.6.0code. Same philosophy asfail_if_stale_remote_branch(from #7227): detect the anomaly, fail clearly, require a human to fix the underlying state.Related history
no_new_commitsidempotency (for retriggering completed patch bumps)fail_if_stale_remote_branch)Explicit non-goals
bump-patch.shunchanged — patch bumps only advance forward, no regression risk.bump_main_to_next_minor()inpost-minor-merge.shunchanged — verified already idempotent (no_new_commitscatches the "main already at target" case as a genuine sed no-op).Test plan
is_downgradeunit tests — 9 cases pass, including the multi-digit9.9.0->9.10.0case that naive lexical comparison would get wrong.main(=9.6.0) withNEW_VERSION=9.5.0 DRY_RUN=true— exits 0 immediately withmain is already at 9.6.0 — minor bump for 9.5.0 has already completed. Idempotent no-op.No branch, no commits, no PR.9.5.0,NEW_VERSION=9.7.0) — guard doesn't fire, full flow proceeds throughupdate_version_beat(9.5.0->9.7.0),update_arm_templates,update_mergify, and wouldgh pr create.update_version_beatunit tests — regression attempt (9.6.0->9.5.0) prints refusal and doesn't commit; upgrade (9.6.0->9.7.0) commits cleanly; no-op (9.7.0->9.7.0) doesn't create duplicate commits.branch_out()sanity check — three paths validated:maindrifted -> refuses with clear error, exits 1maincorrect -> proceeds normally (dry-run)shellcheckclean onbump-minor.sh,common.sh, andpost-minor-merge.sh.After merge
Cloudbeat-version-bump #36 becomes safe to unblock at its
Wait for PR mergegate —post-minor-merge.shis already idempotent, sobranch_out()short-circuits (branch exists),bump_main_to_next_minor()no-ops (main already at9.6.0), and the DRA-artifacts poll finds the already-published9.5.0artifacts.