From 3a4df4d8c4b75c2e8da0bab39afc5f37956cb886 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Tue, 21 Jul 2026 21:33:26 -0400 Subject: [PATCH] ci(#2504): converge main's auto-backmerge.yml with next (continue-on-error hardening) Delivers the #2506 blast-radius fix to main NOW instead of deferring to the next release. Deferring specifically fails for a hotfix: 1.8.x hotfix branches are cut from the immutable v1.8.0 tag (which lacks this hardening), so a hotfix would carry the un-hardened workflow to main and never converge it. Converging now makes main's backmerge robust regardless of whether the next release is a minor or a hotfix. The only functional change is `continue-on-error: true` on the two version-sync steps (verified byte-diff vs next). main and next are now identical on auto-backmerge.yml. --- .github/workflows/auto-backmerge.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/auto-backmerge.yml b/.github/workflows/auto-backmerge.yml index 58638e92a..d651505db 100644 --- a/.github/workflows/auto-backmerge.yml +++ b/.github/workflows/auto-backmerge.yml @@ -147,12 +147,26 @@ jobs: # when it is absent the bounded fragment reader falls back to a fail-closed # stub and every capability fragment reports "could not be read", failing # the sync. Build the ledger first so fragments materialize. + # + # BLAST-RADIUS CONTAINMENT (#2504): version-sync is best-effort and MUST + # NOT be able to abort the job. The job's load-bearing purpose is to open + # and admin-merge the back-merge PR so `main` becomes an ancestor of + # `next` — the invariant that keeps the next `release → main` merge clean. + # Historically a failure here (missing build:lib after a workflow-copy + # regression, or any `npm version` lifecycle hiccup) skipped "Open PR" and + # left `main` diverged, breaking the following release. `continue-on-error` + # on both steps below keeps the ancestry PR unconditional: a sync failure + # is surfaced (the step shows red) but only costs a stale `next` version, + # which is trivially re-synced — never a broken back-merge. Do not remove; + # a required-steps test (release-backmerge-invariants.test.cjs) enforces it. - name: Install dependencies and build (required by the version-sync hook) if: steps.check.outputs.next_exists == 'true' + continue-on-error: true run: npm ci --silent && npm run build:lib - name: Sync next's version to main's released version if: steps.check.outputs.next_exists == 'true' + continue-on-error: true run: | set -euo pipefail VERSION=$(git show origin/main:package.json | node -pe "JSON.parse(require('fs').readFileSync(0,'utf8')).version")