build: add support for Node v24 (new default) & v26 - #1507
Conversation
|
|
There was a problem hiding this comment.
Pull request overview
Updates the repository’s CI/release workflows to exercise newer Node.js versions and make Node 24 the default runtime used by the shared setup-node composite action.
Changes:
- Bump the default Node version in the shared
./.github/actions/setup-nodecomposite action from 22 → 24. - Update CI matrices to run TypeScript bindings tests and Hardhat tests on Node 24 (previously Node 20).
- Expand
edr-npm-release.ymlbinding-test matrices to cover Node 20/22/24/26 and bump release build/publish steps and Docker images to Node 24.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| .github/workflows/hardhat-tests.yml | Switch Hardhat test matrix from Node 20 to Node 24. |
| .github/workflows/edr-npm-release.yml | Bump release build/publish Node versions to 24 and expand binding test matrices to include 24 and 26. |
| .github/workflows/edr-ci.yml | Switch TS bindings test matrix from Node 20 to Node 24. |
| .github/actions/setup-node/action.yml | Update default Node version used by the composite action from 22 to 24. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1507 +/- ##
=======================================
Coverage 79.41% 79.41%
=======================================
Files 446 446
Lines 76644 76644
Branches 76644 76644
=======================================
+ Hits 60864 60865 +1
+ Misses 13653 13652 -1
Partials 2127 2127 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Mocha 10 predates Node 22.18+/24/26 native TypeScript type-stripping, which intercepts .ts files (reparsing them as ESM) instead of letting ts-node handle them via its require hook. This bypasses ts-node's config/type-checking and breaks on Node 26. Mirror Hardhat 2's migration: - bump mocha ^10 -> ^11.1.0 in hardhat-tests and edr_napi (kept in sync for syncpack parity) - convert .mocharc.json -> .mocharc.cjs so node-option can be computed per Node version via the shared config/mocha.cjs helper: no-strip-types (>=24.12), no-experimental-strip-types (22.18-24.11 / 23.6+), or empty (older) - edr_napi: switch test scripts from bin/_mocha to the mocha wrapper (which honors node-option; _mocha does not) and fold --max-old-space-size=8192 into node-option
…se onto #1507 Rebasing onto #1507 (Node 24/26 support on top of current main) re-resolved Cargo.lock. Pin the napi v3 stack to the newest versions that clear the 7-day cooldown check: napi 3.9.2, napi-derive 3.5.6, napi-derive-backend 5.0.4 (napi-sys 3.2.2 already clears it). The newest published versions (napi 3.9.4 / napi-derive 3.5.7 / napi-derive-backend 5.0.5) are still inside the cooldown window.
Re-resolve against the merged package.json (version 0.13.0, @napi-rs/cli ^3.7.0) on top of #1507's Mocha v11 tree. Resolves @napi-rs/cli 3.7.2 and its build-time tooling; all newly pulled napi/emnapi packages were published before the 7-day cooldown threshold.
Regenerated via `pnpm build:typingFile` (--features op) with @napi-rs/cli 3.7.2. Updates the native-binding version checks from 0.12.1 to 0.13.0 to match the version inherited from current main; index.d.ts is unchanged.
01d9372 to
4bb398b
Compare
The release-review job ran `pnpm publish --dry-run` to check each package is publishable. Under npm >= 11 (now reached via the Node 22 -> 24 bump in this workflow), `publish --dry-run` does a registry pre-flight and errors with EPUBLISHCONFLICT when the current version already exists on npm -- so it fails on every PR during the post-release gap, before the next version bump lands. Node 22's npm 10 never contacted the registry on --dry-run, which is why this was latent until now. We want to validate that the package builds into a valid publishable tarball, not whether that version is already on the registry. `pnpm pack` does exactly that: same workspace-protocol translation as publish, fully offline, no version-conflict check.
Squashed investigation tooling, re-based onto migrate-to-napi-v3 after the Node 24/26 work merged to main (#1507). Adds two push-triggered, non-merge arm64 rigs (see /workspace/edr-napi-tsfn-teardown-race-followup.md): - .github/workflows/tsfn-teardown-repro.yml — EDR repro (musl+gnu matrix): builds the binding with debug symbols, loops testNoBuild for a crash rate, full crash log + gdb backtrace (glibc leg lets V8 symbolize its stack). - .github/workflows/tsfn-min-repro.yml + tsfn-min-repro/ — standalone bare napi-rs v3 weak-TSFN addon ({musl,gnu} x {24,26}). Result: 0/500 on all legs -> the bug is NOT a bare weak TSFN; it's EDR-specific (likely a #[napi]-class ObjectWrap Reference / called TSFN / tokio runtime). Root cause class: nodejs/node#52418 GlobalHandles teardown double-free (node->IsInUse), unfixed across Node 22/24/26; not #55706.
Node 20 reached end-of-life, and #1507 added 24 (new default) and 26 alongside it without removing 20. Drop it as both a supported runtime and a compile target; the supported set is now 22, 24, 26 with a floor of 22. Runtime: - edr-npm-release.yml: remove "20" from the five binding-test matrices - package.json: engines.node ">=20" -> ">=22" - crates/edr_napi + its seven npm/* platform packages: engines.node ">= 20" -> ">= 22" (the published contract) - .nvmrc: 20 -> 24 to match the default toolchain Compile baseline (track the minimum supported runtime, 22, not the default 24, so the TS never assumes APIs missing on Node 22): - @tsconfig/node20 -> @tsconfig/node22 in the three tsconfig extends and their package.json devDeps - @types/node ^20 -> ^22 across edr_napi, hardhat-tests, and the three js/* packages - pnpm-lock.yaml: regenerated (only @types/node 20.19.43 -> 22.7.5 and @tsconfig/node20 -> @tsconfig/node22 22.0.5; no other resolutions moved) All five TS packages typecheck clean against the new types.
Node 20 reached end-of-life, and #1507 added 24 (new default) and 26 alongside it without removing 20. Drop it as both a supported runtime and a compile target; the supported set is now 22, 24, 26 with a floor of 22. Runtime: - edr-npm-release.yml: remove "20" from the five binding-test matrices - package.json: engines.node ">=20" -> ">=22" - crates/edr_napi + its seven npm/* platform packages: engines.node ">= 20" -> ">= 22" (the published contract) - .nvmrc: 20 -> 24 to match the default toolchain Compile target: - @types/node ^20 -> ^22 across edr_napi, hardhat-tests, and the three js/* packages, so the TS is typed against the minimum supported Node (22) rather than an EOL one - pnpm-lock.yaml regenerated (only @types/node 20.19.43 -> 22.7.5 moved) @tsconfig/node20 (es2023 lib) is intentionally kept: @tsconfig/node22 raises the lib to es2024, which the pinned @typescript-eslint 5.62.0 parser rejects. Bumping that parser removes rules the shared eslint config still uses (ban-types, no-empty-interface, no-duplicate-imports), so the es2024 lib bump is deferred to a dedicated lint-toolchain PR. All packages typecheck and lint clean against the new @types/node.
Squashed investigation tooling, re-based onto migrate-to-napi-v3 after the Node 24/26 work merged to main (#1507). Adds two push-triggered, non-merge arm64 rigs (see /workspace/edr-napi-tsfn-teardown-race-followup.md): - .github/workflows/tsfn-teardown-repro.yml — EDR repro (musl+gnu matrix): builds the binding with debug symbols, loops testNoBuild for a crash rate, full crash log + gdb backtrace (glibc leg lets V8 symbolize its stack). - .github/workflows/tsfn-min-repro.yml + tsfn-min-repro/ — standalone bare napi-rs v3 weak-TSFN addon ({musl,gnu} x {24,26}). Result: 0/500 on all legs -> the bug is NOT a bare weak TSFN; it's EDR-specific (likely a #[napi]-class ObjectWrap Reference / called TSFN / tokio runtime). Root cause class: nodejs/node#52418 GlobalHandles teardown double-free (node->IsInUse), unfixed across Node 22/24/26; not #55706.
pnpm publish --dry-runtopnpm packas pnpm 11 + Node 24 now actually checks presence of the version in the registry.Multi-version binding tests (
edr-npm-release.yml)Added Node 24 and 26 to all five binding-test matrices, which now cover Node 20, 22, 24, and 26.
New default: Node 24
Bumped the
setup-nodecomposite action default from22to24, so all callers that don't pin a version now use Node 24.Bumped pinned Node 20 and 22 → 24
edr-npm-release.yml: release build job name (node@20→node@24), Docker base images (node:20-bullseye-slim→node:24-bullseye-slim,node:20-alpine3.20→node:24-alpine3.20), the non-Docker build step, and both publish-stagesetup-nodesteps (22→24).edr-ci.yml: TS bindings test matrix (node: [20]→node: [24]).hardhat-tests.yml: Hardhat test matrix (node: [20]→node: [24]).Notes
node:24/node:26Docker tags were confirmed to exist.