Commit Graph

1 Commits

Author SHA1 Message Date
Sebastian "Sebbie" Silbermann 9e1a290955 Add a script for adopting fork pull requests (#97252)
Fork PRs run without repository secrets, so deploy tests never run on
external contributions. The workaround is to re-push the contributor's
commits to a branch in `vercel/next.js` and open a replacement PR from
there, which is fiddly by hand and carries a real security risk. This
adds a `pr-adopt` PNPM script to encode the procedure.

```bash
pnpm pr-adopt <pr-number>            # adopt
node pr-adopt <pr-number> --dry-run  # report without pushing
```

We copy over the title and body as-is and prepend a `Adopts #N. Closes
#N.` line so that the underlying PR automatically closes and we create
the proper backlinks.

Commits are signed

The description is copied rather than rewritten for two reasons: it is
the contributor's own text, and any `Fixes #123` inside it has to
survive, since the original PR closes unmerged and so never fires its
own.

### The confirmation gate

Adoption runs the contributor's code on a branch where CI has repository
secrets, which is exactly what a fork PR is denied. Anything executing
during install, build, or test can read and exfiltrate them, so before
touching git the script prints the PR link, status, author handle and
association, diff size, and every file touched. Confirming requires
retyping the author's handle, and a non-interactive stdin is refused
rather than silently proceeding.

Two details worth a reviewer's attention:

- **The file list is deliberately unranked.** An earlier revision
flagged "high-risk" paths (`.github/`, `package.json`, lockfiles). That
was removed: a payload can sit in any fixture or source file, and
printing "no high-risk paths touched" manufactures false assurance.
- **The list comes from the paginated REST endpoint.** `gh pr view
--json files` silently caps at 100 entries. #96550 has 106 changed files
and returns 100, which would present a truncated list as the complete
surface. If the count still falls short of `changedFiles` (GitHub stops
at 3000), the shortfall is reported rather than hidden.

Draft and closed PRs are both adoptable, since a contributor may still
be iterating or may have abandoned an unreviewed change; the status is
surfaced rather than enforced. Merged PRs are refused because their
commits are already in `canary`.
2026-08-13 15:52:09 +00:00