Skip to content

Bump dotnet/node to Node.js v24.7.0#335

Draft
pavelsavara wants to merge 8740 commits intodotnet:dotnet/mainfrom
pavelsavara:dotnet/bump-node-24.7.0
Draft

Bump dotnet/node to Node.js v24.7.0#335
pavelsavara wants to merge 8740 commits intodotnet:dotnet/mainfrom
pavelsavara:dotnet/bump-node-24.7.0

Conversation

@pavelsavara
Copy link
Copy Markdown
Member

@pavelsavara pavelsavara commented Apr 29, 2026

Contributes to dotnet/runtime#113786

Why

Part of the Emscripten 5.0.6 toolchain bump for .NET 11 (tracking doc:
emsdk_plan_5.0.6.md, Step 4).

Emscripten 5.0.6 requires Node >= 18.3.0 (MINIMUM_NODE_VERSION in
tools/shared.py). Upstream emsdk install 5.0.6 ships 22.16.0 as
default and 24.7.0 as the newer offered Node. We standardize the
fork on 24.7.0 so the .NET workload always carries the newer Node.

Previous fork pin: v18.17.1 (LTS "Hydrogen", 2023-08-09).
New fork pin: v24.7.0 (Current, 2025-08-27).

What this PR does

Single merge commit on top of dotnet/main:

*   Merge upstream Node.js v24.7.0 into dotnet/main
|\
| * d795edb5676  v24.7.0  (upstream nodejs/node tag)
* | 665c717cf1a  dotnet/main tip

No squash. The merge keeps full upstream history reachable so future
upstream merges into dotnet/main see a clean ancestry.

Conflict resolution policy

The 6-major-version jump produced ~6044 conflicting files. They were
resolved as follows:

Bucket Files Resolution
Source tree (deps/, lib/, src/, test/, tools/, doc/, benchmark/, typings/, .github/, top-level node files) ~6000 Take upstream v24.7.0. Standard for a major-version bump; the dotnet patches that touched these were almost all upstream-superseded.
eng/, Directory.Build.*, NuGet.config, global.json, node.proj, eng/azure-pipelines*.yml, es-metadata.yml dotnet-only files; no upstream side existed Preserved unchanged from dotnet/main (verified: zero-line diff).
src/node_version.h 1 Manually synced to upstream v24.7.0. The merge base predates v18.17.1 so dotnet's LTS=1/"Hydrogen" metadata otherwise survived as a non-conflicting hunk. Now reads MAJOR=24, MINOR=7, PATCH=0, IS_LTS=0, codename="".

Mechanically: git merge -X theirs v24.7.0, then for each remaining
unmerged-index entry — DU/AA/AU/UAgit checkout --theirs,
UD/DDgit rm. Final unmerged-index count: 0.

dotnet patches NOT re-applied

The following dotnet patches that touched the upstream tree were
intentionally dropped because they are superseded by v24.7.0:

dotnet patches that were kept (none of these collide with v24
upstream content; they live in dotnet-only files):

  • All of eng/ (Arcade infra, V4 publishing, AzDO pipelines, Signing,
    CodeQL config, dependabot, common-variables, build scripts).
  • Directory.Build.props, Directory.Build.targets, node.proj.
  • NuGet.config, global.json, es-metadata.yml, .azuredevops/.
  • azure-pipelines.yml / azure-pipelines-public.yml (live under
    eng/).
  • VersionPrefix=11.0.0 in eng/Versions.props.

Validation expected from CI

The AzDO pipeline (eng/azure-pipelines.yml) should produce
runtime.<rid>.Microsoft.NETCore.Runtime.Wasm.Node.Transport 11.0.0-alpha.1.<yymmdd>.<rev>
for all 8 RIDs (linux-{x64,arm64,musl-x64,musl-arm64}, osx-{x64,arm64},
win-{x64,arm64}). Each transport package must contain a node binary
that reports:

$ node --version
v24.7.0

Maestro then flows the new transport into dotnet/emsdk/main per
emsdk_plan_5.0.6.md Step 7.

Impact on the produced NuGet package

