From 8ba10b3e8136f978a7eca7cc67fc350955d49e92 Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 26 Oct 2026 23:43:14 +0900 Subject: [PATCH] Develop and test with Node.js 26 The Temporal bindings (#9044) need the `Temporal` global, which Node.js 22 lacks and Node.js 26 provides, so their tests and doc examples can run in CI only on Node.js 26. `.nvmrc` now names 26. The build, coverage and publish jobs read it through the setup-node action and pkg-pr-new reads it directly; the changelog check now reads it too instead of naming 22. The dev container and CONTRIBUTING.md move to 26 as well. The installation tests keep Node.js 22, the oldest version the packages support (`engines` `>=22`). build-compiler no longer runs the stdlib tests on 22, so both installation jobs now run them there. They copy the compiled tests in `tests/tests/src/stdlib` next to the installed packages, install `@babel/code-frame`, which `Test.mjs` imports, at the version `tests/tests` declares, and run `Stdlib_TestSuite.mjs` and `Stdlib_TempTests.mjs` against the runtime from pkg.pr.new. Node.js 25 stopped bundling corepack. The dev container's Node feature enables corepack where Node.js bundles it and installs yarn with npm otherwise, so `postCreate.sh` no longer runs `corepack enable`, which would fail on 26. Review: Do any tests behave differently on 26? The runtime doc examples for `RegExp.escape` and `DataView.getFloat16`/`setFloat16`, which `DocTest.res` skips below Node.js 24, now run in CI. They pass on 26.12.1, as does the rest of `make test`. Review: Do the copied stdlib tests need anything else from the repository? No. Apart from `@babel/code-frame` they import only each other, `./Test.mjs`, `@rescript/runtime/lib/es6` and Node.js built-ins. `Test.mjs` reads the `.res` source next to it only to print a failure, and the copy includes the sources. Review: Where do tests of APIs that Node.js 22 lacks go? Not into `Stdlib_TestSuite` or `Stdlib_TempTests`, which now also run on 22. Comments on the workflow step and in `Stdlib_TestSuite.res` say so. The Temporal tests will need an entry point that only `scripts/test.js` runs. Review: Does the new step work on Windows? It copies with the same Git Bash `cp` as the existing `installation_test` copy, and the tests find the runtime through `node_modules`. `Test.mjs` takes its directory from the pathname of `import.meta.url`, which starts with `/C:/` on Windows, so a failing assertion there reports a missing `.res` file instead of a code frame. The step still fails, just as the stdlib tests in the Windows build-compiler job do today. Review: Does anything else rely on corepack? No. Only `postCreate.sh` ran it; the workflows never do. Signed-off-by: mununki --- .devcontainer/devcontainer.json | 2 +- .devcontainer/postCreate.sh | 3 +- .github/workflows/changelog.yml | 2 +- .github/workflows/ci.yml | 34 +++++++++++++++++++-- .nvmrc | 2 +- CONTRIBUTING.md | 2 +- changes/node-26-dev.internal.md | 1 + tests/tests/src/stdlib/Stdlib_TestSuite.res | 4 +++ 8 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 changes/node-26-dev.internal.md diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b7af5fb8533..8132a68eacd 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,7 +14,7 @@ "version": "latest" }, "ghcr.io/devcontainers/features/node:1": { - "version": "22", + "version": "26", "installYarnUsingApt": false } }, diff --git a/.devcontainer/postCreate.sh b/.devcontainer/postCreate.sh index 7ac369d71fc..e19e78154fe 100755 --- a/.devcontainer/postCreate.sh +++ b/.devcontainer/postCreate.sh @@ -3,5 +3,6 @@ # Install dev dependencies from OPAM opam install . --with-test --with-dev-setup -y -corepack enable +# The Node feature provides yarn: it enables corepack where Node still bundles +# it (Node 24 and older) and installs yarn with npm otherwise. printf "\n" | yarn diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 3795eee28fa..23f4b9c35be 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/setup-node@v7 with: cache: yarn - node-version: 22 + node-version-file: .nvmrc # The scripts import semver. Package builds aren't needed for them. - run: yarn install --immutable --mode=skip-build - run: node --test scripts/changelog.test.js scripts/magicNumbers.test.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ed0c281ef0..75cac6dedc7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -587,6 +587,10 @@ jobs: fi echo "path=$dir" >> "$GITHUB_OUTPUT" cp -r tests/package_tests/installation_test/* "$dir" + # The compiled stdlib tests run against the installed runtime. Their + # Test.mjs imports @babel/code-frame, which tests/tests depends on. + cp -r tests/tests/src/stdlib "$dir/stdlib" + echo "code-frame=$(node -p 'require("./tests/tests/package.json").dependencies["@babel/code-frame"]')" >> "$GITHUB_OUTPUT" - name: Install ReScript package run: | @@ -594,7 +598,8 @@ jobs: npm i --no-audit \ "https://pkg.pr.new/rescript-lang/rescript@${COMMIT_SHA}" \ "https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@${COMMIT_SHA}" \ - "https://pkg.pr.new/rescript-lang/rescript/@rescript/belt@${COMMIT_SHA}" + "https://pkg.pr.new/rescript-lang/rescript/@rescript/belt@${COMMIT_SHA}" \ + "@babel/code-frame@${{ steps.tmp-dir.outputs.code-frame }}" shell: bash working-directory: ${{ steps.tmp-dir.outputs.path }} @@ -618,6 +623,16 @@ jobs: shell: bash working-directory: ${{ steps.tmp-dir.outputs.path }} + # build-compiler runs the stdlib tests on the Node.js version in .nvmrc, + # this job on the oldest supported one, so tests of APIs missing there + # must stay out of Stdlib_TestSuite and Stdlib_TempTests. + - name: Run stdlib tests + run: | + node stdlib/Stdlib_TestSuite.mjs + node stdlib/Stdlib_TempTests.mjs + shell: bash + working-directory: ${{ steps.tmp-dir.outputs.path }} + test-installation-pnpm: needs: - pkg-pr-new @@ -657,6 +672,10 @@ jobs: fi echo "path=$dir" >> "$GITHUB_OUTPUT" cp -r tests/package_tests/installation_test/* "$dir" + # The compiled stdlib tests run against the installed runtime. Their + # Test.mjs imports @babel/code-frame, which tests/tests depends on. + cp -r tests/tests/src/stdlib "$dir/stdlib" + echo "code-frame=$(node -p 'require("./tests/tests/package.json").dependencies["@babel/code-frame"]')" >> "$GITHUB_OUTPUT" - name: Install ReScript package run: | @@ -665,7 +684,8 @@ jobs: pnpm --config.block-exotic-subdeps=false i \ "https://pkg.pr.new/rescript-lang/rescript@${COMMIT_SHA}" \ "https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@${COMMIT_SHA}" \ - "https://pkg.pr.new/rescript-lang/rescript/@rescript/belt@${COMMIT_SHA}" + "https://pkg.pr.new/rescript-lang/rescript/@rescript/belt@${COMMIT_SHA}" \ + "@babel/code-frame@${{ steps.tmp-dir.outputs.code-frame }}" shell: bash working-directory: ${{ steps.tmp-dir.outputs.path }} @@ -684,6 +704,16 @@ jobs: shell: bash working-directory: ${{ steps.tmp-dir.outputs.path }} + # build-compiler runs the stdlib tests on the Node.js version in .nvmrc, + # this job on the oldest supported one, so tests of APIs missing there + # must stay out of Stdlib_TestSuite and Stdlib_TempTests. + - name: Run stdlib tests + run: | + node stdlib/Stdlib_TestSuite.mjs + node stdlib/Stdlib_TempTests.mjs + shell: bash + working-directory: ${{ steps.tmp-dir.outputs.path }} + # The single CI check that the master ruleset requires. Matrix job names # contain runner labels, so requiring this job instead keeps the ruleset # unchanged when runners or jobs change. It runs even when a needed job fails diff --git a/.nvmrc b/.nvmrc index 2bd5a0a98a3..6f4247a6255 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22 +26 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f23e285e03..a9d8eaf89a1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,7 +32,7 @@ algorithm and representation invariants belong beside their implementation. > Most of our contributors are working on Apple machines, so all our instructions are currently macOS / Linux centric. Contributions for Windows development welcome! -- [Node.js](https://nodejs.org/) v22.x or newer +- [Node.js](https://nodejs.org/) v26.x or newer (the version in `.nvmrc`) - [Yarn CLI](https://yarnpkg.com/getting-started/install) (can be installed with `corepack`, Homebrew, etc) - C compiler toolchain (usually installed with `xcode` on Mac) - Rust toolchain (required to build rewatch; follow the instructions at https://www.rust-lang.org/tools/install and install the version listed as `rust-version` in `rewatch/Cargo.toml`) diff --git a/changes/node-26-dev.internal.md b/changes/node-26-dev.internal.md new file mode 100644 index 00000000000..59aca83c9b5 --- /dev/null +++ b/changes/node-26-dev.internal.md @@ -0,0 +1 @@ +- Develop and test with Node.js 26, and run the stdlib tests in the installation tests on Node.js 22, the oldest supported version. diff --git a/tests/tests/src/stdlib/Stdlib_TestSuite.res b/tests/tests/src/stdlib/Stdlib_TestSuite.res index e39543615aa..ae074330a4b 100644 --- a/tests/tests/src/stdlib/Stdlib_TestSuite.res +++ b/tests/tests/src/stdlib/Stdlib_TestSuite.res @@ -1,3 +1,7 @@ +// The installation tests in .github/workflows/ci.yml also run this suite on +// the oldest supported Node.js version, 22. Tests of APIs that Node.js 22 +// lacks belong in a separate entry point that only scripts/test.js runs. + include Stdlib_TestTests include Stdlib_PromiseTest include Stdlib_ErrorTests