## Summary
Fixes flaky jscodeshift codemod tests on Windows CI (e.g.,
`next-async-request-api-dynamic-apis.test.js`,
`built-in-next-font.test.js`, `new-link.test.js`).
### Problem
Windows CI runners have `core.autocrlf=true` by default, which causes
test failures because:
1. Fixture files get checked out with CRLF line endings
2. jscodeshift's printer (recast) outputs CRLF on Windows
3. String comparison fails between expected and actual output
### Solution
Patches jscodeshift's test utilities in `jest-setup-after-env.ts`
(Windows only) to normalize line endings:
```typescript
const normalizeLF = (str: string) =>
str
.replace(/\r\n/g, '\n') // CRLF → LF
.replace(/[ \t]+$/gm, '') // Remove trailing whitespace per line
.replace(/\n*$/, '\n') // Ensure exactly one trailing newline
```
**Key changes:**
- **Patches `runInlineTest`** - Normalizes input, runs transform,
normalizes output, then compares
- **Patches `defineTest`** - Reads fixtures with normalization, uses
patched `runInlineTest`
- **Handles closure issue** - jscodeshift's internal functions use
closures that bypass exports, so we replace the functions entirely
Also includes a belt-and-suspenders `sed` command in the workflow to
strip CRLF from source files.
### Why not just fix `.gitattributes`?
The `.gitattributes` `eol=lf` setting helps, but doesn't solve the
problem because:
1. jscodeshift's recast printer uses platform-native line endings when
generating output
2. Fixture files may have inconsistent trailing whitespace/newlines
3. Self-hosted Windows runners may have different git configurations
### Follow-up
**TODO:** Configure Windows self-hosted runners with `git config
--system core.autocrlf false` so the `sed` workaround can be removed.
See the `TODO` comment in `build_reusable.yml`.
## Test Plan
- Windows CI unit tests should pass consistently
- Normalization only runs on Windows (`process.platform === 'win32'`)
- Other platforms unaffected
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Adds a merge driver that can automatically re-number messages added to
`errors.json` if a merge conflict occurs. Now, it would be easier to
just run `pnpm update-error-codes`, but that's slow and requires
installing deps + building everything, so i'm just manually merging +
renumbering instead.
To avoid disrupting people's workflows (in case this is buggy, or
something), it's currently *not enabled by default*. To enable the merge
driver, run:
```shell
scripts/merge-errors-json/install
```
which will add it to your `.git/config`. Once it's been confirmed to
work well, we can make this command run by default in `postinstall`.
### Testing
Other than the test i added (which doesn't run git), i've tested this
manually with this script that rebases some stacked branches:
<details>
<summary>merge-driver-test.sh</summary>
```bash
#!/usr/bin/env bash
set -eu -o pipefail
cd "$1"
current_branch="$(git branch --show-current)"
(
set -eu -o pipefail
git switch lubieowoce/errors-json-merge-driver
git switch --force-create 'test/errors-json/base'
echo '{
"1": "base message"
}
' > packages/next/errors.json
git commit -am 'base commit'
git switch --force-create 'test/errors-json/one';
echo '{
"1": "base message",
"2": "message from branch one"
}
' > packages/next/errors.json
git commit -am 'commit 1'
git switch 'test/errors-json/base'
git switch --force-create 'test/errors-json/stacked-1'
echo '{
"1": "base message",
"2": "message from stacked 1"
}
' > packages/next/errors.json
git commit -am 'stacked 1'
git switch --force-create 'test/errors-json/stacked-2'
echo '{
"1": "base message",
"2": "message from stacked 1",
"3": "message from stacked 2"
}
' > packages/next/errors.json
git commit -am 'stacked 2'
git rebase 'test/errors-json/one' --update-refs || true
bat packages/next/errors.json
git rebase --abort || true
)
git switch "$current_branch"
```
</details>
The script does a bunch of git operations, so it's easiest to put it
outside of your next.js repo and call `bash merge-driver-test.sh
path/to/next.js`.
This builds on top of work that @timneutkens did in the
`wbinnssmith/try-ci-test` branch to rebuild the integration test CI on
top of `build_reusable.yml` and work around issues with the
`next-integration-stat`, but takes it a few steps further:
- As much of the integration test logic as possible is moved into a
single re-usable workflow so that we won't need to duplicate logic
between 6 workflows going forward (turbopack dev, turbopack build,
turbopack examples, rspack dev, rspack build, rspack examples). Right
now this just ports turbopack dev and build.
- Cleaned up a ton of legacy dead/broken code in
`next-integration-stat`. We might want to revive the comment-on-PR
functionality, so I didn't completely remove it, just the very obviously
broken parts (e.g. references to a >2-year-old stale branch of the
turborepo repository).
---
Manually triggered the workflows:
Dev tests: https://github.com/vercel/next.js/actions/runs/13466611352
Prod tests: https://github.com/vercel/next.js/actions/runs/13466609857
Tested by patching the `test/build-turbopack-*-tests-manifest.js`
scripts like so:
```diff
diff --git a/test/build-turbopack-dev-tests-manifest.js b/test/build-turbopack-dev-tests-manifest.js
index bc1928cf2d..e6546e0018 100644
--- a/test/build-turbopack-dev-tests-manifest.js
+++ b/test/build-turbopack-dev-tests-manifest.js
@@ -91,7 +91,11 @@ async function fetchLatestTestArtifact() {
const res = JSON.parse(stdout)
for (const artifact of res.artifacts) {
- if (artifact.expired || artifact.workflow_run.head_branch !== 'canary') {
+ if (
+ artifact.expired ||
+ artifact.workflow_run.head_branch !==
+ 'bgw/reusable-integration-test-workflow'
+ ) {
continue
}
```
And then diffing the generated json manifests:
https://gist.github.com/bgw/08778b5f63861811fbe88e3f466a8679
Note that some differences are expected: These jobs have been broken for
at least 2-3 weeks.
Based on the results of this poll: https://vercel.slack.com/archives/C04KC8A53T7/p1734380259031279
> In my experience these fixtures need to be carefully reviewed, same as the code that changed them. Collapsing them by default will make this more difficult and possibly error-prone.
This should let GitHub (and Graphite) collapse these files by default in code review.
```
$ git check-attr --all crates/next-custom-transforms/tests/fixture/strip-page-exports/getInitialProps/class/*
crates/next-custom-transforms/tests/fixture/strip-page-exports/getInitialProps/class/output-data.js: linguist-generated: true
crates/next-custom-transforms/tests/fixture/strip-page-exports/getInitialProps/class/output-default.js: linguist-generated: true
```
x-ref: https://github.com/vercel/next.js/pull/51647
follow up for the code indexing issue for "build/**" folder, previous solution seem not working, trying just "build/**" without prefix