Skip to content

Fix fork PR preview deploy: workflow_run split gated to forgebook-contributors#67

Merged
nicholasdbrady merged 2 commits into
mainfrom
nicholasdbrady-glowing-robot
Jul 8, 2026
Merged

Fix fork PR preview deploy: workflow_run split gated to forgebook-contributors#67
nicholasdbrady merged 2 commits into
mainfrom
nicholasdbrady-glowing-robot

Conversation

@nicholasdbrady

Copy link
Copy Markdown
Member

Why

Preview deploys have been failing (403) for every PR opened from a fork, most recently #63 and #66. GitHub always issues a read-only GITHUB_TOKEN for pull_request runs when the PR's head repo differs from the base repo, no matter what permissions: the workflow declares. Adding a contributor to the forgebook-contributors team fixes their repo/team permissions, but doesn't change this fork-vs-same-repo token restriction and can't retroactively fix an already-opened fork PR.

Approach

Split the previously single pull_request-triggered workflow into two, connected by a build artifact - the standard safe pattern for fork PRs that need a privileged step:

  • preview.yml (unprivileged, pull_request): checkout, validate registry, build, run a11y tests, then upload site/dist plus a small PR-metadata JSON (PR number, head SHA) as artifacts. Runs identically for fork and same-repo PRs; never needs or requests write access.
  • preview-deploy.yml (new, workflow_run triggered when preview.yml completes): runs in the base repo's workflow context, so it gets a write-scoped token, but never checks out or executes the PR's code, only the pre-built static artifact. Before deploying it checks whether the PR author is a member of the forgebook-contributors GitHub team and gates on that:
    • Member: deploys to gh-pages and posts/updates the preview-URL PR comment (same behavior as before).
    • Non-member: skips deploy, posts a comment explaining a maintainer needs to add them to the team and re-run the workflow. Build/test signal still runs either way.
  • preview-cleanup.yml (new): the PR-close cleanup job had the identical fork-token problem (masked so far, since no fork PR had been closed yet). Moved to pull_request_target: types: [closed], which is safe here because the job never executes PR code, it only checks out the maintainer-controlled gh-pages branch and deletes a directory by PR number.

Notes for reviewers

  • Team-membership checks require an org-scoped token; the default GITHUB_TOKEN cannot read team membership even for a visible ("closed" privacy) team. This needs a maintainer-created fine-grained PAT (org read: members/teams permission only) stored as the FORGEBOOK_TEAM_READ_TOKEN repo secret - a manual, one-time setup step outside this PR. Until that secret exists, the membership-check step will fail loudly rather than silently misclassifying everyone as a non-member.
  • workflow_run can only trigger off workflow definitions on the default branch, so this can't be validated end-to-end from this PR branch. Once merged, re-running against PR Adding two new notebooks to the forgebook for model migration code updates #66 (still open from a fork) is a good real-world validation case.
  • CONTRIBUTING.md updated with a short note on the new team-gated preview behavior.

Registry validation (npx tsx validate-registry.ts) still passes; this change touches only .github/workflows/ and CONTRIBUTING.md, no notebook or registry content.

…-contributors

Fork-based PRs always get a read-only GITHUB_TOKEN on pull_request events,
regardless of the author's actual repo/team write access, causing the
gh-pages deploy step to 403 (seen on PR #63 and #66).

- preview.yml: trimmed to unprivileged build/validate/test; uploads the
  built site and PR metadata as artifacts instead of deploying directly.
- preview-deploy.yml (new): workflow_run consumer with write access; only
  ever touches the pre-built static artifact, never PR code. Gates the
  actual gh-pages deploy + preview comment on forgebook-contributors team
  membership, via a maintainer-owned PAT (FORGEBOOK_TEAM_READ_TOKEN secret)
  since the default GITHUB_TOKEN can't read team membership.
- preview-cleanup.yml (new): moved the PR-close cleanup job here on
  pull_request_target, since it has the same fork-token problem but is safe
  to run privileged (no PR code execution, just deletes a directory on the
  maintainer-controlled gh-pages branch).
- CONTRIBUTING.md: note that auto-deployed previews require team
  membership; others still get build/test signal plus a comment.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread .github/workflows/preview-deploy.yml Fixed
Comment thread .github/workflows/preview-deploy.yml Fixed
Comment thread .github/workflows/preview-deploy.yml Fixed
…line template

github-script steps interpolated step outputs directly into the JS source
via ${{ }} template expressions, which CodeQL flags as a code-injection
risk since the value flows from a workflow_run artifact. Switched all
occurrences (pr_number and author) to pass through env: and read via
process.env instead, which is the standard mitigation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@nicholasdbrady
nicholasdbrady merged commit d8c0310 into main Jul 8, 2026
5 checks passed
@nicholasdbrady
nicholasdbrady deleted the nicholasdbrady-glowing-robot branch July 8, 2026 04:13
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.

2 participants