Skip to content

fix(ci): checkout PR head SHA so fork PRs resolve - #489

Merged
ciotlosm merged 1 commit into
mainfrom
fix/pr-check-fork-checkout
Sep 28, 2026
Merged

ciotlosm merged 1 commit into
mainfrom
fix/pr-check-fork-checkout

Conversation

@ciotlosm

Copy link
Copy Markdown
Member

Problem

The validate job in .github/workflows/pr-check.yml fails on fork PRs at the very first step (Checkout PR branch) with:

A branch or tag with the name '<branch>' could not be found

The shared pr-check reusable workflow from n3ary/actions (ASCII-only check, Standards drift check) handles fork PRs correctly — it ran and passed on #486. Only the repo-local validate job was affected.

Root cause

The validate job's checkout used:

ref: ${{ inputs.branch || github.head_ref }}

github.head_ref is the branch name on the head repo. For fork PRs that name lives on the fork (e.g. valeboth/app), not on n3ary/app. With repository defaulting to the base repo, actions/checkout does git fetch origin refs/heads/<name> and finds nothing — GITHUB_TOKEN has no access to fork branches by name.

The shared pr-check avoids this by relying on actions/checkout's default fork-aware checkout (no explicit ref).

Fix

Switch to github.event.pull_request.head.sha. The PR commit SHA resolves via the magic ref refs/pull/<N>/head on the base repo, which GITHUB_TOKEN can read. This works for fork and same-repo PRs alike.

The workflow_dispatch path (manual rerun from the Actions UI) still honors inputs.branch and falls back to github.ref_name.

Also added persist-credentials: false so the token isn't written to .git/config after checkout — no subsequent step reuses it.

Diff

       - name: Checkout PR branch
         uses: actions/checkout@v7
         with:
-          ref: ${{ inputs.branch || github.head_ref }}
+          # Use the PR head SHA, not github.head_ref. For fork PRs, the
+          # branch NAME lives on the head repo and refs/heads/<name>
+          # is unreachable from the base repo's GITHUB_TOKEN; head.sha
+          # resolves via refs/pull/<N>/head which IS accessible, and
+          # works for same-repo PRs too. workflow_dispatch falls back
+          # to the user-supplied input or the dispatch's ref name.
+          ref: >-
+            ${{
+              inputs.branch
+              || (github.event_name == 'pull_request' && github.event.pull_request.head.sha)
+              || github.ref_name
+            }}
           fetch-depth: 0
           token: ${{ secrets.GITHUB_TOKEN }}
+          # Don't persist the token to .git/config; no subsequent
+          # step reuses it.
+          persist-credentials: false

Verification

After merge, re-running the validate job on #486 should:

  • Checkout succeed (no more "branch not found")
  • Run pnpm check, pnpm test, pnpm build against the PR head code

Refs: #486

The `validate` job failed for fork PRs because its checkout used
`ref: github.head_ref`, which is the branch name on the head repo.
For forks the base repo's GITHUB_TOKEN can't fetch refs/heads/<name>
on the fork; the run died at the first step with:

  A branch or tag with the name '<branch>' could not be found

Switch the ref to `github.event.pull_request.head.sha`, which resolves
via `refs/pull/<N>/head` on the base repo. This works for fork and
same-repo PRs alike. `workflow_dispatch` still honors its `inputs.branch`
and falls back to `github.ref_name`.

Also add `persist-credentials: false` so the token isn't written to
`.git/config` after checkout (no later step reuses it).

Fixes #486 (validate job only; pr-check ASCII + standards
drift jobs already worked because they use the fork-aware default
checkout from n3ary/actions).
@ciotlosm
ciotlosm force-pushed the fix/pr-check-fork-checkout branch from b592113 to cca0c43 Compare September 28, 2026 17:42
@ciotlosm
ciotlosm merged commit a17a5a7 into main Sep 28, 2026
3 checks passed
@ciotlosm
ciotlosm deleted the fix/pr-check-fork-checkout branch September 28, 2026 17:47
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