Skip to content

ci: release safety on main — draft-first promote + per-name asset verification - #5

Merged
MattJackson merged 1 commit into
mainfrom
ci/release-safety-main
Aug 14, 2026
Merged

ci: release safety on main — draft-first promote + per-name asset verification#5
MattJackson merged 1 commit into
mainfrom
ci/release-safety-main

Conversation

@MattJackson

Copy link
Copy Markdown
Contributor

Re-lands ONLY the release-safety payload from ci/draft-release-then-promote, freshly branched off main (the old branch was stacked on dev and carried unrelated unreleased history; it will not be merged).

Payload:

  • gh release create --draft + promote (--draft=false --latest) only after verification passes
  • .github/release-targets.json: the platform list in exactly one place, feeding both the build matrix and the expected-asset names
  • verify-assets: every expected asset present BY NAME and >= 1 KiB, running on !cancelled()

Verified locally: actionlint clean; the exact embedded verifier code proven against synthetic asset sets — complete passes; one-missing, one-of-five, truncated (<1KiB), zero-asset, right-count-wrong-name, and a truncated targets manifest are all refused.

verify-assets asserted only `assets | length -eq 0`, so a release that
built ONE target out of five passed the gate. That is how busbar v1.5.3
shipped five assets where seven were expected, with Apple Silicon Mac and
x86_64 Linux both 404ing for users. A count can never see a MISSING
platform; only a name can.

Ported busbar core release.yml`s contractual-filename-set approach:

  * .github/release-targets.json is now the platform list, in exactly one
    place. A `targets` job reads it and emits BOTH the build matrix and the
    exact set of asset filenames that matrix owes the release, so the set
    that is built and the set that is verified are the same computation and
    cannot drift. It carries a floor so a truncated manifest cannot produce
    an empty expectation list that passes vacuously.
  * verify-assets now asserts every expected asset is present BY NAME and
    at least 1 KiB (GitHub lists a truncated upload identically to a good
    one), prints a per-asset table to the step summary, and names the
    missing platforms in the failure.
  * verify-assets runs on `!cancelled()`. The build matrix is
    fail-fast:false, so a partial matrix FAILS the job and a `needs:` on a
    failed job SKIPS its dependent by default: the one guard that exists to
    notice a broken release was switched off precisely when the release was
    broken.

The build matrix is byte-identical to what it was, just sourced from the
manifest. Verified locally against synthetic asset sets: complete passes;
one-platform-missing, one-of-five, truncated, zero-asset, and
right-count-wrong-name are all refused.
@MattJackson
MattJackson merged commit 9977d24 into main Aug 14, 2026
2 of 3 checks passed
@MattJackson
MattJackson deleted the ci/release-safety-main branch August 14, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant