mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-27 05:57:27 +00:00
c157b921b0
## What `recover-release-activation.yml` now also admits failed `create-release.yml` runs dispatched from release-train snapshot refs (`release-candidate/<packet>` or `release-dispatch/<packet>`), not only from `main`. A snapshot run is admitted only when main's `release_snapshot.py` proves its commit is the merged head of exactly one `release-candidate/<packet>` release PR. The source run's own `prepare` job ran that branch's code, so it is not trusted. Recovery now refuses to run unless dispatched on `main`, fetches full history for the ancestry check, and gains `pull-requests: read` for the PR lookups. ## Why The release train has dispatched on `release-candidate/*` branches since October, and will move to post-merge `release-dispatch/*` branches so release secrets can be confined to refs that exist only after merge. A train release that failed at activation could not use this recovery path at all. ## Stacking This branch is built on #3295 (snapshot check accepts `release-dispatch/*` refs), whose commit is included here. The two PRs touch different files. ## Validation - New executable test runs the recovery admission against stubbed GitHub and git: `main`, `release-candidate/*` and `release-dispatch/*` runs are admitted; lane branches, missing, unmerged or mismatched PRs, a different head commit, two matching PRs, malformed refs and a merge missing from main are rejected. - Mutations that each fail it: skipping the provenance check, and not mapping `release-dispatch/*` to its candidate head. Two more (admitting any branch in the run predicate, dropping the head-SHA filter in PR selection) are caught by `release_snapshot.py`'s own checks instead. - `release_promotion_policy_test.py` 73/73, `check_workflow_trust.py` and its 44 tests, `release_snapshot_test.py` 7/7, all on a full checkout.