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. - All callers use the T2 trigger set (
opened,edited,synchronize,reopened). Since the pre-push attestation change (#994),synchronizeis the event that judges a pipeline-pushed head, so it is restored rather than dropped afterhead_shabinding. - 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.