Skip automatic docs previews for fork PRs and drop the setup-uv retry steps

Merged
MA
2mo ago
+74-73

Follow-up to #3424, rebuilt on top of #3446 so the logic change lands in .github/scripts/docs_preview.js with tests.

Motivation and Context

actions/checkout v7 (actions/checkout#2454) refuses to fetch a fork PR's head in a pull_request_target run unless the step sets allow-unsafe-pr-checkout: true. The build job in docs-preview.yml does exactly that checkout whenever authorize passes, and authorize passes for a fork PR when the event sender is an admin: reopening a gate-closed fork PR, pushing to a contributor's branch, or hitting "Update branch". That has happened once so far (this run for #3413). With checkout v7 the same event fails at the checkout step, deploy is skipped, and the comment job posts a misleading "Preview build failed" on the contributor's PR.

Rather than opt in to the unsafe checkout, authorize now skips fork heads on the pull_request_target path: logged, no failed job, no comment. Fork PRs are previewed on request with /preview-docs, which runs under issue_comment, is outside checkout's guard, and keeps the same admin/maintainer gate and secret isolation. Same-repo branches, which is every maintainer PR in practice, keep automatic previews.

While here:

  • shared.yml: setup-uv v10.0.1 retries the version-manifest fetch itself (astral-sh/setup-uv#1016), which is what the four continue-on-error + "Install uv (retry)" pairs said they were waiting for, so each collapses to a single step.
  • docs-preview.yml comments: both triggers run the workflow from the default branch whatever the PR targets (which is why v1.x-base PRs get previews at all); GitHub now gives pull_request_target and issue_comment runs read-only access to the default branch's cache scope, so enable-cache: false there is defence in depth; and the two script checkouts added in #3446 carry a note that they must never take a ref:, since the gate's integrity rests on them being default-branch code.

How Has This Been Tested?

  • New scenarios in .github/scripts/docs_preview.test.js: admin push/reopen on a fork PR and a fork PR whose fork was deleted both yield no automatic preview and never call the permissions API; /preview-docs on a fork PR is still authorized for a maintainer. Both fork scenarios fail against the module before this change. node --test '.github/scripts/*.test.js': 46 pass.
  • pre-commit run --files on the touched files.
  • pull_request_target reads the workflow and script from main, so the live check comes after merge: /preview-docs on an open fork PR that touches docs should still build and deploy, and an admin push or reopen on one should now show a skipped build rather than a red one.

Breaking Changes

None for SDK users. Maintainer-facing only: a fork PR no longer gets an automatic docs preview when an admin reopens or pushes to it; comment /preview-docs instead.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

The alternative was adding allow-unsafe-pr-checkout: true to the build step's checkout, which restores the previous behaviour exactly. Security-wise that is tolerable here (admin-gated sender, no secrets on the build runner, persist-credentials: false, read-only cache scope), but GitHub's guidance reserves the flag for checkouts whose code is never executed, this job executes it by design, and the automatic fork path has fired once in the workflow's lifetime, so skipping cleanly and keeping the explicit slash command looked like the better trade. Easy to flip to the opt-in if automatic fork previews turn out to be wanted.

AI Disclaimer