Package version: not bumped (and shouldn't be)

The transport package version is 11.0.0-alpha.1.<yymmdd>.<rev>, computed
from VersionPrefix=11.0.0 in eng/Versions.props plus the Arcade
date+revision stamp. It tracks the .NET workload band, not the Node
version, so a Node 18→24 bump does not change it. Each merge in
main already produces a new build-stamped revision, which is what
Maestro flows downstream — that's the version delta consumers see.

Build-time PackageReferences in node.proj: unchanged

node.proj consumes:

  • runtime.<rid>.Microsoft.NETCore.Runtime.Mono.LLVM.{Tools,Sdk} (Linux only)
  • runtime.<rid>.Microsoft.NETCore.Runtime.Wasm.Python.Transport (osx/win)

These are inputs that build the Node binary, not transitive deps of
the produced package. Their versions live in eng/Versions.props under
runtime…MonoLLVM*Version / runtime…WasmPythonTransportVersion and
are unrelated to this PR. (They will be bumped by separate Maestro
flow PRs once the LLVM dotnet/main-23.x and CPython 3.13.3 packages
are published per emsdk_plan_5.0.6.md Steps 2 and 5.)

Package contents (the file list inside the .nupkg): expected to change

The Microsoft.NETCore.Runtime.Wasm.Node.Transport pkgproj is content-driven:

<File Include="$(NodeInstallDir)**" TargetPath="tools\$(PackageRID)\..." />

Whatever is in $(NodeInstallDir) after the layout targets in
node.proj ends up in the package. The layout is built up by
LayoutNodeWindows / LayoutNodeUnix:

  • Windows: glob $(NodeBuildDir)** then exclude pattern-matched
    build artifacts: bytecode_*, mksnapshot.*, node_mksnapshot.*,
    gen-regexp-special-case.*, genccode.*, genrb.*, iculslocs.*,
    icupkg.*, *_host.*, openssl*.*, overlapped*.*, torque.*,
    obj\**, lib\**, *test*.*, mkcodecache*.*, node.xlf\**,
    node.{exp,iobj,ipdb,lib,map,pdb}. Plus add npm tree (with all
    test/ subdirs removed), nodevars.*, install_tools/*,
    node_etw_provider.man, CHANGELOG.md, LICENSE, README.md.
  • Unix: make install output, plus CHANGELOG.md / LICENSE /
    README.md, plus libc++abi.so.1 + libc++.so.1 on Linux, plus
    strip/codesign/dsymutil pass.

Going v18→v24, the upstream tree (and therefore both make install
output and the unfiltered Windows build dir) will produce:

  • a far larger and reorganized npm tree (npm 9 → ~11.x);
  • different vendored deps/ (V8 12.x, OpenSSL 3.x, ICU bumped, ada,
    simdutf, undici, ngtcp2, etc. — all upstream-controlled);
  • possibly new gyp-output binaries on Windows that are not currently
    in the Remove list.

The pkgproj globbing handles the npm/deps changes automatically. The
only thing that may need a follow-up is adding new entries to the
Windows Remove list if v24's gyp build emits new helper executables
that we don't want in the final package (e.g. additional snapshot/
codegen helpers). That can only be confirmed from a real CI build —
inspect the diff of $(NodeInstallDir)\bin\*.exe between an
old-build artifact and the first v24 build, then add Removes for any
new non-shipping exe.

This PR does not preemptively edit node.proj's Remove list; it
keeps the layout exactly as dotnet/main had it.

Hashes that need updating: yes — one

  • cgmanifest.json: registrations[0].git.commitHash was
    2e414d5d1082233c3516fca923fe351d5186c80e (v18.17.1) →
    updated to d795edb56765d4ec743bcda5a0c1452bed74de0c (v24.7.0).
    Component Governance scans this file; without the bump, CG would
    keep reporting old vendored versions.

No other hashes (e.g. binary checksums, signatures, package SHAs) are
stored in this fork — the Wasm.Node.Transport package is signed at
publish time and its contents are dynamic.

Version numbers that need fixing: only src/node_version.h (already done) and cgmanifest.json (above)

  • src/node_version.h — fixed in the merge commit (24.7.0, IS_LTS=0).
  • cgmanifest.json — fixed in a follow-up commit on this branch.
  • eng/Versions.props VersionPrefix=11.0.0intentionally not
    changed
    . It's the .NET 11 band marker.
  • node.proj <NodeEmsdkVersion>node-$(VersionPrefix)-dotnet</NodeEmsdkVersion>
    → resolves to node-11.0.0-dotnet. Independent of upstream Node
    version. Not changed.
  • deps/undici/src/package-lock.json mentions @types/node-18.19.123
    that's an upstream npm devDep pin inside vendored undici, not a
    fork-controlled value. Not changed.

Out of scope

  • release/* branches (servicing). They keep building older Node
    transport versions for older dotnet/emsdk/release/* bands.
  • Other Emscripten 5.0.6 toolchain repos (dotnet/llvm-project
    dotnet/main-23.x, dotnet/binaryen dotnet/main, dotnet/cpython
    main → 3.13.3, dotnet/emscripten dotnet/main → 5.0.6, and the
    dotnet/emsdk main consolidation PR). Each is a separate PR per
    the plan.

Reviewer checklist

  • Merge commit has exactly two parents and the second parent is
    upstream tag v24.7.0 (d795edb56765d4ec743bcda5a0c1452bed74de0c).
  • git diff origin/dotnet/main...HEAD -- eng/ Directory.Build.props Directory.Build.targets NuGet.config global.json node.proj es-metadata.yml
    produces no output (dotnet infra untouched).
  • src/node_version.h matches upstream v24.7.0 byte-for-byte.
  • cgmanifest.json commitHash matches upstream v24.7.0.
  • AzDO build green; node --version in the published transport = v24.7.0.
  • Inspect $(NodeInstallDir)\bin\ from the first green Windows build
    vs. the previous Node-18 build; if any new helper .exes appear,
    extend the <NodeFiles Remove="..."/> list in node.proj in a
    follow-up.
  • No file in release/* branches changed.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.