From f96b65576fa95a50cba6d57a2e4918745ba05b30 Mon Sep 17 00:00:00 2001 From: ScreenTinker Date: Thu, 25 Jun 2026 12:26:23 -0500 Subject: [PATCH] chore(release): guard bump-version.sh against a diverged origin/main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a pre-push fast-forward check: fetch origin/main and abort if it has commits not in local HEAD, BEFORE the annotated tag is created. Prevents the beta9 incident where origin/main had advanced by one commit so 'git push origin main' was rejected, but the tag pushed anyway and fired release.yml from a commit not on main. Best-effort fetch — warns and proceeds when offline (the push stays the backstop). Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/bump-version.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index 4b2e510..e6848e7 100755 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -17,6 +17,25 @@ if [ -n "$(git status --porcelain)" ]; then exit 1 fi +# Pre-push fast-forward guard. This script creates an annotated tag locally; if +# origin/main has advanced past the commit we're bumping from, `git push origin main` +# is rejected as a non-fast-forward - and if the tag gets pushed anyway it fires the +# release workflow from a commit that isn't even on main (the beta9 divergence +# incident). Catch the divergence HERE, before the tag exists, so nothing can fire. +# Best-effort: when the fetch can't run (offline), warn and proceed rather than block +# a local bump - the push itself is still the backstop. +if git fetch --quiet origin main 2>/dev/null; then + if ! git merge-base --is-ancestor FETCH_HEAD HEAD; then + echo "ERROR: origin/main ($(git rev-parse --short FETCH_HEAD)) has commits not in your" >&2 + echo " HEAD ($(git rev-parse --short HEAD)) - 'git push origin main' would be rejected." >&2 + echo " Merge origin/main into your branch first, then re-run the bump." >&2 + exit 1 + fi +else + echo "WARNING: could not fetch origin/main - skipping the fast-forward check (offline?)." >&2 + echo " Confirm 'git push origin main' will fast-forward before pushing the tag." >&2 +fi + CURRENT="$(cat VERSION)" IFS=. read -r MAJ MIN PAT <<< "$CURRENT"