Skip to content

ci: opt in to checkout v7 fork guard in workflow_run apply jobs#1906

Merged
ascorbic merged 2 commits into
emdash-cms:mainfrom
swissky:ci/fork-checkout-optin
Jul 10, 2026
Merged

ci: opt in to checkout v7 fork guard in workflow_run apply jobs#1906
ascorbic merged 2 commits into
emdash-cms:mainfrom
swissky:ci/fork-checkout-optin

Conversation

@swissky

@swissky swissky commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Repairs the Query Counts — Apply and Auto Format — Apply workflows for fork PRs. Since the actions/checkout v7 bump (#1611), checkout refuses to fetch fork PR code from a workflow_run workflow unless the step explicitly opts in with allow-unsafe-pr-checkout: true. Every apply run that actually reaches the Checkout (fork) step now fails with:

Refusing to check out fork pull request code from a 'workflow_run' workflow. … To opt in, review the risks at https://gh.io/securely-using-pull_request_target and set 'allow-unsafe-pr-checkout: true' on the actions/checkout step.

Example failing runs: 29079049235 (PR #1905), 29074697406. The recent "successful" runs only succeeded because they skipped both checkout steps (no artifact to apply) — so fork PRs currently never get snapshot updates or auto-formatting pushed back.

The opt-in matches the trust design these workflows already document (from the #1638 hardening): after the fork checkout, no code from the fork tree is executed — the jobs only copy the inert snapshot JSONs / git apply the patch from the trusted measure/format artifact, then git add/commit/push with a scoped app token supplied via GIT_ASKPASS, with persist-credentials: false on the checkout. This PR adds allow-unsafe-pr-checkout: true to the two fork checkout steps plus a comment explaining why the checkout is safe, so the reviewed rationale lives next to the opt-in.

Closes #

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Do not include messages.po changes except in translation PRs — a workflow extracts catalogs on merge to main.
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Cursor + Fable 5, reviewed by me

Screenshots / test output

Failure signature from the linked runs:

##[error]Refusing to check out fork pull request code from a 'workflow_run' workflow. This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner access. Fetching and executing a fork's code in that trusted context commonly leads to "pwn request" vulnerabilities.

actions/checkout v7 refuses to check out fork PR code from a
workflow_run workflow unless the step explicitly sets
allow-unsafe-pr-checkout: true. Since the v7 bump (emdash-cms#1611), every
"Query Counts — Apply" and "Auto Format — Apply" run that reaches the
fork checkout fails with "Refusing to check out fork pull request
code", so fork PRs no longer get snapshot updates or auto-formatting
pushed back.

Both jobs were already designed for this trust boundary: they never
execute code from the fork tree — they only apply inert artifacts
produced by the trusted measure/format runs (JSON copies, git apply)
and push with a scoped app token via GIT_ASKPASS, with
persist-credentials: false. Opt in explicitly and document why the
checkout is safe.
@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: bd33ccf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@1906

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@1906

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@1906

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@1906

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@1906

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@1906

emdash

npm i https://pkg.pr.new/emdash@1906

create-emdash

npm i https://pkg.pr.new/create-emdash@1906

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@1906

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@1906

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@1906

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@1906

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@1906

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@1906

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@1906

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@1906

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@1906

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@1906

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@1906

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@1906

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@1906

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@1906

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@1906

commit: bd33ccf

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI-only fix: correctly scoped and safe

This is a targeted CI workflow fix. It adds allow-unsafe-pr-checkout: true — plus explanatory comments — to the two workflow_run-triggered apply jobs that currently fail on fork PRs after the actions/checkout v7 bump.

Approach assessment

The approach is the right one. The v7 fork guard specifically blocks checking out fork PR code from workflow_run workflows unless you opt in. The two apply jobs genuinely need a checkout at the measured fork SHA so they can push the auto-generated commits back (style: format and ci: update query-count snapshots). They don't execute any code from the checked-out tree — auto-format-apply does git apply on a trusted artifact patch, and query-counts-apply only copies inert JSON files — and both already use persist-credentials: false with a scoped app token pushed via GIT_ASKPASS.

I checked for other workflows that might need the same treatment. format-command.yml also has a "Checkout (fork)" step using checkout v7, but it is triggered by issue_comment (not workflow_run) and it actually runs tooling over the checked-out tree, so it is outside the scope of this fix. No other workflow has both workflow_run and a fork checkout step.

Code-level review

  • YAML syntax and indentation are correct; allow-unsafe-pr-checkout: true is at the proper level inside the with: map.
  • Comments accurately describe what the subsequent steps do and why the opt-in is safe.
  • persist-credentials: false remains in place above the new opt-in.
  • Input name matches the one documented in the checkout action's error message.

This is a clean, narrowly scoped CI repair with no production code or user-facing changes.

@ascorbic ascorbic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

@github-actions github-actions Bot added review/approved Approved; no new commits since and removed review/needs-review No maintainer or bot review yet labels Jul 10, 2026
@ascorbic
ascorbic merged commit 52b52ab into emdash-cms:main Jul 10, 2026
42 of 43 checks passed
marcusbellamyshaw-cell pushed a commit to Emdash-Bug-Testing/emdash that referenced this pull request Jul 22, 2026
…sh-cms#1906)

actions/checkout v7 refuses to check out fork PR code from a
workflow_run workflow unless the step explicitly sets
allow-unsafe-pr-checkout: true. Since the v7 bump (emdash-cms#1611), every
"Query Counts — Apply" and "Auto Format — Apply" run that reaches the
fork checkout fails with "Refusing to check out fork pull request
code", so fork PRs no longer get snapshot updates or auto-formatting
pushed back.

Both jobs were already designed for this trust boundary: they never
execute code from the fork tree — they only apply inert artifacts
produced by the trusted measure/format runs (JSON copies, git apply)
and push with a scoped app token via GIT_ASKPASS, with
persist-credentials: false. Opt in explicitly and document why the
checkout is safe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants