Commit Graph
417 Commits
Author SHA1 Message Date
Matt MastracciandGitHub dd2b8fd720 fix(ci): improve Docker image caching and native build skip optimization (#92633)
## Summary

- **turbo-cache.mjs**: Increase stream buffer from 16KB to 16MB (fixes
throughput stalls when piping large artifacts). Add transfer stats
tracking with 5s stall warning. `getToFile()` now returns `{ ok, stats
}`.
- **docker-image-cache.js**: Switch from `docker save/load` to
`export/import` (drops redundant base image layers). Use `zstd
--long=27` for better compression. Add 3x retry logic. Add arch-aware
cache key to prevent cross-arch cache poisoning. Add download stats
logging.
- **native-cache.js**: Consume new `getToFile()` return shape, log
download stats.
- **build_and_deploy.yml**: Reorder to try native binary cache restore
BEFORE Docker image restore. On cache hit, skip the expensive Docker
image download entirely.
2026-04-10 17:22:18 -06:00
Matt MastracciandGitHub e9150cadef fix(ci): improve Docker image cache streaming throughput and arch-awareness (#92617)
## What
- Increase `highWaterMark` from 16KB (Node.js default) to 16MB for
turbo-cache stream downloads and uploads.
- Include host architecture (`os.arch()`) in Docker image cache key. 

## Why

The tiny default buffer in `Readable.fromWeb()` causes constant
backpressure stalls when piping large artifacts (~500MB Docker images)
through `zstd -d | docker load`.

The image contains native binaries (Rust toolchain, lld-link symlink)
that are arch-specific — without this, an image built on x86_64 could be
restored on aarch64 with broken binaries.
2026-04-10 15:25:43 +00:00
Matt MastracciandGitHub f98a3f1101 [turbopack] Rust dependency caching via sccache (#91873)
## What

Use sccache, backed by the Vercel artifact cache, when compiling Rust
code.

## Why

Each CI runner compiles ~960 external Rust crates from scratch (~5 min)
on binary cache misses, even though `Cargo.lock` rarely changes between
commits. Some workflows don't cache and always build from scratch.

## Notes

Builds will use a local cache on each runner, but we've got a lot of
these runners and they'll take some time to populate that local, fastest
level of cache.

Windows builds are currently hitting ~68% of cached compilations for a
reason that isn't totally clear. Linux builds are caching correctly,
however. A follow-up pass at this work will use an incremental turborepo
caching strategy to improve this, and another pass will experiment with
cross-compiling Windows from Linux which will likely also help.

Linux builds that don't change Rust files at all are nearly
instantaneous (as before), and Linux builds that change Rust files will
complete in approximately 1/2 the time. `check` builds are ~1min faster
(~25% faster).

LTO-heavy runs like the benchmark builders are currently still slow
(approx unchanged), needs further investigation (may be related to git
hash embedding?).
2026-04-09 18:42:03 +00:00
6d572c27e0 scripts/pr-status: add reply-and-resolve-thread command (#92450)
### What?

Adds a `reply-and-resolve-thread` subcommand to `scripts/pr-status.js`
that combines replying and resolving a review thread in a single
command. Also updates the generated `thread-N.md` files to show this
command alongside the existing separate `reply-thread` and
`resolve-thread` options, and documents the command in the agent skill
files.

### Why?

When addressing PR review comments, the typical workflow is to reply
with a description of what was done and then immediately resolve the
thread. This previously required two separate commands:

```bash
node scripts/pr-status.js reply-thread <id> "Done -- ..."
node scripts/pr-status.js resolve-thread <id>
```

Having a single command reduces friction for agents (and humans) closing
out review threads after addressing feedback.

### How?

- Added `reply-and-resolve-thread` subcommand in `main()` that calls the
existing `replyToThread()` and `resolveThread()` functions in sequence.
- Updated `generateThreadMd()` to include a "Reply and resolve in one
step" code block in the Commands section of each unresolved thread file
(alongside the existing separate commands, not replacing them).
- Updated `.agents/skills/pr-status-triage/SKILL.md` to mention the
combined command in workflow step 6 and added a "Thread interaction"
quick-command reference section.
- Updated `.agents/skills/pr-status-triage/workflow.md` to show the
one-step alternative in the "Resolving Review Threads" section.

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Tobias Koppers <[email protected]>
Co-authored-by: Claude <[email protected]>
2026-04-07 20:36:15 +02:00
Benjamin WoodruffandGitHub 0dc354b8d7 chore: Upgrade to pnpm 10.x (#92283)
This will let us potentially use https://pnpm.io/settings#minimumreleaseage
2026-04-06 18:12:50 -07:00
Zack TannerandGitHub d5f479c128 ci: remove deploy examples workflow from build-and-deploy (#92324)
We don't need to deploy a single image component example every time
`build_and_deploy` runs. If something about this example changes, it can
be manually re-deployed.
2026-04-03 15:10:06 -07:00
e464ca398c Fix pr-status.js: retry on API errors and report timed-out jobs (#92205)
### What?

Fixes two bugs in `scripts/pr-status.js` that caused the script to
silently report zero failures when there were actual CI failures.

### Why?

When running `node scripts/pr-status.js 92080`, the script reported "No
failed jobs found" despite the PR having real failures. Two root causes:

1. **Transient API errors silently swallowed.** `getAllJobs()` had a
bare `catch { break }` that returned an empty array on any GitHub API
error (e.g., HTTP 502). Since the GitHub Actions jobs API for large runs
frequently returns transient 502s, this caused false "no failures"
reports.

2. **`timed_out` and `startup_failure` jobs were invisible.** The script
only checked for `conclusion === 'failure'`, but GitHub uses distinct
conclusion values like `timed_out` (job exceeded timeout) and
`startup_failure` (runner failed to start). These jobs fell through all
filters and were silently omitted from reports.

### How?

**Retry logic in `getAllJobs()`:**
- Retries each paginated API call up to 3 times with 2s/4s backoff
- If all retries fail on the first page, throws an error (no silent
empty results)
- If later pages fail after partial data is collected, warns and returns
what was fetched

**Broader failure detection with `FAILED_CONCLUSIONS`:**
- Added a shared `FAILED_CONCLUSIONS` set: `{'failure', 'timed_out',
'startup_failure'}`
- Used in `getFailedJobs()`, `categorizeJobs()`, and flaky test
detection
- Jobs with non-`failure` conclusions are annotated in the report table
(e.g., "(timed_out)")
- `getFailedJobs()` now also returns the `conclusion` field so
downstream code can distinguish failure types

Co-authored-by: Tobias Koppers <[email protected]>
Co-authored-by: Claude <[email protected]>
2026-04-02 13:22:13 +02:00
Matt MastracciandGitHub 4b62ff78c0 Add rust-fingerprint task and SCCACHE passthrough env (#92167)
## What

Replace duplicated Rust input globs across every turbo task with a
single rust-fingerprint task that computes a TURBO_HASH stamp file. All
Rust build/check tasks now depend on this stamp instead of repeating the
full glob list.

Also add `SCCACHE_*` to `globalPassThroughEnv` so `sccache` env vars are
available to turbo tasks.

## Why

`SCCACHE_*` and `RUSTC_WRAPPER` env vars are required to build under
sccache, but do not affect the build in a material way.

This simplifies the repeated constructs that are unfortunately difficult
to factor out, but is provably the same as listing all the files each
time (the rust-fingerprint file's content is its `TURBO_HASH`).
2026-03-31 14:15:50 -06:00
Matt MastracciandGitHub eab7a23533 [turbopack] Don't use turborepo to build the docker image (#92029)
# What

The turborepo cache appears to corrupt or truncate the docker file in
the cache - we can instead just hit the API directly and skip a few
steps.
2026-03-28 13:02:26 -07:00
JJ KasperandGitHub 9920dbace1 ci: upload adapter deploy test results (#91846)
Adds a final step to our e2e deploy test job to upload results for our
adapter for comparison.

x-ref:
https://github.com/vercel/next.js/actions/runs/23471649794/job/68298210825#step:5:40
2026-03-24 12:38:25 -07:00
Matt MastracciandGitHub b163a8bf66 [turbopack] Rebuild the docker build scripts (#91799)
## Why

The native binary build system uses 3 different napi-rs Docker images
that are opaque, can't be customized, and require runtime toolchain
downloads. Each CI run downloads compilers and sysroots from scratch,
wasting ~5 minutes per build. There's no way to customize the build
environment or share toolchains across the 4 Linux targets.

Some smoke tests are added to ensure that node.js can actually load the
binaries we build - we don't actually perform much beyond that, just
making sure it survives the dynamic linker and correctly exposes the
node APIs.

We also are able to enable `--icf=all`. This appears to (consistently)
chop off about ~1-2% of the binary size.

## What

Replaces the 3 napi-rs Docker images with a single custom
`next-swc-builder` Dockerfile based on Ubuntu 20.04 that can
cross-compile all 4 Linux targets (x86_64/aarch64 × gnu/musl) from
either an x86_64 or aarch64 host. All toolchains are baked into the
image.

Key changes:
- **`docker/native-builder.Dockerfile`**: Ubuntu 20.04 with clang/lld,
GNU cross-sysroots via `crossbuild-essential`, musl sysroots from
musl.cc, Node.js 20, pinned Rust nightly, and `cargo-rustflags` for flag
resolution
- **`scripts/docker-native-build.sh`**: Inner build script that
constructs RUSTFLAGS via `cargo rustflags --config` (merges
`.cargo/config.toml` with cross-compilation overrides), sets up CC/CXX
per target, and runs the napi build
- **`scripts/docker-native-build.js`**: Node.js local build orchestrator
replacing the bash wrapper, with `--quick`, `--rebuild`, `--test` flags
and smoke testing via `getTargetTriple()`
- **`scripts/docker-image-cache.js`**: Turbo-cached Docker image
(save/load with `--load` for cache hit handling)
- **`.cargo/config.toml`**: Added musl `crt-static` flag, removed
cross-compilation flags (now in build script)
- **CI workflows**: Docker image cached via turbo remote cache,
`build-docker-image` turbo task, simplified `build_and_deploy.yml`

## How

All 4 Linux targets use clang as the C compiler + linker driver with
`gnu-lld-cc` flavor (rust-lld does actual linking). Cross-compilation
uses `--target` + `--sysroot`:
- **GNU targets**: Ubuntu multiarch sysroots from
`crossbuild-essential-{amd64,arm64}`
- **Musl targets**: musl.cc cross-toolchain sysroots with GCC crt files
copied into sysroot lib (works around clang 10's `--gcc-toolchain`
limitation)

RUSTFLAGS are resolved inside the container via `cargo rustflags` which
merges `.cargo/config.toml` (base flags like `-Zunstable-options`, musl
`crt-static`) with per-target cross flags passed as `--config` inline
TOML.

The Docker image is cached via turbo's remote cache (~885 MB tar). On
cache hit, `docker load` restores it in seconds. On miss, the full image
build takes ~2 minutes.

### glibc compatibility

Building on Ubuntu 20.04 (glibc 2.31) ensures broad compatibility. The
table below shows the minimum glibc version required by major Linux
distributions ([source](https://repology.org/project/glibc/versions)):

| Distribution | glibc | Compatible? |
|---|---|---|
| Ubuntu 20.04 (Focal) | 2.31 | ✅ baseline |
| Ubuntu 22.04 (Jammy) | 2.35 | ✅ |
| Ubuntu 24.04 (Noble) | 2.39 | ✅ |
| Debian 11 (Bullseye) | 2.31 | ✅ |
| Debian 12 (Bookworm) | 2.36 | ✅ |
| RHEL / AlmaLinux 8 | 2.28 | ❌ EOL May 2029 (security only) |
| RHEL / AlmaLinux 9 | 2.34 | ✅ |
| Amazon Linux 2 | 2.26 | ❌ EOL June 2026 |
| Amazon Linux 2023 | 2.34 | ✅ |
| Fedora 40+ | 2.39+ | ✅ |
| Arch Linux | 2.41+ | ✅ |
2026-03-24 13:07:37 -06:00
Jiwon ChoiandGitHub f922882fac Skip CI for agent/editor config directory changes (#91622)
## Summary
- Add `.agents`, `.claude`, and `.cursor` to the `docs` group in
`CHANGE_ITEM_GROUPS` in `scripts/run-for-change.mjs`
- Changes to these directories (agent skill definitions, editor configs)
don't affect Next.js build/runtime/tests, so CI should skip for them —
same as docs-only changes
- Both `build_and_deploy.yml` and `build_and_test.yml` already use
`run-for-change.mjs --not --type docs` to detect non-docs changes; this
extends that behavior to agent/editor config files
2026-03-19 12:23:34 +00:00
Benjamin WoodruffandGitHub 68dade4679 Turbopack: Remove old macos-compress script (#90967)
@wbinnssmith added these scripts a long time ago at my suggestion/urging, but I think they ended up bad for a couple reasons that were hard to foresee at the time:

- afsctool operates in-place and doesn't atomically write the compressed file, so if the process gets interrupted, your `target` directory is corrupted. https://github.com/Dr-Emann/applesauce is better for this reason.
- This doesn't acquire the cargo lock, and modifying files while cargo is running is a good way to get corruption of the `target` directory.

https://github.com/bgw/cargo-apfs-compress is my latest attempt at solving this, though I don't have a `LaunchAgents` config for it.  
  
Regarding `node_modules`: pnpm creates reflinks from a shared global store on apfs. Trying to compress these reflinked files is just going to hurt you because it'll break the data deduplication that would've otherwise happened.
2026-03-14 01:25:49 +01:00
ca5e33d7ad [ci] Disable test-level retries during flakiness detection (#91261)
Co-authored-by: Cursor Agent <[email protected]>
2026-03-12 12:37:43 +00:00
JJ KasperandGitHub 38a1d1d73b Add RDC action test to deploy manifest and update PR test trigger (#91173)
x-ref: https://github.com/vercel/next.js/pull/91163
2026-03-10 18:45:18 -07:00
Benjamin WoodruffandGitHub 1eab3361c7 fix: Use a pnpm preinstall script to fix catch-22 in next binary creation (#91016)
We've had a longstanding issue where you'd have to run `pnpm i` _twice_ on a fresh checkout because `pnpm` wouldn't set up binary symlinks until after the binary exists, but the binary wouldn't exist until after `pnpm build` was done:

https://github.com/vercel/next.js/blob/canary/.github/workflows/build_reusable.yml#L303-L311

This solves that problem using a pnpm preinstall script that creates stub binaries for these files if they don't exist yet (because we haven't run `pnpm build`).

## Test Plan

```
git clean -fxd
pnpm i
pnpm build
pnpm test-start test/e2e/app-dir/next-image/
pnpm test-start-turbo test/e2e/app-dir/next-image/
```

I tested this both locally and inside of a fresh ubuntu VM.

Running `pnpm next` after `pnpm i` but before `pnpm build` gives a helpful error message:

<img width="946" height="125" alt="Screenshot 2026-03-06 at 9 37 14 PM" src="https://github.com/user-attachments/assets/4517e8bd-60ca-44f2-a34c-f7f3ec56c634" />
2026-03-10 11:21:15 -07:00
9c939729d1 Fix preview tarball script to include @next/swc-linux-x64-gnu (#91099)
### What?

Adds `@next/swc-linux-x64-gnu` to the preview tarball patching script
(`scripts/patch-preview-tarball.mjs`):

1. Adds the package to the `PACKAGES_TO_PATCH` list so its tarball URL
is fetched.
2. Adds the package as an explicit dependency in the patched
`package.json`, in addition to the overrides/resolutions.

### Why?

The `@next/swc-linux-x64-gnu` native binary package is an optional
dependency of `next` and may not be installed automatically depending on
the platform/package manager. When testing preview tarballs (e.g., in CI
or on Linux environments), the SWC binary needs to be explicitly present
for Next.js to function correctly. Without this change, preview tarball
testing on Linux x64 could fail because the native binary isn't resolved
from the preview build.

Adding it as a direct dependency (not just an override/resolution)
ensures the package manager actually installs it, since optional
dependencies from overridden tarballs may not be auto-resolved.

### How?

- Added `'@next/swc-linux-x64-gnu'` to the `PACKAGES_TO_PATCH` array so
the script fetches its tarball URL.
- After writing overrides/resolutions, the script now also adds
`@next/swc-linux-x64-gnu` as an explicit entry in `pkg.dependencies`
pointing to the tarball URL.

Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-03-09 14:32:12 +01:00
JosephandGitHub 762bff650f fix: run lerna on a branch (#91092)
Trying to fix: `lerna ERR! ENOGIT Detached git HEAD, please checkout a
branch to choose versions.` on `set-preview-version.js`

[Slack
thread](https://vercel.slack.com/archives/C02CDC2ALJH/p1773051154649349)
2026-03-09 13:09:47 +01:00
Tobias KoppersandGitHub 3ba53df746 Fix pr-status script missing failed jobs on page 2+ of API results (#91087)
## Summary

`getFailedJobs()` in `scripts/pr-status.js` used jq's `select(.conclusion == "failure")` filter during GitHub API pagination. When a page had 100 jobs but none were failures, jq returned empty output, and the `if (!output.trim()) break` check terminated the pagination loop early — never fetching page 2+ where actual failures existed.

For example, on PR #90755 (129 total jobs), all 100 jobs on page 1 were success/skipped, while the 2 failures (`test unit windows (22) / build` and `thank you, next`) were on page 2 (jobs 101-129). The script reported "Found 0 failed jobs" when there were actually 2.

## Fix

`getFailedJobs()` now delegates to `getAllJobs()` (which fetches all jobs without jq filtering, so pagination works correctly) and filters for failures in JavaScript afterward. This is simpler and avoids the class of bug where jq pre-filtering interacts badly with pagination.

## Test Plan

- Ran `node scripts/pr-status.js 90755` before fix: reported 0 failed jobs
- Ran `node scripts/pr-status.js 90755` after fix: correctly reported 2 failed jobs (`test unit windows (22) / build` and `thank you, next`)
2026-03-09 10:20:47 +01:00
Tobias KoppersandGitHub 5e965bbb2d Add script to patch project with preview tarball URLs (#91057)
### What?

Adds a new script `scripts/patch-preview-tarball.mjs` that patches a
target project's `package.json` to use Next.js preview tarballs from
`vercel-packages.vercel.app`.

### Why?

When testing unreleased Next.js changes against external projects (e.g.,
reproducing bugs, verifying fixes), there's no convenient way to point a
project at a specific Next.js commit's build artifacts. This script
automates the process of wiring up preview tarball URLs into a project's
dependency overrides.

### How?

The script:

1. **Resolves a commit SHA** via one of three methods:
   - `--commit <sha>` — use an explicit commit
- `--branch <name>` — look up the branch tip via the GitHub API (`gh`)
   - *(default)* — use the local `git rev-parse HEAD`

2. **Builds tarball URLs** for `next`, `@next/mdx`, `@next/env`, and
`@next/bundle-analyzer` using the
`vercel-packages.vercel.app/next/commits/<sha>/<pkg>` pattern.

3. **Verifies** that the preview tarball exists (HEAD request to the
`next` tarball URL).

4. **Patches `package.json`** in the target project (or its workspace
root) by setting both `overrides` (npm/pnpm) and `resolutions` (yarn)
for the packages.

**Usage:**

```bash
node scripts/patch-preview-tarball.mjs --project <path> [--commit <sha> | --branch <name>]
```
2026-03-09 10:13:48 +01:00
Hendrik LiebauandGitHub 87a8fb2f8f Fix preview version in window.next.version for PR builds (#90937)
Preview builds served via `vercel-packages.vercel.app` were showing the
published canary version instead of the PR-specific preview version.
This happened because `create-preview-tarballs.js` updated
`package.json` after the build, but the version was already baked into
the compiled `dist/` files by `setNextVersion` in `taskfile-swc.js`.

This extracts the version computation from `create-preview-tarballs.js`
into a new `set-preview-version.js` script that runs before `pnpm run
build`, so the compiled output naturally includes the correct version.
`create-preview-tarballs.js` now reads the version from
`packages/next/package.json` instead of computing it independently.

## Test Plan

1. Create a new app: `pnpm create next-app@canary`
2. Install the preview build from this PR: `pnpm i
https://vercel-packages.vercel.app/next/commits/06681c21e886a97e39d277808780884151c00318/next`
3. Run `pnpm dev` and inspect `next.version` in DevTools — should show
`16.2.0-preview-06681c21-20260306` instead of the canary version
2026-03-06 12:30:19 +01:00
Tobias KoppersandGitHub 2544467b80 Prefix pr-status replies with 🤖 emoji (#90943)
### What?

Prefixes replies posted by `scripts/pr-status.js` with the `:robot:` (🤖) emoji.

### Why?

When the pr-status script replies to PR review threads, there's no visual indicator that the reply was generated by AI rather than a human. Adding the robot emoji makes it immediately clear.

### How?

One-line change in the `replyToThread()` function in `scripts/pr-status.js` that prepends `:robot: ` to the reply body before posting it via the GitHub GraphQL API.
2026-03-05 12:18:24 -08:00
Tobias KoppersandGitHub de1add2539 Remove unused turbo-tasks items and add lint check (#90801)
### What?

Adds a lint script (`scripts/check-unused-turbo-tasks.mjs`) that detects
unused `#[turbo_tasks::function]`, `#[turbo_tasks::value]`, and
`#[turbo_tasks::value_trait]` definitions across the Rust codebase, and
removes all currently unused items.

### Why?

Dead turbo-tasks definitions add compilation overhead (each generates
trait impls, registrations, etc.) and make the codebase harder to
navigate. A lint check prevents regressions.

### How?

**New script** (`scripts/check-unused-turbo-tasks.mjs`):
1. Discovers all `.rs` files in `turbopack/crates/` and `crates/`
(excluding `turbo-tasks-macros-tests`)
2. Parses three kinds of turbo-tasks annotations:
- `#[turbo_tasks::function]` → extracts `fn` name + context (free,
inherent impl, trait impl, trait default)
   - `#[turbo_tasks::value]` → extracts `struct`/`enum` name
   - `#[turbo_tasks::value_trait]` → extracts `trait` name
3. Scans all files for identifier references, excluding definition sites
4. Reports any name that has no external references

The script is added to the `pnpm lint` command (runs in parallel with
other checks).

**Removed 23 unused items** across 18 files:

| Kind | Count | Examples |
|------|-------|---------|
| `value` (struct/enum) | 9 | `OutputAssetsWithAvailability`,
`ModuleNameMap`, `OptionModuleIds`, `LockedVersions`,
`AssetContentSnapshot` |
| `function` | 14 | `client_env`, `next_js_file`, `convert_path`,
`is_hot_module_replacement_enabled`,
`any_content_changed_of_output_asset` |

Also cleaned up imports that became unused after the removals.
2026-03-03 12:01:45 +01:00
cfd5d5db0f pr-status: add --wait flag and background execution for /pr-status command (#90687)
## Summary

- Add a `--wait` flag to `scripts/pr-status.js` that writes a partial
report with currently available CI results, then blocks on `gh run
watch` until CI completes, and re-runs the full analysis to produce the
final report
- Refactor `main()` into a reusable `runAnalysis()` function so it can
be called twice (partial + final)
- Update the `/pr-status` command to run the script with `--wait` in the
background, present the partial report immediately while CI is still
running, then poll for completion with 5-minute timeouts

### How it works

1. `/pr-status` launches `node scripts/pr-status.js --wait` in the
background (1-minute Bash timeout)
2. The script writes the initial report (with whatever jobs have
completed so far) and prints `Output written to ...`
3. The command polls for that message using `TaskOutput` with 20-second
timeouts, then reads `index.md` and analyzes the partial results
4. Meanwhile, the script blocks on `gh run watch` until CI finishes,
then re-runs the full analysis
5. After presenting the partial analysis, the command polls for the
background script to complete using `TaskOutput` with 5-minute timeouts
(repeating if needed)
6. When it finishes, the command re-reads the final report and analyzes
any newly failed jobs

### Files changed

- `scripts/pr-status.js` — Extracted `runAnalysis()` from `main()`,
added `--wait` flag with `gh run watch` blocking and re-analysis
- `.claude/commands/pr-status.md` — Updated workflow to use `--wait`
with background execution, poll for readiness (20s timeouts), and poll
for final results (5-min timeouts)

## Test plan

- [ ] Run `node scripts/pr-status.js <completed-pr-number>` (no
`--wait`) — should behave identically to before
- [ ] Run `node scripts/pr-status.js <completed-pr-number> --wait` —
should produce report and exit immediately (no waiting needed since CI
is done)
- [ ] Run `node scripts/pr-status.js --wait` on a branch with
in-progress CI — should write partial report, block on `gh run watch`,
then write final report
- [ ] Run `/pr-status` command — should show partial results, then
update with final results after CI completes

---------

Co-authored-by: Claude <[email protected]>
2026-03-03 10:41:41 +01:00
Tobias KoppersandGitHub b7c11377b1 pr-status: add reply-thread and resolve-thread subcommands (#90773)
### What?

Adds two new subcommands to `scripts/pr-status.js`:
- `reply-thread <threadNodeId> <body>` — posts a reply to a PR review
thread
- `resolve-thread <threadNodeId>` — marks a review thread as resolved

Each generated `thread-N.md` file now includes a `## Commands` section
at the bottom with ready-to-use commands pre-populated with the correct
GraphQL node IDs. The resolve command is only shown for threads that are
still open.

Also updates the pr-status-triage skill to remind agents to reply to
review threads with a description of actions taken before resolving
them.

### Why?

When an agent addresses review feedback, it should close the loop by
replying to the thread (describing what was done) and resolving it.
Previously there was no way to do this from the pr-status workflow — the
agent would need to manually construct `gh api graphql` calls.

### How?

- Fetches GraphQL node IDs for review threads (added `id` to the
thread-level query)
- Uses `execFileSync` with argument arrays (not shell strings) to safely
pass the reply body to `gh api graphql` without shell escaping issues
- GraphQL mutations used: `addPullRequestReviewThreadReply` and
`resolveReviewThread`
- Subcommand dispatch at the top of `main()` checks `process.argv[2]`
against known subcommand names before falling through to the existing
PR-number behavior
2026-03-03 08:58:31 +01:00
Tobias KoppersandGitHub 207538313b Fix ENOBUFS errors in pr-status.js when fetching large CI logs (#90654)
## Summary

Fixes `spawnSync /bin/sh ENOBUFS` errors in `scripts/pr-status.js` when
fetching large CI job logs.

The script uses `execSync` (which internally uses `spawnSync`) to fetch
CI job logs via `gh api .../jobs/{id}/logs`. `execSync` has a hard
`maxBuffer` limit (set to 50MB), and when CI job logs exceed that size,
Node.js throws an `ENOBUFS` error. This causes the flaky test detection
to silently fail, reporting 0 flaky tests.

**Before:**
```
Fetching logs for 37 failed jobs...
[stderr] Command failed: gh api "repos/vercel/next.js/actions/jobs/65135029618/logs"
spawnSync /bin/sh ENOBUFS
[stderr] Command failed: gh api "repos/vercel/next.js/actions/jobs/65135029722/logs"
spawnSync /bin/sh ENOBUFS
Found 0 flaky tests (failing on 2+ different branches)
```

**After:**
```
Fetching logs for 18 failed jobs...
Found 0 flaky tests (failing on 2+ different branches)
```

## Changes

- Added an `execAsync()` helper that uses `child_process.spawn` instead
of `execSync`. `spawn` streams data through pipes with no built-in
buffer limit, avoiding `ENOBUFS` entirely.
- Updated `getJobLogs()` and the log-fetching loop in `getFlakyTests()`
to use `execAsync` instead of `exec`.
- All other API calls (small JSON responses) continue using the
synchronous `exec()` helper since they are well within the 50MB limit.

## Test Plan

Ran `node scripts/pr-status.js 90617` against a PR with multiple failed
jobs — completes successfully with no ENOBUFS errors.
2026-03-02 08:56:51 +01:00
Sebastian "Sebbie" SilbermannandGitHub 9c31bbdaa9 [ci] Use commit instead of PR number for preview builds in deploy tests (#90722) 2026-03-01 12:59:37 +01:00
Sebastian "Sebbie" SilbermannandGitHub 61fa3c6317 [sync-react] Allow syncing from a React commit (#90283) 2026-02-25 08:49:03 +00:00
Sebastian "Sebbie" SilbermannandGitHub 632725b0ad [sync-react] Allow syncing React with local build (#90277) 2026-02-21 04:06:34 +00:00
Tobias KoppersandGitHub 9a7733ed83 Automatically build and clear native build when running pnpm build (#89819)
## What?

Adds a `maybe-build-native.mjs` script to `packages/next-swc/` that conditionally rebuilds native SWC bindings during `pnpm build`. The script is integrated into the turborepo pipeline as the `build` task for `@next/swc`.

## Why?

Developers often forget to run `pnpm swc-build-native` after pulling Rust changes, leading to confusing runtime errors. Conversely, rebuilding native binaries when nothing changed wastes significant time. This automates the decision so `pnpm build` always does the right thing.

## How?

The `maybe-build-native.mjs` script runs as `@next/swc`'s `build` task and:

1. **Skips in CI** — exits immediately when the `CI` env var is set, since CI uses prebuilt `@next/swc-*` npm packages
2. **Finds the last version bump** — uses `git log -G` to locate the commit that last changed `"version":` in `packages/next/package.json`
3. **Checks for Rust changes** — compares `*.rs` files against the working tree (committed + staged + unstaged) since that version bump commit
4. **Rebuilds if needed** — runs `build-native` and copies/formats the generated TypeScript definitions
5. **Clears stale binaries** — if no Rust changes are detected, removes any leftover `.node` files from `native/` so the prebuilt npm packages are used instead

Turborepo's `turbo.json` is configured with Rust-specific inputs (`crates/`, `Cargo.*`, `rust-toolchain`) and `CI` in `env` so CI and local builds get separate cache keys.

### Files changed
- `packages/next-swc/maybe-build-native.mjs` — new script with the conditional build logic
- `packages/next-swc/package.json` — added `"build": "node maybe-build-native.mjs"`
- `packages/next-swc/turbo.json` — added `build` task with Rust inputs, `CI` env, and `native/*.node` outputs
2026-02-19 13:24:33 +01:00
a7c61c10ad [turbopack] Run the deployment tests for turbopack and webpack (#84360)
Fork the set of deployment tests so they run with both turbopack and
webpack. Now that turbopack is the default bundler we need this
coverage.

Because we are now running twice as many tests, decrease concurrency,
otherwise we hit rate limits on vercel. There were attempts to improve
rate limit recovery in the vercel CLI
(https://github.com/vercel/vercel/pull/14443 and
https://github.com/vercel/vercel/pull/14407) which helped but did not
solve the issue. Also there was an investigation into the API service
where we discovered some suspicious but ultimately correct code
(https://github.com/vercel/api/pull/55967).

The basic issue is that the vercel CLI polls `api-deployments-get`
fairly aggressively at the beginning of a deploymnet, and since we start
so many deployments in parallel we will always hit the rate limits. The
recovery logic in the CLI is good but has (reasonably) a fixed set of
retries it will attempt, inevitably some tasks get unlucky. So retrying
the test does work, but really we should slow down which is what we do
here. 😥


https://github.com/vercel/next.js/actions/runs/20290161194/job/58272593085

Fixes PACK-5613

---------

Co-authored-by: JJ Kasper <[email protected]>
2026-02-17 11:52:10 -08:00
a04d598f3c docs: agent skills, pr-status script, and AGENTS.md updates (1/8) (#89857)
## Summary

- **Agent skills**: 9 new skill files in `.agents/skills/` covering DCE,
flags, react-vendoring, runtime-debug, PR triage, and skill authoring
- **PR status tooling**: `scripts/pr-status.js` script and
`.claude/commands/pr-status.md` command
- **AGENTS.md**: updated with skill references and development
guidelines

## Test plan

- [ ] No runtime behavior changes
- [ ] Docs and tooling only

---------

Co-authored-by: Tim Neutkens <[email protected]>
2026-02-16 18:32:27 +01:00
JJ KasperandGitHub 5101d0499e Fix devlow job timeouts (#89804)
Attempting to fix the devlow job timeouts that have been happening on
canary for a bit

x-ref:
https://github.com/vercel/next.js/actions/runs/21889767463/job/63192963474
2026-02-10 22:15:44 -08:00
JJ KasperandGitHub a0b5d9ad8b Fix reset-project script for E2E deploy tests (#89693)
Our reset script was failing from invalid body shape: 

```sh
Error: Create project failed. Got status: 400, {"error":{"code":"bad_request","message":"Invalid request: should NOT have additional property `env`."}}
```

x-ref:
https://github.com/vercel/next.js/actions/runs/21793009770/job/62875798461
x-ref:
https://github.com/vercel/next.js/actions/runs/21807482052/attempts/1
2026-02-09 09:28:05 +01:00
JJ KasperandGitHub 1bf6c2f4b1 Fix flaky turbo cache pull with retries and graceful fallback (#89575)
- Add retry logic (3 attempts with 5s delay) for transient network
failures
- Don't fail the job when cache restoration fails - let workflow build
from source
- Add error handling for dry run failures and JSON parsing

This attempts to address transient failures seen here
https://github.com/vercel/next.js/actions/runs/21735816168/job/62700523424?pr=89574
2026-02-06 15:06:40 +00:00
JJ KasperandGitHub 0d15dd58bb Add separate E2E deploy env for turbopack tests (#89458)
x-ref: [slack
thread](https://vercel.slack.com/archives/C04KC8A53T7/p1770151130656569?thread_ts=1770107873.440639&cid=C04KC8A53T7)
2026-02-03 21:13:12 +00:00
Niklas MischkulnigandGitHub 345a36c96f Don't upload build cache for deployment tests (#89432)
We use `vc deploy -f`, so the build cache is never read anyway.
2026-02-03 12:43:10 -08:00
Benjamin WoodruffandGitHub a4c1a0cd72 Turbopack: Rename crates/napi to crates/next-napi-bindings and update crate name (#89314)
Disclaimer: This PR is entirely claude+opencode generated.

- Crate name said `next-swc-napi`, which was confusing, because this has a lot more than swc bindings nowdays.
- The crate name didn't match the directory name, which often confused agents.

This does not change the npm package name, as that would likely have a much larger blast radius, and could break more things, to a point where it may not be worth it.
2026-01-30 15:36:57 -08:00
JJ KasperandGitHub 1104c45f25 Add full adapters E2E tests to workflow (#89125)
This updates to run the entire E2E deploy tests same as we do currently
but with adapters enabled to catch regressions there. These run on a
separate test team to isolate from existing test team and avoid rate
limits.

Test run of the workflow done here
https://github.com/vercel/next.js/actions/runs/21418745794
2026-01-28 14:16:20 -08:00
Tobias KoppersandGitHub fcd3416ce6 Improve /pr-status: comments, argument, avoid full log (#89092)
* add general comments
* remove full log to avoid the agent accessing it
* add PR number argument
2026-01-27 11:41:22 +01:00
Tobias KoppersandGitHub aa6086d011 /pr-status (former /ci-failures): fetch PR reviews too (#89082)
### What?

* allow to pass PR number
* fetch PR reviews
* Rename to /pr-status update agent instructions
2026-01-27 10:21:26 +01:00
JJ KasperandGitHub d224a56201 Fix reset deploy project script (#89001)
This script has been quietly failing on cron occasionally, this updates
to ensure it shows as failing when the inner requests fail and also adds
back-off logic for re-creating the project after deleting the previous.

x-ref:
https://github.com/vercel/next.js/actions/runs/21327384008/job/61386921911#step:6:12
2026-01-26 15:18:41 -08:00
Tobias KoppersandGitHub 1a2eccf30e Improve performance and token usage of /ci-failures command (#88960)
Improve performance and token usage of `/ci-failures` command

include type in failure table, provide more instructions

use subagents

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the PR.
- Read the Docs Contribution Guide to ensure your contribution follows the docs guidelines: https://nextjs.org/docs/community/contribution-guide

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See: https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. (A discussion must be opened, see https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added (https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to understand the PR)
- When linking to a Slack thread, you might want to share details of the conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2026-01-23 22:37:19 +01:00
Hendrik LiebauandGitHub 239471c83d [ci] Exclude test/production from deploy tests (#88763) 2026-01-19 20:53:06 +01:00
Sebastian "Sebbie" SilbermannandGitHub 0fd7d90d63 [scripts] Avoid conflicting type for pack-next --compress (#88439)
`type: 'string'` conflicts with `choices: T[]`. It's basically `string |
T` which just collapses to `string` if `T` is a union of string
literals.

Before:
```console
$ p pack-next --help
...
 --compress ... [string] [choices: "none", "strip"]
```

After: 
```console
$ p pack-next --help
...
 --compress ... [choices: "none", "strip"]
2026-01-12 20:18:40 +00:00
Hendrik LiebauandGitHub 7a2f4ad140 Type-check run-tests.js and remove unused related flag (#88433)
The file already had the `@ts-check` directive, so the IDE did show errors in that file. But since it was not included in the root `tsconfig.json`, those errors were not reported during CI runs.

One issue found this way was that the `related` flag was defined but never used. The referenced script was removed in #67644.
2026-01-12 19:46:11 +01:00
Niklas MischkulnigandGitHub 10213b360b Fix pack-next script for next-swc (#88126) 2026-01-09 09:43:53 +01:00
Jimmy LaiandGitHub 4cd3ca26d7 perf: improve stats action reliability and reduce CI noise (#87945)
## Summary

Comprehensive improvements to the PR stats action for more reliable benchmarks and reduced CI noise.

### Vercel KV Integration
- Add `@vercel/kv` for historical data persistence
- Track metrics over time with `loadHistory()` / `saveToHistory()`
- Display trend sparklines in comments when history is available

### Comment Generation Refactor
- New `METRIC_LABELS` and `METRIC_GROUPS` configuration system
- Organized metrics by category (Dev Server, Production Builds, Production Runtime)
- Better formatting utilities (`prettifyTime`, `formatChange`, `generateTrendBar`)
- Bundle group totals for KV persistence

### Noise Reduction
- Significance thresholds: `50ms AND 10%` for time, `1KB AND 1%` for size
- Additional `<2%` filter for long-running operations (builds)
- Filters typical CI variance while catching real regressions

### Stats Config Updates
- Add `measureDevBoot: true` to enable dev boot benchmarks
- Fix `appDevCommand` to include `dev` subcommand
- Add `--webpack` flag to `appBuildCommand`
- Rename "Client Bundles (main, webpack)" to "Client Bundles (main)"
- Add `turbopack: {}` to test configs

### GitHub Actions Updates
- New `action.yml` with bundler input parameter
- Workflow improvements in `pull_request_stats.yml`

### New Files
- `scripts/test-stats-benchmark.sh` - Local testing script
- `.github/actions/next-stats-action/src/util/stats.js` - Shared stats utilities
- `.github/actions/next-stats-action/test-local.js` - Local comment testing

## Test Plan
```bash
cd .github/actions/next-stats-action
node test-local.js              # Basic test
node test-local.js --with-history  # Test with trend sparklines
```
2026-01-06 12:36:41 +01:00
Jimmy LaiandGitHub a39366938a chore: add dev boot profiling and benchmark scripts (#87940)
## Summary

Development scripts for profiling and benchmarking Next.js dev server boot time.

### Benchmarking Scripts
- `benchmark-boot-time.sh` - Wall-clock benchmarking with two metrics:
  - **Listen time**: When TCP port accepts connections
  - **Ready time**: When first HTTP request succeeds
- `benchmark-next-dev-boot.js` - Multi-iteration benchmarking with statistics (median, p95, stddev)

### Profiling Scripts
- `profile-next-dev-boot.js` - CPU profiling infrastructure using V8 inspector
- `analyze-profile.js` - Analyze CPU profiles to identify hot modules by CPU time

### Analysis Scripts
- `analyze-dev-server-bundle.js` - Bundle analyzer for dev server (generates treemap report)
- `trace-cli-startup.js` - Module loading trace to identify slow imports

## Usage

```bash
# Benchmark dev server boot time (5 runs by default)
./scripts/benchmark-boot-time.sh

# Multi-iteration benchmark with stats
node scripts/benchmark-next-dev-boot.js --iterations 10

# Generate CPU profile
node scripts/profile-next-dev-boot.js

# Analyze profile output
node scripts/analyze-profile.js .next/cpu-profiles/*.cpuprofile

# Analyze dev server bundle
node scripts/analyze-dev-server-bundle.js --open
```

## Test Plan
- [x] Run `./scripts/benchmark-boot-time.sh` locally
- [x] Verify scripts execute without errors
2026-01-06 12:18:01 +01:00
Sebastian "Sebbie" SilbermannandGitHub 0812317fb9 [ci] Stop running explicit build when creating release (#87212) 2025-12-16 10:46:28 +01:00