Commit Graph

1130 Commits

Author SHA1 Message Date
Sebastian "Sebbie" Silbermann cd3476c3c8 [ci] Add stats comment with partial stats (#95401)
We used to not post a comment when a part of the bundler matrix got
cancelled. Conceptually, a cancelled job is just like a failed on in the
sense of not being able to produce stats.

Now we always aggregate stats and post stats from the bundlers that did
produce them.

The risk here is a race between a run that was cancelled because another
run superseded it and the run that superseded it. Though practically,
aggregating the stats isn't slower than running the full workflow. Not
impossible (especially given how slow the Webpack job is) but incredibly
rare.
2026-07-06 19:13:28 +00:00
Sebastian "Sebbie" Silbermann f656c597c6 [fragment-scroll] Enable new scroll handler by default (#95378) 2026-07-06 18:39:07 +00:00
Hendrik Liebau 422c93ef86 Add serverComponentsHmrCancellation experimental flag (#95462)
This is the first change in a series that will let `next dev` cancel a
Server Components HMR refresh once a newer refresh supersedes it. Here
we only introduce the `experimental.serverComponentsHmrCancellation`
flag and plumb it to every place later changes will read it, without
adding any behavior yet, so on its own this change is an inert no-op.

The flag is declared in `ExperimentalConfig`, validated in the Zod
schema, and defaults to `false` in `defaultConfig`. We thread it into
the runtime config via the `NextConfigRuntime` pick list and
`getNextConfigRuntime`, expose it to user-bundled client code through
`define-env` as `process.env.__NEXT_SERVER_COMPONENTS_HMR_CANCELLATION`,
and pass it into the app render options in `base-server.ts` and the
`app-page` build template. The edge SSR template hardcodes it to
`false`, because edge rendering does not expose the Node response-close
signal the cancellation relies on.

So that the following changes are exercised as soon as their behavior
lands, `config.ts` honors a
`__NEXT_EXPERIMENTAL_SERVER_COMPONENTS_HMR_CANCELLATION` environment
variable that forces the flag on while still respecting an explicit user
config value, mirroring how `cachedNavigations` is rolled out. Both the
`test-cache-components-dev` and `test-cache-components-prod` CI shards
export that variable: the development shard so the feature is exercised
once its behavior lands, and the production shard as a guard that this
development-only feature stays inert in production even with the flag
enabled. The default stays `false`; a later change flips it once the
implementation is complete and drops the shard overrides.
2026-07-04 14:23:35 +02:00
Sebastian "Sebbie" Silbermann d3169de7e5 Collect modules with browser variants statically (#95200)
Instead of hardcoding the list, we now automatically detect any
`.browser` sibling and create a compiler alias for that module.

Together with a linting rule, we'll ensure no future regressions are
handled automatically (detection of conditional require and missing
.browser sibling).

This isn't the smoothest DX yet. Ideally we'd generate the list at
Next.js compile time (i.e. before publishing) to avoid having to rerun a
script (I'll follow-up). Generating the list during build time (next dev
or next build) is just another tiny cost users would have to pay.
2026-07-03 08:45:23 +02:00
Benjamin Woodruff 6f592dec9d [ci] Disable mid-stack PR optimization for native PR stacks (#95427)
https://vercel.slack.com/archives/C04KC8A53T7/p1783018076576349

<img width="1015" height="347" alt="Screenshot 2026-07-02 at 11 57
05 AM"
src="https://github.com/user-attachments/assets/74d99079-d165-435a-aece-161862795ef6"
/>

If we're in the middle of a stack, but the PRs below us in the stack are
already merged, we should not skip CI jobs. This logic isn't smart
enough to handle that.
2026-07-02 19:28:37 +00:00
Benjamin Woodruff 24262a8212 [ci] Actually migrate Turbopack jobs back to ARM (#95386)
This is embarrassing, I wasn't paying enough attention when I put up
#95374. We have to both change the build dependency *and* switch the
machine type...
2026-07-02 08:40:01 -07:00
Benjamin Woodruff a26a1d640b [ci] Avoid running full CI mid-stack for GH-native stacks, same as we do for Graphite (#95218)
Running CI only on the top and bottom of the stack avoids expensive
`O(n^2)` behavior when merging one PR at a time and recursively rebasing
all the others starting at the bottom of the stack.

GitHub added this to the webhook/GH actions object for us to be able to
do this: https://vercel.slack.com/archives/C01SKER9S1G/p1777926655162839

Prior to this PR being part of a stack, fails open (runs full CI):
<img width="1938" height="993" alt="Screenshot 2026-06-26 at 3 03 37 PM"
src="https://github.com/user-attachments/assets/54d6055a-2860-45b3-a03a-a9356b3db2a4"
/>

Example mid-stack run (skips the full e2e jobs):
<img width="1917" height="664" alt="Screenshot 2026-06-26 at 3 24 33 PM"
src="https://github.com/user-attachments/assets/9ee466da-f3ea-4298-b5b8-2527d197c121"
/>

https://github.com/vercel/next.js/actions/runs/28268549361/job/83760907003?pr=95219
2026-07-01 23:22:24 -07:00
Benjamin Woodruff 36331cfe3b [ci] Migrate Turbopack build_and_test jobs back to arm64, leave webpack jobs as x86-64 (#95374)
IT increased the concurrency limit from 50 to 100. This ramps back up
the `build_and_test` job. I'll keep an eye out for long queue times
before migrating us all the way back to arm64.


https://vercel.slack.com/archives/C0B0LKK5QD7/p1782910263667649?thread_ts=1782838752.523649&cid=C0B0LKK5QD7
2026-07-01 21:47:32 +00:00
Benjamin Woodruff 7b68a3135f [ci] Migrate some CI jobs back to x86-64, build both arm and x86-64 native binaries, include both os and architecture in native artifact names (#95341)
This should be a more robust version of
https://github.com/vercel/next.js/pull/95332 that re-introduces some
x86-64 runners, but also properly segments the artifact cache.

Even if we don't end up merging this, this does some cleanup of
`uploadNativeArtifact` that might be useful to pull out into a separate
PR.
2026-07-01 10:39:43 +02:00
Benjamin Woodruff 860c0742e9 [ci] Add optimize-ci, changes, and fetch-test-timings jobs to the needs list for the tests-pass job (#95339)
On #95332, the `fetch-test-timings` job failed. That caused downstream
jobs to get a "skip" state, instead of a failure state, which then
caused `tests-pass` to succeed. This is because if a dependency job
fails, GitHub's default behavior is for the downstream job to skip, and
to not cascade the failure.

Depending on all of these helper jobs seems like the simplest way to
prevent this from happening in the future.
2026-07-01 10:39:43 +02:00
Benjamin Woodruff c2edfabcdd Revert "[ci] Move some test suites back to x86-64 runners to reduce pressure on our currently-limited pool of arm runners (#95332)" (#95336)
There was a bug in this PR
(https://github.com/vercel/next.js/pull/95332#discussion_r3502904527)
but it "passed" CI and auto-merged because `fetch test timings` failed
causing downstream jobs to end up in a skipped state. I'll fix that in a
separate PR.
2026-07-01 06:07:18 +02:00
Benjamin Woodruff 792f746339 [ci] Move some test suites back to x86-64 runners to reduce pressure on our currently-limited pool of arm runners (#95332)
https://vercel.slack.com/archives/C0B0LKK5QD7/p1782838752523649

This is a mitigation until we can get IT to increase the concurrency on
`ubuntu-latest-16-core-arm-oss` runners.
2026-07-01 02:41:34 +00:00
Sebastian "Sebbie" Silbermann dcb662c7fb [ci] Add support for auth based preview build registries (#95204)
Follow-up to https://github.com/vercel/next.js/pull/93464 which didn't
consider auth based preview build registries.
2026-06-30 20:59:15 +02:00
Benjamin Woodruff 38bd101b10 [ci] Migrate build_and_test and pull_request_stats to use arm64 runners (#94870)
A 16 core x86-64 runner is $0.042/minute. A 16 core arm64 runner is
$0.026/minute.
https://docs.github.com/en/billing/reference/actions-runner-pricing

It also looks like they're faster! After factoring the performance
improvement, this appears to be a ~50% cost reduction for migrated jobs.

Datadog SQL:

```
SELECT
  REGEXP_REPLACE(ci_job_name, '\s*\([0-9]+/[0-9]+\)', '') AS ci_job_name,
  labels,
  branch,
  commit_date,
  SUM(duration) / 1000 / 1000 / 1000 / 60 as minutes,
  ci_pipeline_id
FROM dd.ci_pipelines(
    columns => ARRAY ['@git.commit.committer.date', '@ci.pipeline.id', '@duration', '@git.branch', '@ci.node.labels', '@ci.job.name'],
    event_type => 'job',
    filter => '@git.repository.id_v2:github.com/vercel/next.js @ci.pipeline.name:build-and-test @ci.provider.instance:github-actions @ci.pipeline.id:(28266192824-1 OR 28266190122-2) -@ci.job.name:*changed*',
    from_timestamp => now() - INTERVAL '30 days',
    to_timestamp => now()
  ) AS (
    commit_date VARCHAR,
    ci_pipeline_id VARCHAR,
    duration BIGINT,
    branch VARCHAR,
    labels VARCHAR,
    ci_job_name VARCHAR
  )
GROUP BY
  REGEXP_REPLACE(ci_job_name, '\s*\([0-9]+/[0-9]+\)', ''),
  labels,
  commit_date,
  branch, 
  ci_pipeline_id
ORDER BY 
  REGEXP_REPLACE(ci_job_name, '\s*\([0-9]+/[0-9]+\)', ''),
  branch,
  commit_date,
  minutes;
```


https://app.datadoghq.com/ddsql/editor?ddsql_dataset_id=34de66b9-30f4-48dd-ac98-354dc7e67fdf

Full Data:
https://docs.google.com/spreadsheets/d/1SszR3RsPeJ13nVW5ggMakwy87fkQMqWMHbZDehHH8IA/edit?usp=sharing

Here's the abbreviated data for jobs longer than 5 minutes:
<img width="1187" height="656" alt="Screenshot 2026-06-26 at 4 38 00 PM"
src="https://github.com/user-attachments/assets/9341039e-c4ea-405c-8d24-cdbc5ed1ba24"
/>

It seems like for the jobs switched over to arm64, they run in about
~73-82% of the time as arm.
2026-06-30 09:57:35 -07:00
Sebastian "Sebbie" Silbermann 287c04cf86 [ci] skip Datadog git metadata upload on junit upload (#95210)
Pass `--skip-git-metadata-upload` to all `datadog-ci junit upload`
invocations. This stops the in-CI git metadata sync, which forces an
expensive `git fetch` unshallow on every shallow CI checkout before each
test-report upload.

We don't need to upload git metadata manually since our GH actions are
directly integrated with DataDog via app.

> Git metadata upload is only required if you can’t integrate your CI
provider directly with Datadog. If you are using a [source code provider
integration](https://docs.datadoghq.com/code_coverage/setup/?tab=github#integrate-with-source-code-provider),
such as Datadog GitHub app or Gitlab integration, you can disable the
git metadata upload by passing the --skip-git-metadata-upload=1 flag to
the datadog-ci coverage upload command, like this:


--https://docs.datadoghq.com/code_coverage/setup/?tab=github#coverage-upload-outputs-could-not-sync-git-metadata-error

## test plan

- [x] no more unshallow when uploading junit reports to DataDog: [upload
from this branch shows no "syncing git
metadata"](https://github.com/vercel/next.js/actions/runs/28252881331/job/83708778650?pr=95210#step:38:113)
that [you'd used to see on prior
uploads](https://github.com/vercel/next.js/actions/runs/28252765955/job/83708485242?pr=95207#step:38:112)
2026-06-26 10:59:17 -07:00
Sebastian "Sebbie" Silbermann 1d09001f0c [cd] Allow forcing a release without new commits (#95136) 2026-06-25 05:25:22 +00:00
Sebastian "Sebbie" Silbermann 69acc33f03 [ci] Make automatic native binding install opt-in (#95114)
A `pnpm install` installs native bindings for Next.js by default. This
makes sense for local development where half of the team doesn't work on
native code and just needs the most recent bindings. However, CI almost
exclusively wants to test with bindings that are built from the current
commit. The rest doesn't need native bindings at all.

The only exception is `test_examples` which is likely not functional.
Though we still support it by allowing to opt-into automatically
installing native bindings in CI.

## test plan

- [x] fetch test timings still skips:
https://github.com/vercel/next.js/actions/runs/28087707205/job/83157705446?pr=95114#step:7:228
2026-06-24 22:39:36 +02:00
Sebastian "Sebbie" Silbermann 681940523a [cd] add ad-hoc preview release cut from canary (#95086)
Add a `preview` release type so `@preview` npm releases can be cut
**ad-hoc from `canary`** via the `Trigger Release` workflow, retiring
the dedicated long-lived preview branch. The GitHub environment has been
updated accordingly.

A preview cut produces **two commits**, pushed in a single update:

1. **Bump-to-preview** — all packages set to the computed preview
version, tagged `v…-preview.N`. This tag's build publishes `@preview`
(relies on #95085).
2. **Revert-to-canary** — restores the `-canary.N` versions so `canary`
keeps advancing its own line and isn't stranded on a preview version.

```
B  canary HEAD before cut (e.g. 16.3.0-canary.61)
│
P  v16.3.0-preview.N   ← tag here; tag build publishes @preview
│
R  canary HEAD after cut (versions restored to 16.3.0-canary.61)
```

### Preview version numbering

`base = max(canary major.minor.patch, npm @preview major.minor.patch)`:
- base still on the published preview line → continue it (`n + 1`)
- canary advanced to a higher base (or no `@preview` published) → reset
to `.0`

So if `canary` jumps to `18.0.0-canary.x` since the last
`16.3.0-preview.x`, the next cut is `18.0.0-preview.0`, not a
continuation.

## Test plan

The dry mode of `start-release.js` was extended to intercept the GH
requests and log the relevant data.

```console
$ node ./scripts/start-release.js --release-type preview --dry-run
Dry run: keeping commits locally, skipping git push and GitHub release creation
Running pnpm release-preview...
[...]
> lerna version 16.3.0-preview.4 --force-publish -y --no-push --allow-branch '**'
[...]
Creating GitHub-signed release commit(s) for v16.3.0-preview.4 from local commits 0f5c1e865cc34edb257a16823ed6525d9cd58bfc..0062348c411776271fe7eac64e97b8bad2775b77
[dry-run] GitHub API POST /repos/vercel/next.js/git/blobs [...]
[dry-run] GitHub API POST /repos/vercel/next.js/git/commits {"message":"v16.3.0-preview.4","tree":"0000000000000000000000000000000000000016","parents":["0f5c1e865cc34edb257a16823ed6525d9cd58bfc"]}
[dry-run] GitHub API POST /repos/vercel/next.js/git/commits {"message":"Restore canary version 16.3.0-canary.61 after v16.3.0-preview.4 preview release","tree":"000000000000000000000000000000000000002d","parents":["0000000000000000000000000000000000000017"]}
[dry-run] GitHub API POST /repos/vercel/next.js/git/refs {"ref":"refs/tags/v16.3.0-preview.4","sha":"0000000000000000000000000000000000000017"}
[dry-run] GitHub API PATCH /repos/vercel/next.js/git/refs/heads/sebbie/preview-release-from-canary {"sha":"000000000000000000000000000000000000002e","force":false}
Dry run: skipping local branch sync; would set sebbie/preview-release-from-canary to 000000000000000000000000000000000000002e and tag v16.3.0-preview.4 at 0000000000000000000000000000000000000017
Created GitHub-signed release tag v16.3.0-preview.4 at 0000000000000000000000000000000000000017; branch sebbie/preview-release-from-canary now at 000000000000000000000000000000000000002e
Dry run: skipping GitHub release creation
Release process is finished
```
2026-06-24 16:33:37 +02:00
Sebastian "Sebbie" Silbermann e2f853850e [ci] Make preview tarballs available while new Canaries are being published (#95112)
Fixes 

>This environment is not supported by Next.js or publish of
16.3.0-canary.64 is incomplete.

--
https://github.com/vercel/next.js/actions/runs/28082958066/job/83141991913#step:7:246
2026-06-24 16:32:48 +02:00
Sebastian "Sebbie" Silbermann c8ff8b1c52 [cd] publish on release tags instead of branch push (#95085)
That way we can push multiple commits when doing a release. For
canaries, nothing will change.

In a follow-up, we'll start cutting `@preview` from the `canary` branch.
To support that case, we need to immediately revert the version in
`lerna.json`. We shouldn't push commits indidually to avoid having an
incomplete release if something else is pushed between `@preview`
version bumps and `@canary` version reverts.

## test plan

After merge, the next canary release should publish from the
`v…-canary.N` tag run (`deploy-target = production`), while the canary
branch push for the same commit shows `skipped` — exactly one production
run per release.



<!-- NEXT_JS_LLM_PR -->
2026-06-24 08:52:30 +02:00
Benjamin Woodruff 51d440520a [ci] Only install chromium-headless-shell and not chromium (#94882)
Because it's not sure which one you'll want, playwright installs TWO
copies of Chromium by default. A full copy and a stripped down headless
version.

Most of the install time is spent in `apt-get`/`dpkg`, but this at least
buys us a few seconds back.

Before:

![Screenshot 2026-06-16 at
6.02.44 PM.png](https://app.graphite.com/user-attachments/assets/1cb05dca-c36d-472d-8ffd-1e177f77fc10.png)

After:

<img width="1700" height="552" alt="Screenshot 2026-06-16 at 6 24 50 PM"
src="https://github.com/user-attachments/assets/d382cb8e-a875-4d67-92d6-32ff51c06488"
/>


Playwright also installs ffmpeg in case you want to perform a screen
recording (we don't), but it's much smaller (2.3 MiB), and there doesn't
appear to be a way to disable it.
2026-06-17 21:20:01 +00:00
Sebastian "Sebbie" Silbermann 47c8c6fc92 [cd] Continue release train if @next/swc-wasm-* fails to publish (#94912)
https://github.com/vercel/next.js/pull/94622 tried to be more strict
with when a release is considered healthy. However, `@next/swc-wasm-web`
is not enrolled in Trusted Publishing and blocks the release train.

This PR restores the behavior for `@next/swc-wasm-*` packages prior to
https://github.com/vercel/next.js/pull/94622 i.e. we continue the
release train even if any `@next/swc-wasm-*` fails. Other NAPI bindings
will continue to block the release train if they fail to publish.

The bail vs no-bail behavior is controlled with a repository variable so
that we can mor easily test if `@next/swc-wasm-web` is enrolled in
Trusted Publishing.
2026-06-17 20:49:57 +02:00
Sebastian "Sebbie" Silbermann 618957c166 [cd] More robust publish pipeline (#94622) 2026-06-17 19:44:59 +02:00
Benjamin Woodruff eb9b1dad10 [ci] Remove playwright stamp file logic (#94876)
This is left over from self-hosted runners. This should never be used in
gh hosted runners.
2026-06-17 09:08:41 -07:00
Luke Sandberg 723c06200d switch our test benchmark runs to release-with-assertions (#94538)
In ci when testing our benchmarks use our test profile
`release-with-assertions`

This avoids an expensive `lto` step and ensures that our tests run with
debug asserts.

I noticed that our workflow for 'test cargo benches' was very slow and a
lot of that time was the build presumably due to lto overheads across so
many benchmark binaries.


Compare:

* cargo benches for this pr:
https://github.com/vercel/next.js/runs/79974366863?pr=94538
   - build=4m42s
   - test=1m46s
* cargo benches before this pr:
https://github.com/vercel/next.js/actions/runs/27097792020/job/79973082715#logs
   - build=8m23s
   - test=6m56s

Of course doing this revealed a few things

* a birthday paradox panic in one of the persistence tests
* some 'top level read' errors to address in the benchmarks and in the
turbopack-cli server used for some benchmarks.

And finally, that the persistence tests are just extremely slow in test
mode due to their initialization overhead (populating >1GB dbs), so that
harness is rewritten to remove some variants and also to reduce max
sizes in test mode
2026-06-17 16:05:05 +00:00
Benjamin Woodruff b08fb8d922 [ci] Clean up references to self-hosted runners (#94827)
We're no longer using self-hosted runners. I had claude look for places
where we had references to self-hosted runners and I had it clean them
up.

Stats job for this PR:
https://github.com/vercel/next.js/actions/runs/27572281422/job/81511924690?pr=94827
2026-06-16 09:17:10 -07:00
Benjamin Woodruff 36a8f4c271 [ci] Use node-version-file when we already have a repository checkout and reduce hardcoded references to node versions (#94780)
I noticed the `node-version-file` option for `setup-node` while
reviewing https://github.com/vercel/nextjs-react-compiler/pull/2

We should use it in places where we're already checking out the
repository anyways. It should make it easier to keep node versions in
sync.
2026-06-16 00:48:22 +00:00
Luke Sandberg cd1a292c7b pass --locked to cargo binstall (#94834)
If `binstall` fails to download a precompiled artifact it falls back to
`cargo install` and many tools (like `nextest`) require the `--locked`
flag. So pass the `--locked` flag.
2026-06-15 17:18:44 -07:00
Cong-Cong Pan eacb749030 chore: upgrade next-rspack to rspack 2.0 (#92222)
## Summary
- upgrade `@rspack/core` to `2.0.0-rc.0`
- sync the in-tree next rspack Rust binding/toolchain with newer rspack
releases
- align Next server runtime selection so `NEXT_RSPACK` uses the
turbo-like app runtime path
- include missing compiled `@next/react-refresh-utils` output in
`ncc-compiled`

## What is done
- `@next/rspack` Rust binding builds locally
- `packages/next` builds locally
- rspack-related tests are running and have been reduced to deeper
runtime compatibility failures

## Rspack test investigation
Latest checked CI run: `build-and-test` run `27129243230` at head
`484e7bf1b30655a9f94d0855b9e00774b4b38cd0`.

Confirmed Rspack / webpack parity gaps:
-
`test/e2e/edge-runtime-configurable-guards/edge-runtime-configurable-guards.test.ts`:
Rspack does not expose the webpack parser hooks used by
`MiddlewarePlugin`. The current Rspack path falls back to SWC analysis
in `finishModules`, which can report diagnostics but cannot apply the
parser-time transforms that wrap `eval` / `new Function`, track
`InnerGraph` usage for used vs unused dynamic code, or apply
`unstable_allowDynamic` with webpack parity. Dev therefore misses the
expected dynamic-code runtime warnings and also reports false
`process.cwd` Edge warnings from Next internals; prod fails
allowed/unused dynamic-code cases.
-
`test/development/middleware-overrides-node.js-api/middleware-overrides-node.js-api.test.ts`:
same parser-hook limitation. Webpack can observe that `process.cwd` is
overwritten before use, while the Rspack SWC fallback statically flags
`process.cwd` as an unsupported Edge Node API.
- `test/production/css-features/css-compilation.test.ts`: the CSS is
minified and prefixed as expected, but the Rspack lightningcss path
currently does not expose/control source map generation the way this
test expects, so emitted CSS has no `sourceMappingURL` comment or `.map`
file to assert.
- `test/e2e/app-dir/server-source-maps/server-source-maps.test.ts`:
invalid source maps are not handled with the same graceful diagnostic as
webpack/Node source-map handling. Rspack logs the raw `webpack-internal`
frame for the damaged map case instead of surfacing the expected
`Invalid source map. Only conformant source maps...` message with the
cause.
-
`test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts`:
raw CI output observed a dev-mode timeout waiting for `networkidle`
after refresh/back/forward lazy fetching. This was not the final
structured failure in the latest run, but it remains a Rspack dev parity
follow-up around router cache lazy fetches and network settling.
- `test/e2e/middleware-src/middleware-src.test.ts`: after the test adds
root middleware files, Rspack dev still lets `src/middleware`
participate; the expected behavior is that only the root middleware
runs.
- `test/e2e/env-config/env-config.test.ts`: changing `.env` logs `Reload
env:` but the client keeps the previous `NEXT_PUBLIC_` value, pointing
at an Rspack dev env invalidation/HMR gap.
-
`test/e2e/app-dir/use-cache-without-experimental-flag/use-cache-without-experimental-flag.test.ts`:
after enabling the `useCache` flag, the dev server does not finish
restarting, pointing at build-error recovery/restart parity.
-
`test/development/app-dir/server-navigation-error/server-navigation-error.test.ts`:
middleware navigation-error cases hit `ERR_CONNECTION_REFUSED`,
consistent with the Rspack dev server exiting or restarting unexpectedly
during those error flows.
- `test/e2e/opentelemetry/instrumentation/opentelemetry.test.ts`: the
custom-server dev process exits before the SDK handle is initialized,
then cleanup fails on `shutdown`; this needs follow-up in Rspack
dev/custom-server startup.
- `test/e2e/next-image-new/app-dir/app-dir.test.ts`: after toggling
image source, `onLoadingComplete` still reports the previous image
dimensions/source, pointing at an Rspack dev image/HMR or asset
invalidation parity issue.
- `test/e2e/node-cli-args/node-cli-args.test.ts`: on Node `20.19.x`,
`node --experimental-network-inspection` resolves instead of rejecting.
This looks like a Node-version behavior change rather than an Rspack
compiler issue.

Not attributed to this Rspack upgrade:
-
`test/e2e/app-dir/instant-navigation-testing-api/instant-navigation-testing-api.test.ts`
was marked by `scripts/pr-status.js` as a known flaky test across
branches.
-
`test/production/app-dir/build-output-prerender/build-output-prerender.test.ts`
ran in the webpack prod job and only differs by prerender error ordering
in the inline snapshot.


<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
2026-06-15 23:19:53 +00:00
Sebastian "Sebbie" Silbermann 069345bf55 [ci] Allow "rerun failed jobs" to work up until 5 days for e2e deploy tests (#94812) 2026-06-15 10:56:57 +00:00
Sebastian "Sebbie" Silbermann 902a7c3e5d [ci] Always upload canary tarballs from the canary branch (#94557) 2026-06-12 10:06:41 +02:00
Benjamin Woodruff b8d268d0da [ci] Download fnm directly from GitHub releases and validate checksum (#94579)
I determined that [`nvm` wasn't sufficient for our use-case since we
need to support
windows](https://github.com/vercel/next.js/pull/94175#issuecomment-4654622674),
so this doubles down on `fnm`.

This reduces risks of supply chain attacks with `fnm`.

This also cleans up some old stuff that was left over from self-hosted
runners and/or that was there for debugging, if it isn't useful anymore.
2026-06-10 14:23:29 -07:00
Benjamin Woodruff 3caee03f2a [ci] Reduce usage of turborepo cache in build_and_deploy.yml (#94319)
We're consolidating on `actions/cache` now that we got rid of
self-hosted runners. This doesn't remove all of the uses of turborepo's
cache (notably sccache), but this does eliminate the remote turborepo
cache for the native build cache and the docker image.

These build steps use docker so that we're building against an old
pinned glibc (2.31), and so that we can have access to both `aarch64`
and `x86_64` musl sysroots.

## Testing

**Local Build:** `node scripts/docker-native-build.js` still works (this
script just exists for being able to debug these builds locally)

**CI Build:**
- Run an automated-preview CI job, but cancel it before the native build
succeeds to test writing to the docker cache but not the native cache:
https://github.com/vercel/next.js/actions/runs/26986955366/job/79638633136?pr=94319
- Re-run the job with only the docker image cache, see that we get a
cache hit for the docker image:
https://github.com/vercel/next.js/actions/runs/26986955366/job/79639365126?pr=94319
- Re-run the job again and see that we hit the native build cache hit
and don't touch docker at all:
https://github.com/vercel/next.js/actions/runs/26986955366/job/79647324952?pr=94319
- Manually trigger the job to do a full preview build:
https://github.com/vercel/next.js/actions/runs/26989861549
2026-06-10 14:23:18 -07:00
Sebastian "Sebbie" Silbermann 9af81ed9a1 [cd] Ensure release can be triggered on old branches (#94596) 2026-06-09 10:25:17 -07:00
Benjamin Woodruff fc8edc4722 [ci] Remove dead playwright docker image creation logic (#94576)
We reverted the use of this docker image in
https://github.com/vercel/next.js/pull/94366

We're going to use GitHub actions custom runner images instead (which
don't use docker)
2026-06-09 10:15:47 -07:00
Tim Neutkens c082ffe4e2 Reduce new test concurrency to five (#94552)
### What?

Reduce the `test-new-tests-dev` and `test-new-tests-start` workflow
matrices from ten groups to five.

### Why?

Restore these flake-detection jobs to five concurrent shards.

### How?

Change each matrix group list from `1/10` through `10/10` to `1/5`
through `5/5`.

### Verification

- `pnpm prettier --with-node-modules --ignore-path .prettierignore
--check .github/workflows/build_and_test.yml`
- `git diff --cached --check`

<!-- NEXT_JS_LLM_PR -->
2026-06-08 17:43:22 +02:00
Sebastian "Sebbie" Silbermann 00db625ff6 [ci] Disable on-call notification if manual deploy e2e tests failed (#94554) 2026-06-08 15:30:33 +00:00
Benjamin Woodruff e8638a6c07 Revert "[ci] Increase TEST_CONCURRENCY from 8 to 12 (#94138)" (#94517)
There's some evidence that this was meaningfully increasing flakiness:
https://vercel.slack.com/archives/C04KC8A53T7/p1780773226831399
2026-06-06 21:41:53 +00:00
Benjamin Woodruff ef63481d68 [ci] Set persist-credentials: false for all GH actions (#94214)
The actual security implications of this are likely *very* minor, but in
the interest of reducing how many credentials we have, there's little
reason for us not to set this to `false`.

In cases where we create a new commit via GH actions, we already do that
via the GitHub API, so those don't need the on-disk git credentials to
push.

---

From: https://github.com/actions/checkout :

> The auth token is persisted in the local git config. This enables your
scripts to run authenticated git commands. The token is removed during
post-job cleanup. Set persist-credentials: false to opt-out.

```
    # Whether to configure the token or SSH key with the local git config
    # Default: true
    persist-credentials: ''
```
2026-06-05 18:28:18 +00:00
Benjamin Woodruff 2b8f5f59a3 [ci] Switch release-next-rspack to a more explicit environment name (#94480)
Matches the environment name I asked IT to use for NPM trusted
publishing:
https://vercel.slack.com/archives/C01LN7C5QR5/p1780600987032909

Nothing else uses the `npm` environment, but the name is confusing. We
want to use separate environments for these publishing workflows as they
allow us to define things like reviewers, if we want to block the
release on a manual review.
2026-06-05 11:19:30 -07:00
Benjamin Woodruff 7147d0e036 Revert "ci: run Linux Playwright jobs in prebuilt Microsoft container (#93794)" (#94366)
We're going to go with custom images instead, though we don't have an
implementation for this yet.

This does save a meaningful amount of minutes, but it also significantly
increases complexity.

This is a clean revert, minus the fix that the PR included for listening
on localhost in `packages/next/src/build/analyze/index.ts`, which is
still good.
2026-06-05 17:21:21 +00:00
Tim Neutkens b92cf40ee6 Enable Node streams by default (#94311)
### What?

Defaults `experimental.useNodeStreams` to `true` while keeping the
experimental config flag and explicit `false` opt-out available. Removes
redundant dedicated node-stream CI jobs because the ordinary path
exercises Node streams after this change.

Depends on the standalone test compatibility update in #94347, which
intentionally remains outside the Node streams PR stack.

### Why?

Node streams can be exercised through the standard Node.js App Router
test path once they are the default, allowing a smaller rollout before
the larger follow-up that removes the flag and obsolete plumbing.

CI exposed one necessary compatibility fix for this intermediate state:
projects with a `next.config.*` received the new default after raw
experimental-feature processing, leaving the runtime stream selector on
the web implementation while compiled app code selected Node stream
helpers.

### How?

- Set `defaultConfig.experimental.useNodeStreams` to `true`.
- Synchronize `__NEXT_USE_NODE_STREAMS` from the fully resolved config,
including cached and standalone resolved configs, so defaults and
adapter modifications are reflected at runtime.
- Preserve the current public config/schema and explicit `experimental:
{ useNodeStreams: false }` opt-out; edge bundles continue to define the
stream flag as `false`.
- Remove the dedicated node-stream test jobs and now-unused manifest;
the affected streaming assertion compatibility changes are isolated in
#94347.

### Verification

Run before extracting the prerequisite assertion changes into #94347:

- `pnpm --filter=next types`
- `pnpm --filter=next build`
- `IS_WEBPACK_TEST=1 __NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES=true pnpm
test-start-webpack
test/e2e/app-dir/ppr-root-param-fallback/ppr-root-param-fallback.test.ts`
- `IS_TURBOPACK_TEST=1 TURBOPACK_BUILD=1
__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES=true pnpm test-start-turbo
test/e2e/app-dir/ppr-root-param-fallback/ppr-root-param-fallback.test.ts`
- `IS_WEBPACK_TEST=1 __NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES=true pnpm
test-start-webpack
test/e2e/app-dir/use-server-inserted-html/use-server-inserted-html.test.ts`
- `pnpm test-dev-webpack
test/e2e/app-dir/ppr-root-param-fallback/ppr-root-param-fallback.test.ts
test/e2e/app-dir/use-server-inserted-html/use-server-inserted-html.test.ts`
- `pnpm test-dev-turbo
test/e2e/app-dir/ppr-root-param-fallback/ppr-root-param-fallback.test.ts
test/e2e/app-dir/use-server-inserted-html/use-server-inserted-html.test.ts`
- `pnpm test-start-webpack
test/production/app-dir/use-node-streams-env-precedence/use-node-streams-env-precedence.test.ts`
- `pnpm test-start-webpack test/e2e/app-dir/app/standalone.test.ts`

<!-- NEXT_JS_LLM_PR -->
2026-06-02 21:34:22 +02:00
Tim Neutkens 8bb6aa9708 Delay Node Fizz piping until after render task (#94347)
### What?

Delay dynamic Node Fizz piping by one React render task after
`onShellReady()`, and keep the dedicated Node-stream CI jobs scoped to
`test/use-node-streams-tests-manifest.json`.

### Why?

The Node adapter started `pipeable.pipe(pt)` inside `onShellReady()`,
before the existing continuation delay could take effect. In App Router
renders backed by RSC, that caused short-lived Suspense boundaries to
flush fallback and reveal markup that the web-stream path avoids by
waiting before its first pull.

The previous test assertion relaxations hid this runtime mismatch. The
original assertions pass once piping starts after the settling window,
so they have been restored.

The workflow correction remains necessary because merging the
cache-components manifest into the ordinary Node-stream jobs filtered
out relevant e2e coverage.

### How?

- Resolve the Node Fizz shell promise from `onShellReady()` without
immediately piping.
- For dynamic renders, wait one React render task and then start piping
into the `PassThrough`.
- Preserve the existing `onAllReady()` behavior for static generation.
- Use the Node-stream manifest alone for ordinary Node-stream dev and
prod CI jobs.

### Verification

- `pnpm --filter=next build`
- `__NEXT_USE_NODE_STREAMS=true
__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES=true NEXT_TEST_PREFER_OFFLINE=1
pnpm test-dev-turbo
test/e2e/app-dir/ppr-root-param-fallback/ppr-root-param-fallback.test.ts`
- `__NEXT_USE_NODE_STREAMS=true
__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES=true NEXT_TEST_PREFER_OFFLINE=1
pnpm test-dev-turbo
test/e2e/app-dir/use-server-inserted-html/use-server-inserted-html.test.ts`

<!-- NEXT_JS_LLM_PR -->
2026-06-02 21:34:21 +02:00
Sebastian "Sebbie" Silbermann 06080d0281 [cd] Stop fetching all tags when searching parent tag (#94302) 2026-06-02 06:54:54 +00:00
Benjamin Woodruff 0a355571a0 [ci] Update all actions/* dependencies (#94174)
Previously we pinned all of these to their current versions at the time.
That meant that some of these got pinned to really old versions. This
updates all of the "first-party" `actions/*` dependencies.

Prompted claude with:

```
For all of these uses of actions/*, make sure we're pulling in the latest stable version (check the gh cli). When upgrading across major versions, fetch the release notes from the GH releases using the gh CLI and make sure that there are no problems that the upgrade will cause.
```

Claude read all the release notes and seems to think these upgrades are
safe.

![Screenshot 2026-05-27 at
3.36.15 PM.png](https://app.graphite.com/user-attachments/assets/4b863905-a983-43a1-ba3d-5d3cc2988bc2.png)
2026-05-28 09:26:57 -07:00
Benjamin Woodruff 3a4c36747c [ci] Use Turbopack in non-webpack-specific e2e test jobs (#94005)
Turbopack is the default bundler, so we should prioritize testing that
in these variants of the CI runs (cache components, node streams,
windows).

There's also some limited evidence that indicates that it might be
faster for e2e test runs, though that's not conclusive (because of
different shard sizes):
https://vercel.slack.com/archives/C0B0LKK5QD7/p1779320615501259
2026-05-28 00:43:59 +02:00
Benjamin Woodruff dbc973054f [ci] Rename GRAPHITE_TOKEN to GRAPHITE_CI_OPTIMIZER_TOKEN (#94166)
This secret got renamed when we issued a new one. Discussion:
https://vercel.slack.com/archives/C01LN7C5QR5/p1777662825523989

<img width="670" height="226" alt="Screenshot 2026-05-27 at 12 12 42 PM"
src="https://github.com/user-attachments/assets/65c3d125-a493-4b02-b461-3a5292604ad6"
/>


<img width="446" height="167" alt="Screenshot 2026-05-27 at 12 11 42 PM"
src="https://github.com/user-attachments/assets/24e226fb-5818-45de-9883-e8fd7d0d26c6"
/>
2026-05-27 20:10:08 +00:00
Benjamin Woodruff 3127d71efc [ci] Give the build cache in cache in build_and_deploy a more obvious name, not just a hash and run number (#93957)
This should make the output of `gh cache list` a lot clearer. Without
this, it's not obvious where these cache keys are coming from.
2026-05-27 11:36:32 -07:00
Benjamin Woodruff 6b64722383 [ci] Increase TEST_CONCURRENCY from 8 to 12 (#94138)
We're using 16 core machines, our `TEST_CONCURRENCY` of 8 is arbitrary.
This tries increasing that to 12.

- GH Actions for 8 (control, #94142):
https://github.com/vercel/next.js/actions/workflows/build_and_test.yml?query=branch%3Abgw%2Ftest-concurrency-8
- GH Actions for 12 (this branch):
https://github.com/vercel/next.js/actions/workflows/build_and_test.yml?query=branch%3Abgw%2Ftest-concurrency-12
- GH Actions for 16 (#94133):
https://github.com/vercel/next.js/actions/workflows/build_and_test.yml?query=branch%3Abgw%2Ftest-concurrency-16

It appeared that (across a couple of runs) that `TEST_CONCURRENCY=16`
*may* lead to more test failures. Plausibly this could be due to
timeouts. `TEST_CONCURRENCY=12` does not appear to be causing noticeably
more failures than usual, and seems to be slightly speeding things up.

Datadog SQL:

```
SELECT
  SUM(duration) / 1000 / 1000 / 1000 / 60 as minutes,
  branch,
  ci_pipeline_id
FROM dd.ci_pipelines(
    columns => ARRAY ['@ci.pipeline.id', '@duration', '@git.branch'],
    event_type => 'step',
    filter => '@git.repository.id_v2:github.com/vercel/next.js @ci.pipeline.name:build-and-test @ci.provider.instance:github-actions @ci.pipeline.id:(26473602379-1 OR 26484229016-1 OR 26485947297-1 OR 26493064901-1 OR 26492002693-1 OR 26485986756-1 OR 26485929595-1 OR 26484214883-1 OR 26480156826-1)',
    from_timestamp => now() - INTERVAL '30 days',
    to_timestamp => now()
  ) AS (
    ci_pipeline_id VARCHAR,
    duration BIGINT,
    branch VARCHAR
  )
GROUP BY branch, ci_pipeline_id ORDER BY branch;
```

<img width="1193" height="807" alt="Screenshot 2026-05-26 at 11 07
05 PM"
src="https://github.com/user-attachments/assets/bbd75ee1-9766-48a8-90da-6225908de251"
/>
2026-05-27 18:17:40 +00:00
Benjamin Woodruff 67d5f9615a [ci] Explicitly disable package-manager-cache for uses of actions/setup-node (#93953)
If this action detects that you're likely using `npm` it (by default)
enables a cache for `npm`. We use `pnpm`, so it doesn't do anything (and
we manually set up a pnpm cache in some places), but the implicit
behavior here is a little dangerous: e.g.
https://adnanthekhan.com/posts/angular-compromise-through-dev-infra/#finding-the-pivot

So let's explicitly disable this everywhere. It wasn't doing anything
for us anyways.
2026-05-27 06:05:07 +00:00