Commit Graph

1563 Commits

Author SHA1 Message Date
Benjamin Woodruff ‮ 7b58e5880c Turbopack: Add support for specifying additional roots (#98003)
Full motivation and plan here:
https://app.notion.com/p/vercel/Turbopack-pnpm-Global-Virtual-Store-383e06b059c480579403ddfd71cc2d40?source=copy_link

The goal is to allow `DiskFileSystem` to traverse outside of it's own
root to other configured `DiskFileSystem`s when following symlinks. We
may allow traversal in other situations in the future, but this is
limited to symlink resolution for now.

## Global Virtual Store

The motivation for this is to enable [pnpm's Global Virtual Store
feature](https://pnpm.io/global-virtual-store) (and there are other
package managers doing this, including nub and bun).

We'd expose the ability to manually configure this in `next.config.js`,
but we should also auto-configure ourselves for popular package managers
(or at least make a best effort to do so, the `PNPM_HOME` semantics can
be complicated). The `ignoreIfMissing` option is provided for this
situation: We can configure a bunch of roots automatically, and they
only actually get set up if they exist, the check for directory
existence is cheap.

## NFT changes

This requires a couple extensions to the `*.nft.json` file format:
https://github.com/vercel/next.js/pull/98469

## Related Issues

- #93556
- https://github.com/pnpm/pnpm/issues/14972
2026-09-18 17:08:40 -07:00
Niklas Mischkulnig 3bf71ee3fd test: run cargo unit tests with miri as well (#97535)
### What?

Adds a CI job that runs selected Rust unit tests under
[Miri](https://github.com/rust-lang/miri) to detect undefined behavior
in unsafe code.

The job currently covers the low-level crates that are compatible with
Miri:

- `turbo-persistence`
- `turbo-rcstr`
- `turbo-tasks-malloc`

It also makes those crates Miri-compatible by:

- using provenance-free tagged-pointer operations in `turbo-rcstr`;
- disabling mimalloc and native compression under Miri;
- making mmap support a default-enabled Cargo feature that is disabled
for Miri and wasm;
- running persistence through file I/O when mmap is disabled;
- skipping only tests measured to exceed the Miri time budget;
- removing leaked test arenas from the analyzer predicate tests.

### Why?

Miri can detect invalid memory access and other undefined behavior that
normal Rust tests may not expose. Running it in CI gives low-level
unsafe code an additional correctness check.

The job uses an explicit package allowlist because Turbo Tasks builds
its generated registry from linker sections, and Miri does not support
the linker-defined section symbols required by that registry.

### How?

- Installs the `miri` Rust component in CI and the development
container.
- Adds a dedicated `test-cargo-unit-miri` task and reusable workflow
configuration.
- Makes `memmap2` optional behind the default `mmap` feature and
disables that feature in Miri CI and the wasm dependency graph.
- Uses structural `cfg(miri)` branches for allocator and compression
paths Miri cannot execute.
- Re-enables three persistence compaction tests after measuring them
successfully under Miri.
- Keeps normal native behavior unchanged and documents measured Miri
exclusions at the affected tests.

Verification included focused normal and Miri tests for persistence,
rcstr, allocation accounting, compression, and the refactored leak-free
predicate cases.

<!-- NEXT_JS_LLM -->


<!-- fleet fb42942f-173a-484c-b4de-4e18354834c6 -->

---------

Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
2026-09-18 09:29:06 +02:00
Sebastian "Sebbie" Silbermann 033bc32c02 [ci] Remove the broken Test examples workflow and its test suite (#98517)
Removes the `Test examples` workflow and its orphaned test suite. The
workflow fails every scheduled run: its pinned Playwright docker image
(v1.35.1) is incompatible with the Playwright version the repo now
requires (v1.61.0), so the browser cannot launch. It also no longer runs
what it was created for: since the `run-tests.js` glob root moved from
`test/` to the repository root, the `--type examples` string-prefix
filter `examples/` matches test files inside example apps instead of
`test/examples/examples.test.ts`, leaving that suite without any runner.

This deletes `.github/workflows/test_examples.yml`, the `test/examples/`
suite, and the `--type examples` filter in `run-tests.js`. The
`examples/` prefix stays in the default-run exclusion list so test files
inside example apps (which run with each example's own jest/vitest
setup) are still not picked up by bare `run-tests.js` invocations.

Co-authored-by: Claude Code <noreply@anthropic.com>
2026-09-11 10:53:28 +02:00
Sebastian "Sebbie" Silbermann 4e906f163c [ci] Fix scheduled Rspack test job (#98508)
This workflow is responsible for periodically updating the manifest. The
workflow broke in https://github.com/vercel/next.js/pull/97590 since the
[called workflow requires `pull_request:
write`](https://github.com/vercel/next.js/blob/626ab223bae3f9b29b3ec8cbd18a58d86b871ec1/.github/workflows/integration_tests_reusable.yml#L172)
to open the update PR.

Fixes
```
[Invalid workflow file: .github/workflows/rspack-nextjs-build-integration-tests.yml#L10](https://github.com/vercel/next.js/actions/runs/34439645923/workflow)
The workflow is not valid. .github/workflows/rspack-nextjs-build-integration-tests.yml (Line: 10, Col: 3): Error calling workflow 'vercel/next.js/.github/workflows/integration_tests_reusable.yml@334052ffbb383395b74cac6a90e0b15c7317957b'. The nested job 'collect_nextjs_development_integration_stat' is requesting 'pull-requests: write', but is only allowed 'pull-requests: none'.
```
-- https://github.com/vercel/next.js/actions/runs/34439645923
2026-09-11 10:40:31 +02:00
Sebastian "Sebbie" Silbermann 87edae5980 [ci] Remove Turbopack test manifest pipeline (#98507)
The manifest is no longer considered for skipping test since
https://github.com/vercel/next.js/pull/81170. It also didn't update
anymore automatically so I removed updating areweturboyet.com which was
broken for a while now anyway when we switched away from static tokens.
2026-09-11 10:40:30 +02:00
Sebastian "Sebbie" Silbermann 1329212686 [ci] Cleanup orphaned next-stats-action (#98348)
Became orphaned in https://github.com/vercel/next.js/pull/97792. Another
script and the test harness needed some utils from `next-stats-action`
so I moved that into `test/lib/link-packed-packages`.
2026-09-10 13:50:36 +02:00
Sebastian "Sebbie" Silbermann 76a0bdbdf4 [scripts] Move scripts (and benchmarks) off of node-fetch (#98347)
We're using Node.js versions with a built-in `fetch` implementation in
all of these scripts.
2026-09-10 13:50:35 +02:00
Tobias Koppers e44c5f192c ci: check that Turbopack compiles for wasm (#97588)
### What?

Adds a CI job that checks Turbopack compiles for
`wasm32-wasip1-threads`, so wasm portability
regressions are caught rather than rediscovered.

### Why?

Everything under `#[cfg(target_family = "wasm")]` is invisible to host
builds **and** to host clippy —
it is only checked when you deliberately build for the target. Four
separate defects in this stack were
caught only that way (a wrong build-script condition, two bad imports,
and a value that compiled but was
wrong). Without a gate, the next one lands unnoticed.

This also re-enables coverage that had been off for ~2 years: the old
`test-next-napi-bindings-wasi` job
was disabled with `if: false` pending napi-rs/napi-rs#2009, which closed
in April 2024.

### How?

Modelled on `rust-check` via `build_reusable.yml` (`needsRust`,
`skipInstallBuild`, `skipNativeBuild`),
so it does not pay for a JS build. Beyond `rustup target add` it needs
two things:

- **a WASI C toolchain**, because `lzzzz` (LZ4, via `turbo-persistence`)
and `zstd-sys` have C build
scripts. The SDK build is selected from `$RUNNER_ARCH` —
`build_reusable.yml` defaults to an arm64
runner, and an x86_64 clang fails there with `Exec format error` — with
a pinned sha256 per arch,
  unpacked under `$RUNNER_TEMP` so the workspace stays clean.
- **emnapi**, because `next-napi-bindings`' build script calls
`napi_build::setup()`, whose wasi path
panics without `EMNAPI_LINK_DIR` — so it is required even for `cargo
check`. It is installed into a
scratch directory rather than the root `package.json`, because this job
runs with `skipInstallBuild`
  and therefore never runs `pnpm install`.

Two things worth recording, both of which cost a CI round trip to find:

- pnpm is invoked from the repo root with `--dir`, not by `cd`-ing into
the scratch directory: corepack
resolves the pnpm version from the nearest `package.json`, and outside
the repo it picks the latest
  pnpm (11.x), which cannot run on the pinned Node 20
  (`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`).
- the job is added to `tests-pass`, whose `needs:` list is what actually
blocks a PR — a job that runs
but is absent from that list looks like coverage while blocking nothing.

The `emnapi@2.0.0-alpha.4` pin is deliberate and is the one fragility
here: the archive must define
`emnapi_create_env` / `emnapi_delete_env`, which exists only in emnapi
v2, still a prerelease. Move to
the stable release once it ships.


<!-- fleet b6d0486f-97c7-42a7-bdaf-3490774cdec3 -->

Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
2026-09-09 10:25:45 +02:00
Sebastian "Sebbie" Silbermann 665d3458b6 [ci] Align build-and-deploy triggers with build-and-test (#98331)
Change detection (`git diff HEAD~1`) only covers the whole change set
when the checkout is the PR merge commit. `build-and-test` runs on
`pull_request` while `build-and-deploy` ran on `push` for upstream PR
branches, so a multi-commit push whose last commit was docs-only made
`build-and-deploy` skip the preview build while deploy tests in
`build-and-test` waited up to 30 minutes for a preview tarball that
never got published.

`build-and-deploy` now triggers on the same events as `build-and-test`
(`push` to the default branch and `pull_request`), while still accepting
release tags and workflow dispatch. The `deploy-target` fork guard is
removed since upstream PRs are no longer covered by a push run, and
`create-release-branch.js` now rewrites the workflow's branch list
alongside the existing `refs/heads/canary` replacement so release
branches keep their staging deploys.

Preview tarball creation now uses the PR head sha instead of falling
back to the merge-commit sha on `pull_request` `opened` events
(`github.event.after` only exists on `synchronize`), matching the sha
that `upload_preview_tarballs.yml` publishes under and that tests poll
for. This fallback was a pre-existing bug that only affected fork PRs;
it would have started affecting every upstream PR's first run once
previews moved to the `pull_request` event.
2026-09-08 10:55:44 +02:00
Marcos Hernanz 4fffc2c653 Enable hourly next-maintainer auto-close workflow (#98225)
## Summary

- enable the existing auto-close workflow once per hour
- keep manual dispatch available
- leave the workflow logic and permissions unchanged

## Verification

- production `workflow_dispatch` succeeded end to end:
https://github.com/vercel/next.js/actions/runs/33788887152
- production returned a clean empty-queue response after OIDC
authentication and Vercel Trusted Sources validation
- Prettier and `git diff --check` pass
2026-09-03 13:03:41 -07:00
Marcos Hernanz 0eb4d7d585 Add Next Maintainer auto-close workflow (#98197)
## Summary

- add a manually dispatchable workflow; the hourly schedule is left
commented until initial production verification
- keep the workflow YAML small and place delivery in
`.github/scripts/next-maintainer-auto-close.js` for normal code review
- use a short-lived exact-audience GitHub Actions OIDC token with no
long-lived secret
- trust the authenticated queue contract instead of reimplementing its
Zod validation in the workflow
- post the verifier-authored comment and close with GitHub native
completed, not planned, or duplicate state reasons
- retain one invisible marker only to prevent duplicate public comments
across retries

If an issue is open with the marker, the workflow leaves it open. This
intentionally lets a human reopen win and avoids timeline
reconstruction.

## Permissions

The job grants only `contents: read`, `id-token: write`, and `issues:
write`; every other permission remains none. Both GitHub actions are
pinned to full commit SHAs. Checkout is sparse to the one trusted
JavaScript file and has credential persistence disabled.

## Verification

- mocked delivery harness passes ten scenarios: empty queue, completed,
not planned, duplicate, pull-request rejection, already-closed recovery,
independent close, open marker, transferred issue, and transient failure
- `node --check`, Prettier, and ESLint pass for the extracted
implementation
- Vercel Agent Review, Vercel Security Review, Socket Security, workflow
change detection, and documentation validation pass
- after merge, dispatch the registered workflow on `canary` and add the
production run link here before enabling the hourly schedule

## Dependency

This is the narrow GitHub write-side companion to
vercel-labs/next-maintainer-agent#541, which is deployed.
vercel-labs/next-maintainer-agent#546 further reduces the queue DTO and
changes the delivery limit to 25 first claims per rolling week; this
workflow is compatible with both DTO versions.
2026-09-03 10:32:40 -07:00
Sebastian "Sebbie" Silbermann 52cd5b96ab Skip discussions in the issue_lock workflow (#98146)
The last remaining `Lock Threads` failures are likely due to missing
permissions for discussions which `dessant/lock-threads` handles by
default.

This disables discussion handling to get the workflow green to start
tracking regressions. We can discuss if we want to lock inactive
discussions in a follow-up (which would be new behavior this workflow
never performed).

Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-09-01 18:06:18 +00:00
Sebastian "Sebbie" Silbermann 3866d6fd2b [ci] Fix issue_lock (#97755)
Fixes
> "github-token" length must be less than or equal to 100 characters
long
-- https://github.com/vercel/next.js/actions/runs/33188474239

GitHub uses stateless tokens now which are way longer. See
https://github.com/dessant/lock-threads/issues/55

---------

Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-09-01 17:50:10 +02:00
Sebastian "Sebbie" Silbermann 429514a468 [ci] Simplify upload-preview-tarballs workflow (#98109)
The upload script dropped its `@vercel/blob` usage in #97922 and
[imports only built-in modules
today](https://github.com/vercel/next.js/blob/canary/scripts/upload-preview-tarballs.js),
so the job no longer needs node_modules at all which allows simplifying
the workflow.


Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-31 20:20:10 +02:00
Will Binns-Smith 2c752da34d devlow: use commander for cli argument parsing (#93860)
This has devlow use `commander` to parse its arguments.

There's a breaking change here to make it fit better into `commander`'s
patterns without extra code. It also makes things more explicit:

Arbitrary variant filtering can no longer be done with
`--variantname=value`. Now that there are more flags, these share the
namespace with these, so instead we use `--filter variantname=value`, or
`-F variantname=value`.

Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Co-authored-by: Will Binns-Smith <755844+wbinnssmith@users.noreply.github.com>
2026-08-31 10:56:56 -07:00
Sebastian "Sebbie" Silbermann 7421a868ad [ci] Remove the popular workflow and its action (#97753)
The `popular` workflow posted weekly Slack digests of the most-reacted
issues, PRs, and feature requests. That reporting is now handled by the
Next.js maintainer agent, so this PR deletes the workflow along with its
backing `next-repo-actions` action (sources and checked-in ncc bundles),
which had no other consumer, and regenerates the `.github` lockfile
without the action's dependencies.

Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-29 11:54:35 +02:00
Sebastian "Sebbie" Silbermann 28195e9b75 [ci] Remove dormant code_freeze workflow (#97756)
Code freezes are now managed by toggling the existing `code freeze`
repository ruleset in the repository settings, so the `code_freeze`
workflow is no longer needed. It was also broken beyond repair: it
targeted the legacy branch-protection API with a `CODE_FREEZE_TOKEN`
secret that no longer exists instead of the rulesets the repository uses
now, and it referenced a `releaseType` input that was never declared.
This PR deletes the workflow and `scripts/code-freeze.js`, which had no
other consumer.

Note on the investigated alternative: resurrecting the workflow on top
of the rulesets API with just `GITHUB_TOKEN` is not possible. Creating
or updating repository rulesets requires the "Administration" repository
permission, which the workflow token cannot be granted (`permissions:
administration: write` is rejected as an invalid workflow, and even
`write-all` gets `403 Resource not accessible by integration`). Verified
empirically in
https://github.com/eps1lon/github-actions-repository-dispatch-admin-permissions.

Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-28 19:11:37 +02:00
Sebastian "Sebbie" Silbermann bfc33e2bb0 [ci] Remove the unused wrong-issue-template workflow and action (#97749)
The `issue_wrong_template.yml` workflow closed issues labeled `please
use the correct issue template`. That label was only ever applied
manually by maintainers and has not been used since January 2025 (9
issues total, ever), so every recent run of the workflow was skipped.
This change removes the workflow along with its backing
`wrong-issue-template` action (source, checked-in ncc bundle, and build
script).

Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-28 19:08:20 +02:00
Sebastian "Sebbie" Silbermann f889820802 [ci] Remove the stale-issue workflow (#97758)
The `issue_stale` workflow ran `actions/stale` once a day to mark issues
with no activity in 545 days (~1.5 years) as stale and close them a week
later, and to auto-close issues labeled `please add a complete
reproduction` (2 days), `please simplify reproduction` (14 days), or
`please verify canary` (14 days). Marking and closing issues based on
inactivity is no longer wanted, so the workflow is deleted.

The `STALE_TOKEN` secret has already been revoked.

Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-28 17:35:56 +02:00
Sebastian "Sebbie" Silbermann a18361694e [ci] Use presigned URLs to upload preview builds (#97922)
Follow-up to #97256, pairing with
[vercel/vercel-packages#107](https://github.com/vercel/vercel-packages/pull/107).
The token exchange endpoint no longer returns a client-upload token
derived from a store read-write token; it presigns the upload URL with
the deployment's own Vercel OIDC identity and returns the URL, pinning
the pathname, expiry, size cap, and access and overwrite policy
server-side. No store credential exists anywhere after this lands, and
no Blob SDK is needed here for the new path — the script PUTs the
tarball bytes to the URL directly.

The client only uses presigned-URL. The server still supports client
tokens until we landed this and synced the mirror.


Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-28 17:29:16 +02:00
Sebastian "Sebbie" Silbermann 027205875b [ci] Run flake detection and new deploy tests when merged and on backport branches (#97991)
The previous detection mechanism special-cased `canary` which lead to
large diffs when backport branches ran CI.

We stop special casing `canary` reducing complexity and giving us
another flake-detecting attempt when the change is merged.

That way we can safely enable flake detection on backport branches
without having to test large diffs when PRs are merged targetting
backport branches. New backport branches will no longer have flake
detecton and new deploy test runs disabled.
2026-08-28 09:09:32 +00:00
Niklas Mischkulnig d6e5741682 ci: remove pull_request_stats workflow (#97792)
This was quite useless (very flaky) and furthermore also slow
2026-08-27 09:43:29 +02:00
Sebastian "Sebbie" Silbermann 7dcf6c0a68 [ci] Use short-lived access tokens for preview-build uploads instead of static token (#97256)
Replaces the static `PREVIEW_BUILDS_BLOB_READ_WRITE_TOKEN` secret with a
short-lived access token to upload to Vercel Blob in exchange for a
GitHub OIDC (endpoint side:
https://github.com/vercel/vercel-packages/pull/98):

- the job mints GitHub Actions OIDC tokens for the
`https://vercel-packages.vercel.app` audience itself (the workflow gains
`id-token: write`) and re-mints shortly before expiry since a token
lives about five minutes while a package batch can take longer
- `upload-preview-tarballs.js` exchanges the token at vercel-packages
for scoped client-upload tokens via POST and uploads the tarball bytes
directly to Blob storage with `@vercel/blob/client`'s `put`, so the blob
read-write token never leaves vercel-packages
- the `preview-builds` environment is dropped from the job: it only
existed to selectively expose the static token and restrict uploads to
canary, and the canary binding is now enforced by the `job_workflow_ref`
match at vercel-packages.


---------

Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-25 20:13:01 +02:00
Sebastian "Sebbie" Silbermann 09f9c8a758 Fix ISR misses with backslashes in segments when deployed on Windows (#97876)
https://github.com/vercel/next-js-mirror/pull/150
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-25 18:12:50 +02:00
Sebastian "Sebbie" Silbermann 988a6ab727 [ci] Authenticate Turborepo remote caching with OIDC instead of a static PAT (#97590)
CI authenticated to Vercel Remote Cache with a long-lived Personal
Access Token in the `TURBO_TOKEN` repository secret. That token never
expired, is scoped to a team member rather than the team, and is
readable by every job that inherits secrets.

Each job now mints its own short-lived, cache-only token instead, using
`vercel/setup-turborepo-remote-cache-action` against a Turborepo CLI
OIDC policy configured on the Vercel team following
https://vercel.com/docs/monorepos/remote-caching/external-ci-cd#openid-connect-oidc

Forks skip the step entirely since they won't have access to repository
variables. During outages or any other permission errors, the steps
outcome will simply be ignore and we fall back to uncached behavior.

This could lead to silent regressions or hiding new, incorrect callsites
lacking necessary permissions. A Datadog monitor is not as simple as I'd
like since DD does not track outcome but conclusion (which is always
success for continue-on-error). Adding custom tags via DD CLI feels to
heavy. We'll revisit if this becomes a recurring issue.
2026-08-20 10:16:10 +02:00
Sebastian "Sebbie" Silbermann 1941060ff4 [ci] Wait for the next version to be available on npm before deploy tests (#97460)
Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
2026-08-18 13:20:44 +02:00
Zack Tanner 10439f3c6f [ci] Fix backport canary release dispatch (#97383)
## Summary

- Use the job-scoped `GITHUB_TOKEN` with explicit `actions: write`
permission to dispatch `trigger_release.yml` after a stable backport.
- Avoid requesting Actions write access from the release GitHub App,
which currently prevents the dispatch token from being created.
- Preserve the existing forced preminor canary release behavior.

This fixes the failure that left canary semver-behind stable after the
`v16.3.1` backport. The evaluation succeeded, but the dispatch failed
while creating the App token in the [failing dispatch
job](https://github.com/vercel/next.js/actions/runs/31750536217/job/94615208366).

## Verification

https://github.com/vercel/next.js/actions/runs/31830288265/job/94864091005
```
should_dispatch=true
reason=Dispatching canary preminor release because stable release 16.3.1 is ahead of 16.3.1-canary.17
released_version=16.3.1
current_canary_version=16.3.1-canary.17
dispatch_input=false
auto_dispatch_enabled=true
```
2026-08-17 06:56:34 -07:00
Jimmy Miller e928f2395f Migrate napi-rs bindings from v2 to v3 (#95412)
Draft PR for testing

<!-- NEXT_JS_LLM_PR -->
2026-08-13 11:35:52 -04:00
Marcos Hernanz 7a5d2f9f32 Allow issue participants to request reopening (#96947)
## Summary

- Let issue authors and people who commented before closure reopen an
issue within 14 days using `Reopen: <reason>`.
- Limit the automation to unlocked issues closed by triage-or-higher
human maintainers, with ordered timeline checks, bot filtering,
idempotency, and state revalidation.
- Align resolved-issue and contributor guidance with the new reopening
window.

## Verification

- `Prettier 3.6.2 --check .github/workflows/issue_reopen.yml
.github/comments/resolved.md contributing/repository/triaging.md`
- Mocked workflow harness covering 19 closure, eligibility, boundary,
bot, idempotency, and race scenarios
- `autoreview --mode local --stream-engine-output` (Codex and Claude
clean)
- Live GitHub API spot-check for ordered same-second `commented` and
`closed` timeline events
- Not run: live issue close/reopen smoke test (issue-triggered workflows
run only from the default branch)
2026-08-12 15:34:54 -07:00
Sebastian "Sebbie" Silbermann 10725074a4 [ci] Use OIDC tokens to read private preview builds (#96919)
Replaces the shared, static `PREVIEW_BUILDS_READ_TOKEN` secret with OIDC
tokens for reading auth-protected preview builds from vercel-packages
(see https://github.com/vercel/vercel-packages/pull/96):

- CI jobs mint a GH oidc token for the
`https://vercel-packages.vercel.app` audience
- deploys have a `.npmrc` written that uses the Vercel OIDC token

Tarball polling now also fails fast on 401/403 (retrying can't change
the authorization outcome) and failure messages include response headers
so request IDs are available for debugging.



Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 18:21:05 +02:00
Hendrik Liebau a5000124d7 Forward a build-container pin to deploy-test deployments (#97191) 2026-08-12 10:57:39 +02:00
Sam Poder b87f7b4a21 [turbopack] Don't run Webpack tests on Turbopack-only changes (#96656)
Hopefully this saves us money + makes it easier to merge Turbopack PRs
due to flaky Webpack tests
2026-08-07 13:49:12 -07:00
Sebastian "Sebbie" Silbermann 2b11d569b4 [ci] Default deploy e2e tests to the repo next version (#96895)
This is mostly just to remove some confusion and clean up unused default
values in some places.

When you run on a backport branch or older tag, you probably never want
to use `canary` and just the version at that point. Running on `canary`
branch will implicitly use the latest `@canary` from NPM.

Since our setup job already checks for the version declared in the
checkout, we should use that everywhere so that we only have to check a
single place to be sure about what version is/will be used.

I'll backport this especially because it'll fix a bug in 15.x where we
ignore the release tag.
2026-08-07 19:26:55 +02:00
Sebastian "Sebbie" Silbermann d470d18941 [ci] Reset the turbopack deploy test project in the weekly cron (#96822)
The weekly `test-e2e-project-reset-cron` workflow never defined
`VERCEL_TURBOPACK_TEST_TEAM` or `VERCEL_TURBOPACK_TEST_TOKEN`, even
though `run-e2e-test-project-reset.mjs` iterates over all three deploy
test teams. Because `resetProject` defaulted `teamId` and `token` to the
base team, and a destructuring default fires on an explicit `undefined`,
the turbopack iteration silently resolved to `vtest314-next-e2e-tests`.

The cron has therefore been deleting and recreating the base team's
project twice per run while never resetting the turbopack team's
project, and reporting success throughout. This dates back to #89458,
which wired the env pair into `build_reusable.yml` and
`test_e2e_deploy_release.yml` but missed the cron.

This drops the defaults in favor of explicitly passing the team.
2026-08-07 11:57:11 +02:00
Sebastian "Sebbie" Silbermann 4f37c39616 [ci] Open automated update pull requests with nextjs-bot (#96683)
Gets rid of of all usages of the static `GH_TOKEN_PULL_REQUESTS` token
that was issued for `vercel-release-bot`.

We already create commits with `nextjs-bot`. `nextjs-bot` already had
permissions to open PRs which is already being used by React sync.
2026-08-06 16:32:54 +02:00
Sebastian "Sebbie" Silbermann 2c04735944 [fragment-scroll] Remove config.experimental.appNewScrollHandler (#95602) 2026-08-06 09:53:09 +00:00
Sebastian "Sebbie" Silbermann 50eacb5b22 [react-sync] Open pull requests as the bot that authors the commits (#96682)
Noticed when auto-merge didn't work. `vercel-release-bot` isn't in the
exemption list (for good reason).

Since `vercel-release-bot` still uses a static token, it's time to use
the app fully.

The rest of the usage I'll do in a follow-up.

## test plan

It'll fail for now when enabling auto-merge. Everything else works
though. I'll fix the perms for auto-merge in a follow-up.

- [x] [sync from this
branch](https://github.com/vercel/next.js/actions/runs/30954178134/job/92143210455)
-> https://github.com/vercel/next.js/pull/96688
2026-08-05 07:24:09 +02:00
Luke Sandberg fca0fea594 [ci] Fix create_release_branch for new repo permissions (#96641)
### What

Fixes the **Create Release Branch** workflow, which currently fails on
every run.

1. Drop `permission-environments: write` from the GitHub App token
request.
- The release App installation no longer grants it, and
`actions/create-github-app-token` fails hard on an ungranted permission.
2. Drop the runtime `deployment-branch-policies` API call (and its 5s
sleep) from `scripts/create-release-branch.js`.
- No longer needed: the `release-stable` environment now statically
allows branches conforming to `next-NN` / `next-NN-*`. This is what the
permission above existed for.
3. Create the setup commit as a GitHub-signed commit via
`scripts/github-utils/signed-commit.js` instead of `git push`.
- Branch protection requires signed commits; `git push` pushed an
unsigned one. Uses the same `createSignedCommit` + `upsertBranchRef`
pattern as `scripts/automated-update-workflow.js`.

### Why

The most recent run
([30923742579](https://github.com/vercel/next.js/actions/runs/30923742579/job/92040655448))
dies at the first step, `Create GitHub App token`, with a 422 — so the
job never even clones the repo.

### Note for review

Release tags are **annotated** tag objects, so `git rev-parse v16.0.0`
returns the tag object SHA, not the commit. `createSignedCommit` passes
`baseSha` straight into `parents: [...]`, so the base is dereferenced
with `^{commit}`. Its internal `^{tree}` lookup happens to resolve
either way, so this would otherwise only have failed at commit-creation
time during a real release.

The static patterns cover `next-16-2`-style names but not a single-digit
major like `next-9-5`. Not a concern for current or future releases, but
noting it since the previous code created the policy for any branch
name.

### Verification

The workflow is `workflow_dispatch`-only and writes to the real repo, so
it can't be run end-to-end from a PR. Verified locally against the real
`v16.0.0` tag in a throwaway clone:

- `git reset --hard v16.0.0` leaves HEAD exactly at `v16.0.0^{commit}`,
confirming the base SHA is right.
- Replaying the lerna.json / `build_and_deploy.yml` /
`build_and_test.yml` mutations produces exactly those 3 changed files
and nothing else.
- Driving `createTreeFromLocalCommit` with a mocked `request` (no
network) uploads 3 blobs with correct `100644` modes and a `base_tree`
that matches the tag's tree.
- `node --check`, prettier, and eslint all clean.

Still needs a real `workflow_dispatch` run after merge to confirm the
token step succeeds and the resulting commit shows as **Verified**.
2026-08-04 17:18:15 +00:00
Hendrik Liebau c00449d52b [ci] Wait for the preview tarballs before running the deploy tests (#96527)
The "Test new and changed tests when deployed" jobs install Next.js from
the preview tarballs built for the commit under test, but nothing made
them wait for those tarballs to exist. Until #96438 the job was ordered
behind `test-prod` and the other new-test jobs, which delayed it long
enough that the tarballs had usually landed by the time it looked for
them. Now that it starts immediately it frequently fails with "Artifacts
not found for commit ...".

The ordering cannot be expressed as a `needs:` entry, because the
tarballs are published by a different workflow and, for pull requests
from branches in this repository, a different event than the
`build-and-test` run that consumes them. We therefore add a
`wait-for-preview-tarball` job that polls for the tarball instead, and
make both deploy test jobs depend on it. Doing the waiting in one cheap
job keeps the deploy test matrices off their 16-core runners until there
is something for them to install.

The new job is also listed in `tests-pass`. A dependency failure skips
the jobs that need it, and a skipped job does not count as a failure, so
without that entry a tarball that never arrives would have let the
required check pass with the deploy tests never having run.

`test-new-tests-deploy-cache-components` gets the same treatment,
dropping the incidental ordering it still inherited from
`test-cache-components-prod` and picking up the docs-only guard that
`test-new-tests-deploy` already had.
2026-08-03 16:27:51 +02:00
Marcos Hernanz 439163392d Add automated code review workflow (#96359)
## Summary

Adds one protected `pull_request_target` workflow for advisory automated
review of non-draft, member-authored PRs.

The existing Vercel reviewer runs Codex, Claude, and synthesis with
read-only GitHub access. This base-owned workflow treats that result as
untrusted, validates it, and owns the only GitHub mutation.

## Write boundary

- no checkout, PR code execution, dependency installation, Actions
secrets, or shell interpolation
- globally empty permissions; the job has only OIDC and pull-request
read
- exact repository, event, author association, PR state, base SHA, and
head SHA validation
- final read-only PR revalidation immediately before publishing
- HTML comments stripped, mentions neutralized, token patterns redacted,
and output capped at 48 KB
- a write token is minted only after validation
- exactly one top-level comment `POST` or `PATCH`
- existing comments are eligible only when attributed to one of gh-sts's
immutable `general` GitHub App IDs and begin with the fixed marker
- both actions are pinned to immutable commit SHAs

The workflow intentionally runs once on `opened` or `ready_for_review`;
it does not run on `synchronize`.

## Validation

- `actionlint`
- Prettier
- syntax validation of all three embedded `github-script` programs
- upstream commit verification for both pinned actions
- independent Codex and Claude autoreview

The workflow remains inert until the matching gh-sts policy is approved.
2026-07-31 17:32:32 -04:00
Sebastian "Sebbie" Silbermann dc358f450c [ci] Run new/changed deploy tests asap (#96438)
These are equally important if not more important (since they test build
adapters) than next-start tests so we now run them immediately instead
of waiting for test-prod.

They job is now skipped entirely for docs changes. Which saves a few
seconds for docs-only changes.
2026-07-31 20:12:30 +00:00
Benjamin Woodruff f6d094061e [ci] Background some steps in build_reusable to reduce setup overhead, remove unneeded lld installation (#96195)
This is a pretty minor win, but it can save a few seconds per job.


https://github.blog/changelog/2026-06-25-actions-steps-can-now-be-run-in-parallel/

Also remove the installation of `lld` for rustc with `apt-get`. It's
very slow, and rustc should already ship with `lld` these days? The
composite action to install the rust toolchain isn't run often (test
shards download a prebuilt native binary), but `build-native` it can
block other jobs from running and become a bottleneck.

Testing the full `build-and-deploy` job, which uses the rust install
action: https://github.com/vercel/next.js/actions/runs/30138483769
2026-07-28 22:49:20 -07:00
Sebastian "Sebbie" Silbermann 1412d0fe91 [cd] Send Slack notification if publish fails (#96304)
Failing to publish (especially a partial publish) leaves Next.js in a
corrupted state that needs to be addressed immediately. However, we only
created alerts when deploy tests failed which requires a successful
publish.

Now we send special message to the same channel as broken canary and
deploy tests go.

This won't catch a failing deploy-target job. We'll see if deploy-target
also frequently fails/flakes.
2026-07-28 15:21:21 -04:00
Sebastian "Sebbie" Silbermann e8866c8b7a [ci] Skip passed-tests cache steps for jobs that never run tests (#96001)
CI jobs in `build_and_test` printed a "Cache save failed." warning from
the "Save passed-tests cache" step even when they never run tests. The
step ran for every job with an `afterBuild` command, but
`.next-test-passed.txt` is only ever written by `run-tests.js`, so jobs
like lint, rust-check, or types-and-precompiled warned on every run
because the path never existed.

`run-tests.js` already owns the decision of whether result caching is
active (`profile.cachingEnabled`), so it now signals the workflow
itself: when it opens the passed-tests file (which happens before any
test runs, and only when result caching is enabled), it writes the path
to the `passed_tests_file` step output. The "Save passed-tests cache"
step in `build_reusable.yml` only runs when that output is present and
takes its `path` from it. Jobs that never run `run-tests.js`, and
flake-detection runs (where `NEXT_FLAKE_DETECTION` disables the result
cache), never emit the output and skip the save silently. A job that
fails midway through its tests has already emitted the output, so its
partial file still saves and a genuine warning is still possible.
2026-07-21 12:21:45 +00:00
Sebastian "Sebbie" Silbermann f8dc962e17 [ci] Avoid apt-get in the next-stats-action Docker image (#95847)
The `Stats (webpack)` / `Stats (turbopack)` CI jobs have been
intermittently failing on PRs and canary (e.g. [this
run](https://github.com/vercel/next.js/actions/runs/29476089144/job/87563318723)).
The jobs run on arm64 runners, where the `ubuntu:24.04` base image
fetches apt packages from `ports.ubuntu.com`, which is intermittently
unreachable. Since `apt-get update` only warns when index fetches fail,
the Docker build breaks one layer later at `apt-get install` with
"Unable to locate package curl".

This change switches the base image to `buildpack-deps:noble-scm`, which
already ships curl, ca-certificates, and git, so the build no longer
makes any apt calls at all. The `apt-get upgrade` step is dropped along
with it; it was already a silent no-op whenever the mirror was down, and
the ephemeral CI container does not rely on it.

Both `.github/next-stats-action.Dockerfile` (the one CI builds via
`action.yml`) and the duplicate
`.github/actions/next-stats-action/Dockerfile` are updated to stay in
sync.
2026-07-17 10:45:36 -07:00
Sebastian "Sebbie" Silbermann 3ae5630d0a [ci] Allow running all deploy tests with builds from a private registry (#95784) 2026-07-16 11:33:21 +02:00
Benjamin Woodruff 0cfc85ceae Clarify AI-assisted contribution policy in PR template and AGENTS.md (#95629)
## Summary

Documents the policy around AI-assisted contributions, for both humans
and agents:

- `.github/pull_request_template.md`: notes that AI use is encouraged
for researching, creating, and reviewing changes, but contributors must
deeply understand their contributions, and PR descriptions from external
contributors must be written by a human.
- `.github/ISSUE_TEMPLATE/1.bug_report.yml`: adds the equivalent note
for bug reports — issue descriptions from external contributors must be
written by a human, though AI may help create reproductions.
- `AGENTS.md`: replaces the old "PR Descriptions" section with two new
sections. "GitHub Pull Requests" distinguishes branch PRs (agents may
write descriptions) from fork PRs targeting `vercel/next.js` (agents may
not). "GitHub Issues, Comments, and Discussions" restricts agent-written
issues, discussions, and comments to members of the
`vercel`/`vercel-labs` GitHub orgs, tells agents how to check membership
via the GitHub API, lists what agents can still help non-members with
(drafting details, reviewing, reproductions, translation, searching for
duplicates), and carves out exceptions (commenting on the user's own PR,
Vercel-operated bots, GitHub/Graphite review bots, and forks of the
repo).
- Renames the LLM watermark marker from `NEXT_JS_LLM_PR` to
`NEXT_JS_LLM` everywhere it appears (`AGENTS.md`,
`contributing/repository/pull-request-descriptions.md`, and the
`create-pr`/`backport-pr` skills), since it now also applies to issues,
discussions, and comments. Nothing in the repo consumes the old marker
name.
- `.agents/skills/create-pr/SKILL.md`: adds a "Fork PRs vs Branch PRs"
section referencing the `AGENTS.md` policy. Assorted typo fixes along
the way.

## Verification

- `gh api /user/memberships/orgs` and `gh api
orgs/vercel/members/<login>` (confirmed the documented membership checks
work and return the documented statuses)
- Not run: no test/build commands (docs-only change; prettier applied
via the pre-commit hook)

<!-- NEXT_JS_LLM -->
2026-07-10 11:27:52 -07:00
Jude Gao 45e0295d70 [ci] Bump PR stats job timeout to 35 minutes (#95592) 2026-07-08 20:09:41 -04:00
Niklas Mischkulnig da06078b9b test: Fix immutable static asset deployment tests for real (#95600)
https://github.com/vercel/next.js/pull/95550 wasn't enough:

-
https://github.com/vercel/next.js/actions/runs/28907225463/job/85769093204
-
https://github.com/vercel/next.js/actions/runs/28907225463/job/85769093252

Because `VERCEL_IMMUTABLE_STATIC_FILES_ENABLED` might be set, but it
still only works when using adapters, so it broke in the non-adapter
deploy test jobs.

Also prepare for when we switch the default of `NEXT_ENABLE_ADAPTER` by
setting it explicitly to `0` for when we want to test the old CLI
builder.
2026-07-08 14:16:35 +02:00
Benjamin Woodruff bd77087864 [ci] Migrate webpack tests back to arm runners (#95549)
I partially rolled back CI jobs because we ran out of runners. IT
increased the concurrency from 50 to 100, so I've been slowly migrating
back to arm runners while watching that we don't end up with long queue
times again.

Thread: https://vercel.slack.com/archives/C0B0LKK5QD7/p1782838752523649

Average job queue time in the last day has been 59 seconds:

https://github.com/vercel/next.js/actions/metrics/performance?dateRangeType=DATE_RANGE_TYPE_CUSTOM&range=1783296000000-1783296000000
2026-07-07 07:50:14 -07:00