Shared PR-Enforcement Action (.github/actions/require-no-mistakes)
- The shared implementation of the
PR must be raised via no-mistakesgate is a composite action that lets enforcing repositories replace copied, drift-prone scripts. It verifies the signature line, parses the v1 pipeline-step attestation, bindshead_shato the PR head, and requiresreview,test, anddocumentto becompleted. Callers pin a release tag or commit SHA, never@main, which the judged PR can edit. Per-repo configuration is exemptions only (exempt-authors,exempt-bot-authors,exempt-head-branches); which steps are required is deliberately not an input, so no caller can weaken the gate while still reporting the same check name. The action README owns usage;CONTRIBUTING.mdowns the contributor-facing contract. - This repository's own gate (
.github/workflows/no-mistakes-required.yml) is a thin caller of the action, pinned at an already-published commit SHA. GitHub downloadsuses:at job setup, so the pin must always name a ref that already carries the action. That pin IS the self-certification guard: a PR editing the action is fully tested on its own head (the Go tests execute the working-treeverify.py) while the required check judging it runs the published pinned copy, so the change cannot rewrite its own judge. Bumping the pin is a separate deliberate PR. - This repo's automation exemptions stay in the job-level
if:, not inexempt-authors. An in-job exemption still needs the run to start, and a GITHUB_TOKEN PR's run is created inaction_requiredand never starts; thepaths-ignoreentries exist for the same reason. Repos without that constraint should prefer the action's inputs. - Duplicate step records are LAST-WINS by design (
check_required_stepsinverify.py), and a skip-shaped sibling field on acompletedrecord is deliberately not inspected. Some pre-migration inline gates were stricter (requiring every record of a name to becompleted); that strictness is explicitly NOT the standard, and relaxing to last-wins on migration is the intended outcome, not a regression. Do not "harden" this without an owner decision. - A caller that gains
head_shabinding must also dropsynchronizefromon.pull_request.types, matching this repository's own post-#773 trigger set. Binding plussynchronizepins a stale FAILURE check run to a head the pipeline is about to fix, andgh pr checkscollapses same-named runs bystartedAt, so the CI monitor can park the run red forever. That change is only safe where no ruleset or branch protection REQUIRES the check - otherwise a pushed head gets no run and the requirement blocks the merge forever. Verify per repo withgh api repos/<owner>/<repo>/rulesetsplus.../branches/<branch>/protection; at the time of the fleet migrationtreehouse,sshhip, andwheelhouserequired it and therefore keepsynchronize. - Migrating a repository is rarely a one-file swap. Repos whose tests extract and execute the inline
run:block (anextractGateScript()helper and its gate test) break at import once the block is gone, and repo-levelAGENTS.mdnotes that tell agents to hand-copy the gate from a sibling repository must be rewritten - that copying is the drift the shared action exists to remove. - Regressions:
require_no_mistakes_action_test.goexecutesverify.pythe way a runner does (verdicts, exemption surface, event-payload binding);workflow_no_mistakes_required_test.goowns the CALLER - immutable-SHA pin, single delegating step, exemptions, triggers, concurrency identity, fork boundary - and drives the real action through the event payload.