Problem
format-suggest.yaml now fails on every pull request coming from a fork. It dies after ~5s in the actions/checkout step with:
Refusing to check out fork pull request code from a 'pull_request_target' workflow. This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner access.
Example: #2703 (fork PR, format-suggest failed 2026-09-02). For comparison, #2699 (also a fork PR) still passed on 2026-06-19.
Cause
GitHub changed the default behaviour of actions/checkout: checking out a fork's head SHA under pull_request_target (or workflow_run) is refused unless explicitly opted in. Announced 2026-06-18 for v7, backported to the other supported major versions with enforcement on 2026-07-20 — which is why actions/checkout@v4 (a floating major tag) picked it up without any change on our side.
Since pull_request_target runs the workflow definition from the base branch, contributors cannot fix this in their PRs; it has to be changed on main.
Suggested fix
The upstream template this workflow is derived from, posit-dev/setup-air/examples/format-suggest.yaml, has already been updated:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
allow-unsafe-pr-checkout: true
vs. the current .github/workflows/format-suggest.yaml:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
allow-unsafe-pr-checkout: true is the documented opt-out. It is defensible for this workflow because the checked-out tree is only treated as passive data (air format . does not execute package code), which is the exact use case GitHub calls out as acceptable — but it is worth a conscious decision rather than a copy-paste, so I did not open a PR for it.
The stricter alternative, if you'd rather not opt out at all, is the two-workflow split: run air format . under pull_request (no secrets), upload the diff as an artifact, and post the suggestions from a separate workflow_run job that never checks out fork code.
Other r-lib repos deriving from the same template are presumably affected identically.
References
Problem
format-suggest.yamlnow fails on every pull request coming from a fork. It dies after ~5s in theactions/checkoutstep with:Example: #2703 (fork PR,
format-suggestfailed 2026-09-02). For comparison, #2699 (also a fork PR) still passed on 2026-06-19.Cause
GitHub changed the default behaviour of
actions/checkout: checking out a fork's head SHA underpull_request_target(orworkflow_run) is refused unless explicitly opted in. Announced 2026-06-18 for v7, backported to the other supported major versions with enforcement on 2026-07-20 — which is whyactions/checkout@v4(a floating major tag) picked it up without any change on our side.Since
pull_request_targetruns the workflow definition from the base branch, contributors cannot fix this in their PRs; it has to be changed onmain.Suggested fix
The upstream template this workflow is derived from,
posit-dev/setup-air/examples/format-suggest.yaml, has already been updated:vs. the current
.github/workflows/format-suggest.yaml:allow-unsafe-pr-checkout: trueis the documented opt-out. It is defensible for this workflow because the checked-out tree is only treated as passive data (air format .does not execute package code), which is the exact use case GitHub calls out as acceptable — but it is worth a conscious decision rather than a copy-paste, so I did not open a PR for it.The stricter alternative, if you'd rather not opt out at all, is the two-workflow split: run
air format .underpull_request(no secrets), upload the diff as an artifact, and post the suggestions from a separateworkflow_runjob that never checks out fork code.Other r-lib repos deriving from the same template are presumably affected identically.
References
pull_request_targetdefaults for GitHub Actions checkoutpull_request_target