From 3e972b7812e1634e9edac4b24730fe95a396e1d0 Mon Sep 17 00:00:00 2001 From: Musa Musa Date: Wed, 26 Aug 2026 17:16:01 +0100 Subject: [PATCH] ci: make Release re-triggerable, and write down when bypass is legitimate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both prompted by today's GitHub Actions outage. release.yml fired only on push to main, and a push is a single shot. Actions created zero runs repo-wide for over an hour, so a release commit landing in that window would have consumed its changesets and parked the version on main with nothing on npm — recoverable only by pushing another commit for the sole purpose of firing the event. workflow_dispatch removes that trap, and exposing it costs nothing: changeset publish is a no-op for a version already on the registry, so an accidental dispatch cannot republish or overwrite. CONTRIBUTING now says when the admin bypass on main is legitimate, because a bypass with no stated criteria becomes a habit. Two cases: the checks cannot run at all (platform outage), or a production incident that must land faster than the matrix. Both require running the local equivalents first, and it names which local command covers what — pnpm verify covers everything except the multi-runtime matrix, which only CI can give. It also records the diagnostic lesson: check githubstatus.com before concluding the fault is your branch. The first hour of that outage went on suspecting a workflow-file edit, then a push credential, then pushing a throwaway commit to isolate it. All three wrong, and one status check would have said so immediately. The bypass explicitly does not extend to force-push, deletion or tag immutability. Those have no bypass actor, because they are the rules whose violation destroys work rather than making a mess. --- .changeset/release-dispatch.md | 15 +++++++++++++++ .github/workflows/release.yml | 9 +++++++++ CONTRIBUTING.md | 29 +++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 .changeset/release-dispatch.md diff --git a/.changeset/release-dispatch.md b/.changeset/release-dispatch.md new file mode 100644 index 0000000..ab15093 --- /dev/null +++ b/.changeset/release-dispatch.md @@ -0,0 +1,15 @@ +--- +"resilix": patch +--- + +`release.yml` can now be triggered manually (`workflow_dispatch`). + +The publish fires on a push to `main`, and a push gives exactly one chance to run it. During the +2026-08-26 GitHub Actions outage no runs were created at all, which means a release commit landing +in that window would have consumed its changesets and left the version on `main` with nothing +published — recoverable only by pushing another commit purely to fire the event. Exposing the +dispatch is safe: `changeset publish` is a no-op for a version already on the registry. + +`CONTRIBUTING.md` also now states when the branch-protection bypass is legitimate — a platform +outage or a production incident, with the local checks run first — and that it never extends to +force-push, branch deletion or tag immutability. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 03be0ab..9e26aa3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,15 @@ name: Release on: push: branches: [main] + # Re-triggerable by hand. The publish is driven by a push to main, and a push produces exactly + # one chance to run it: if Actions is unavailable when the release commit lands — as during the + # 2026-08-26 major outage — no run is ever created, changesets has already consumed its + # changesets, and the version sits on main with nothing on npm. Without this the only recovery + # is pushing another commit to main purely to fire the event. + # + # Safe to expose: `changeset publish` is a no-op for a version that is already on the registry, + # so an accidental dispatch cannot republish or overwrite anything. + workflow_dispatch: permissions: contents: write diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6e5d864..a288f80 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -131,6 +131,35 @@ maintainer. pointing at the commit whose provenance attestation says it built `resilix@0.5.0`; a moved tag makes that attestation a lie. +### When the admin bypass is legitimate + +The bypass on `main: PR + green checks` exists so a solo maintainer is never locked out. It is not +a convenience, and "the checks are slow" is not a reason. There are two: + +1. **A platform outage means the checks cannot run at all.** On 2026-08-26 GitHub Actions was in + `major_outage` for over an hour and created zero runs repo-wide. A PR in that window is + `BLOCKED` forever with nothing to wait for. Check + [githubstatus.com](https://www.githubstatus.com) before concluding it is your branch — the + first hour of that outage was spent suspecting a workflow-file edit and then a push credential, + both wrong. +2. **A production incident** where the fix must land faster than a full matrix run. + +In both cases, **run the checks locally first and say so in the merge**: + +```bash +pnpm verify # lint, paths, typecheck, coverage, build, package, smoke, docs +pnpm test:compat # opossum's own suite — not in verify, it needs a network fetch +pnpm test:perf +``` + +`pnpm verify` covers everything the nine required checks do except the multi-runtime matrix, which +only CI can provide. If you bypass, the next green CI run on `main` is what actually confirms it — +watch it. + +The bypass does **not** extend to `main: no force-push, no deletion` or to tag immutability. Those +have no bypass actor at all, deliberately: they are the rules whose violation destroys work rather +than merely making a mess. + ### Required checks, and the two that are deliberately absent Required: `build`, `node 18`, `node 20`, `node 22`, `node 24`, `bun`, `deno`,