From b89ed12c9e4b797e580647ed9088acf7f1620bb5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 19:07:21 +0000 Subject: [PATCH] fix(ci): checkout the event SHA, not refs/pull//merge, in governance jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 8 governance-reusable.yml jobs that pass `ref: ${{ github.ref }}` to actions/checkout were failing at checkout on every PR with "couldn't find remote ref refs/pull//merge". Root cause: governance.yml triggers on pull_request and calls governance-reusable.yml via workflow_call. In a reusable workflow, github.ref inherits the caller's PR ref, which is the named merge ref refs/pull//merge. actions/checkout cannot fetch that named ref, so the 8 jobs that requested it died at checkout — leaving governance effectively ungated on PRs (only push-to-main runs were enforcing). The two jobs that omit an explicit ref (workflow-staleness, validate-hypatia-baseline) were unaffected, matching the observed 8/10 failure. Fix: pin those checkouts to `ref: ${{ github.sha }}` — the concrete event commit (the PR merge commit on pull_request, the pushed commit on push). github.sha resolves to the same merge commit refs/pull//merge points at, but is always fetchable. Content is unchanged; the diff-based jobs (quality trufflehog base/head) already use explicit SHAs, so enforcement semantics are preserved. The secondary `ref: main` checkouts that pull the standards check scripts are untouched. Estate-wide: re-enables PR-time governance enforcement across all repos that consume this reusable workflow. Owner-approved 2026-06-27. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01MJdfXv5E5gwGD2yaJq8jRM --- .github/workflows/governance-reusable.yml | 80 ++++++++++++++++++++--- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/.github/workflows/governance-reusable.yml b/.github/workflows/governance-reusable.yml index 43bd996f..fc2c6056 100644 --- a/.github/workflows/governance-reusable.yml +++ b/.github/workflows/governance-reusable.yml @@ -128,7 +128,15 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} # Estate language policy bans Python with no exceptions (CLAUDE.md # Language Policy; SaltStack exception removed 2026-01-03). The @@ -464,7 +472,15 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} - name: Enforce Guix primary / Nix fallback run: | HAS_GUIX=$(find . -name "*.scm" -o -name ".guix-channel" -o -name "guix.scm" 2>/dev/null | head -1) @@ -492,7 +508,15 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} - name: Security checks run: | FAILED=false @@ -723,7 +747,15 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} - name: Check file permissions run: | find . -type f -perm /111 -name "*.sh" | head -10 || true @@ -772,7 +804,15 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} - name: RFC 9116 security.txt validation run: | SECTXT="" @@ -830,7 +870,15 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} - name: Check SPDX headers + permissions run: | failed=0 @@ -874,7 +922,15 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} path: caller - name: Checkout standards (for the check script) uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -897,7 +953,15 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} - ref: ${{ github.ref }} + # Pin to the concrete event SHA (the PR merge commit on + # pull_request, the pushed commit on push). Do NOT use + # `ref: ${{ github.ref }}`: in a reusable workflow called from a + # pull_request, github.ref is the named merge ref + # `refs/pull//merge`, which actions/checkout cannot fetch + # ("couldn't find remote ref refs/pull//merge") — it broke 8/10 + # governance jobs on every PR estate-wide. github.sha resolves to the + # same merge commit but is always fetchable. + ref: ${{ github.sha }} path: caller - name: Checkout standards (for the check script) uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0