Skip to content

Commit 89b2de7

Browse files
Merge branch 'nodejs:main' into main
2 parents f26f6a2 + 42fd49a commit 89b2de7

90 files changed

Lines changed: 7276 additions & 5330 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
<!--
2+
If you are submitting a pull request for the first time,
3+
check out the guide for first-time contributors for tips and answers to FAQs:
4+
https://github.com/nodejs/node/blob/HEAD/doc/contributing/first-contributions.md
5+
26
Before submitting a pull request, please read:
37
48
- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md

.github/workflows/benchmark.yml

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
name: Benchmark
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
repo:
7+
type: string
8+
description: GitHub repository to fetch from (default to the current repo)
9+
pr_id:
10+
type: number
11+
required: true
12+
description: The PR to test
13+
commit:
14+
required: true
15+
type: string
16+
description: The expect HEAD of the PR
17+
category:
18+
required: true
19+
type: string
20+
description: The category (or categories) of tests to run, for example buffers, cluster etc. Maps to a folders in node/benchmark
21+
filter:
22+
type: string
23+
description: A substring to restrict the benchmarks to run in a category. e.g. `net-c2c`
24+
runs:
25+
type: number
26+
default: 30
27+
description: How many times to repeat each benchmark
28+
29+
permissions:
30+
contents: read
31+
32+
jobs:
33+
build:
34+
strategy:
35+
fail-fast: true
36+
matrix:
37+
include:
38+
- runner: ubuntu-24.04
39+
system: x86_64-linux
40+
- runner: ubuntu-24.04-arm
41+
system: aarch64-linux
42+
- runner: macos-15-intel
43+
system: x86_64-darwin
44+
- runner: macos-latest
45+
system: aarch64-darwin
46+
name: '${{ matrix.system }}: with shared libraries'
47+
runs-on: ${{ matrix.runner }}
48+
steps:
49+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
50+
with:
51+
repository: ${{ inputs.repo || github.repository }}
52+
ref: refs/pull/${{ inputs.pr_id }}/merge
53+
persist-credentials: false
54+
fetch-depth: 2
55+
56+
- name: Validate PR head and roll back to base commit
57+
run: |
58+
[ "$(git rev-parse HEAD^2)" = "$EXPECTED_SHA" ]
59+
git reset HEAD^ --hard
60+
env:
61+
EXPECTED_SHA: ${{ inputs.commit }}
62+
63+
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
64+
with:
65+
extra_nix_config: sandbox = true
66+
67+
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
68+
with:
69+
# We do not pass any `authToken` to avoid polluting the cache with potentially untrusted code.
70+
name: nodejs
71+
72+
- name: Configure sccache
73+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
74+
with:
75+
script: |
76+
core.exportVariable('SCCACHE_GHA_VERSION', 'on');
77+
core.exportVariable('ACTIONS_CACHE_SERVICE_V2', 'on');
78+
core.exportVariable('ACTIONS_RESULTS_URL', process.env.ACTIONS_RESULTS_URL || '');
79+
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
80+
81+
- name: Build Node.js on the base commit
82+
run: |
83+
nix-shell \
84+
-I nixpkgs=./tools/nix/pkgs.nix \
85+
--pure --keep TAR_DIR --keep FLAKY_TESTS \
86+
--keep SCCACHE_GHA_ENABLED --keep ACTIONS_CACHE_SERVICE_V2 --keep ACTIONS_RESULTS_URL --keep ACTIONS_RUNTIME_TOKEN \
87+
--arg useSeparateDerivationForV8 true \
88+
--arg loadJSBuiltinsDynamically false \
89+
--arg ccache "${NIX_SCCACHE:-null}" \
90+
--arg devTools '[]' \
91+
--arg benchmarkTools '[]' \
92+
--run '
93+
make build-ci -j4 V=1
94+
'
95+
mv out/Release/node base_node
96+
97+
- name: Checkout the merge commit
98+
run: git reset FETCH_HEAD --hard
99+
100+
- name: Re-build Node.js on the merge commit
101+
# ccache is disabled here to avoid polluting the cache. Local build outputs should make this build relatively quick anyway.
102+
run: |
103+
nix-shell \
104+
-I nixpkgs=./tools/nix/pkgs.nix \
105+
--pure \
106+
--arg useSeparateDerivationForV8 true \
107+
--arg loadJSBuiltinsDynamically false \
108+
--arg ccache 'null' \
109+
--arg devTools '[]' \
110+
--arg benchmarkTools '[]' \
111+
--run '
112+
make -j4 V=1
113+
'
114+
115+
- name: Run benchmark
116+
run: |
117+
nix-shell \
118+
-I nixpkgs=./tools/nix/pkgs.nix \
119+
--pure --keep FILTER --keep LC_ALL --keep LANG \
120+
--arg loadJSBuiltinsDynamically false \
121+
--arg ccache 'null' \
122+
--arg icu 'null' \
123+
--arg sharedLibDeps '{}' \
124+
--arg devTools '[]' \
125+
--run '
126+
set -o pipefail
127+
./base_node benchmark/compare.js \
128+
--filter "$FILTER" \
129+
--runs ${{ inputs.runs }} \
130+
--old ./base_node --new ./node \
131+
-- ${{ inputs.category }} \
132+
| tee /dev/stderr \
133+
> ${{ matrix.system }}.csv
134+
echo "> [!WARNING] "
135+
echo "> Do not take GHA benchmark results as face value, always confirm them"
136+
echo "> using a dedicated machine, e.g. Jenkins CI."
137+
echo
138+
echo "Benchmark results:"
139+
echo
140+
echo '"'"'```'"'"'
141+
Rscript benchmark/compare.R < ${{ matrix.system }}.csv
142+
echo '"'"'```'"'"'
143+
echo
144+
echo "> [!WARNING] "
145+
echo "> Do not take GHA benchmark results as face value, always confirm them"
146+
echo "> using a dedicated machine, e.g. Jenkins CI."
147+
' | tee /dev/stderr >> "$GITHUB_STEP_SUMMARY"
148+
env:
149+
FILTER: ${{ inputs.filter }}
150+
151+
- name: Upload raw benchmark results
152+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
153+
with:
154+
name: csv-${{ matrix.system }}
155+
path: ${{ matrix.system }}.csv
156+
157+
aggregate-results:
158+
needs: build
159+
name: Aggregate benchmark results
160+
runs-on: ubuntu-slim
161+
steps:
162+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
163+
with:
164+
persist-credentials: false
165+
sparse-checkout: |
166+
benchmark/*.R
167+
tools/nix/*.nix
168+
*.nix
169+
sparse-checkout-cone-mode: false
170+
171+
- name: Download benchmark raw results
172+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
173+
with:
174+
pattern: csv-*
175+
merge-multiple: true
176+
path: raw-results
177+
178+
- uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
179+
with:
180+
extra_nix_config: sandbox = true
181+
182+
- name: Benchmark results
183+
run: |
184+
nix-shell \
185+
-I nixpkgs=./tools/nix/pkgs.nix \
186+
--pure \
187+
-E '(import <nixpkgs> {}).mkShell { buildInputs = import ./tools/nix/benchmarkTools.nix { withHttpBenchmarkDeps = false; }; }' \
188+
--run '
189+
export LC_ALL=C.UTF-8
190+
echo "> [!WARNING] "
191+
echo "> Do not take GHA benchmark results as face value, always confirm them"
192+
echo "> using a dedicated machine, e.g. Jenkins CI."
193+
echo
194+
echo "Benchmark results:"
195+
echo
196+
echo '"'"'```'"'"'
197+
awk "FNR==1 && NR!=1{next;}{print}" raw-results/*.csv | Rscript benchmark/compare.R
198+
echo '"'"'```'"'"'
199+
echo
200+
echo "> [!WARNING] "
201+
echo "> Do not take GHA benchmark results as face value, always confirm them"
202+
echo "> using a dedicated machine, e.g. Jenkins CI."
203+
' | tee /dev/stderr >> "$GITHUB_STEP_SUMMARY"

.github/workflows/lint-release-proposal.yml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,24 @@ jobs:
2828
persist-credentials: false
2929
fetch-depth: 2
3030
- name: Lint release commit title format
31+
id: commit-message-parse
3132
run: |
32-
EXPECTED_TITLE='^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}, Version [[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+ (\(Current|'.+' \(LTS)\)$'
33+
VERSION=$(${CXX:-cc} -E -dM src/node_version.h | awk '
34+
$2 == "NODE_MAJOR_VERSION" { maj = $3 }
35+
$2 == "NODE_MINOR_VERSION" { min = $3 }
36+
$2 == "NODE_PATCH_VERSION" { pat = $3 }
37+
$2 == "NODE_VERSION_LTS_CODENAME" { gsub(/^"|"$/, "'"'"'",$3); lts = $3 }
38+
END { if (maj) print maj "\\." min "\\." pat " " (lts != "'"''"'" ? lts " \\(LTS" : "\\(Current" ) "\\)" }
39+
')
40+
MAJOR=${VERSION%%\\.*}
41+
EXPECTED_TITLE='^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}, Version '"$VERSION"'$'
3342
echo "Expected commit title format: $EXPECTED_TITLE"
3443
COMMIT_SUBJECT="$(git --no-pager log -1 --format=%s)"
35-
echo "Actual: $ACTUAL"
44+
echo "Actual: $COMMIT_SUBJECT"
3645
echo "$COMMIT_SUBJECT" | grep -q -E "$EXPECTED_TITLE"
37-
echo "COMMIT_SUBJECT=$COMMIT_SUBJECT" >> "$GITHUB_ENV"
46+
47+
echo "COMMIT_SUBJECT=$COMMIT_SUBJECT" >> "$GITHUB_OUTPUT"
48+
echo "MAJOR=$MAJOR" >> "$GITHUB_OUTPUT"
3849
- name: Lint release commit message trailers
3950
run: |
4051
EXPECTED_TRAILER="^$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pull/[[:digit:]]+\$"
@@ -54,8 +65,6 @@ jobs:
5465
SKIP_XZ=1 make release-only
5566
- name: Lint release commit content
5667
run: |
57-
MAJOR="$(awk '/^#define NODE_MAJOR_VERSION / { print $3 }' src/node_version.h)"
58-
5968
echo "Checking for expected files in the release commit:"
6069
missing_expected=
6170
for expected in CHANGELOG.md src/node_version.h doc/changelogs/; do
@@ -81,7 +90,6 @@ jobs:
8190
run: |
8291
EXPECTED_CHANGELOG_TITLE_INTRO="## $COMMIT_SUBJECT, @"
8392
echo "Expected CHANGELOG section title: $EXPECTED_CHANGELOG_TITLE_INTRO"
84-
MAJOR="$(awk '/^#define NODE_MAJOR_VERSION / { print $3 }' src/node_version.h)"
8593
CHANGELOG_PATH="doc/changelogs/CHANGELOG_V${MAJOR}.md"
8694
CHANGELOG_TITLE="$(grep "$EXPECTED_CHANGELOG_TITLE_INTRO" "$CHANGELOG_PATH")"
8795
echo "Actual: $CHANGELOG_TITLE"
@@ -106,4 +114,6 @@ jobs:
106114
done
107115
shell: bash # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference, we want the pipefail option.
108116
env:
117+
COMMIT_SUBJECT: ${{ steps.commit-message-parse.outputs.COMMIT_SUBJECT }}
118+
MAJOR: ${{ steps.commit-message-parse.outputs.MAJOR }}
109119
GH_TOKEN: ${{ github.token }}

.github/workflows/stress-test.yml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: Stress Test (rebase tested branch on main for cache reuse)
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
test_path:
7+
description: Test path or glob (e.g. test/parallel/test-debugger-break.js or "test/parallel/test-debugger-*")
8+
required: true
9+
type: string
10+
os:
11+
description: Runner to use
12+
required: true
13+
default: macos-15
14+
type: choice
15+
options:
16+
- macos-15
17+
- ubuntu-24.04
18+
- ubuntu-24.04-arm
19+
repeat:
20+
description: Number of times to repeat each test (--repeat)
21+
required: true
22+
default: '1000'
23+
type: string
24+
test_jobs:
25+
description: Number of jobs to run in parallel (-j).
26+
required: true
27+
default: '1'
28+
type: string
29+
test_args:
30+
description: Extra args for tools/test.py, space-separated (e.g. "-t 10 --worker")
31+
required: false
32+
default: ''
33+
type: string
34+
35+
env:
36+
PYTHON_VERSION: '3.14'
37+
XCODE_VERSION: '16.4'
38+
CLANG_VERSION: '19'
39+
RUSTC_VERSION: '1.82'
40+
41+
permissions:
42+
contents: read
43+
44+
jobs:
45+
stress-test:
46+
runs-on: ${{ inputs.os }}
47+
env:
48+
# Linux builds with clang (matching test-linux.yml), macOS with gcc/g++.
49+
CC: ${{ startsWith(inputs.os, 'ubuntu') && 'sccache clang-19' || 'sccache gcc' }}
50+
CXX: ${{ startsWith(inputs.os, 'ubuntu') && 'sccache clang++-19' || 'sccache g++' }}
51+
# Enable sccache - this is okay for a manually-dispatched workflow that is typically used to
52+
# test lib-only or test-only deflaking changes. This should be able to pick up cache from
53+
# test-linux.yml and test-macos.yml running on the main branch.
54+
SCCACHE_GHA_ENABLED: 'true'
55+
SCCACHE_IDLE_TIMEOUT: '0'
56+
steps:
57+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
58+
with:
59+
persist-credentials: false
60+
path: node
61+
- name: Install Clang ${{ env.CLANG_VERSION }}
62+
if: runner.os == 'Linux'
63+
uses: ./node/.github/actions/install-clang
64+
with:
65+
clang-version: ${{ env.CLANG_VERSION }}
66+
- name: Set up Xcode ${{ env.XCODE_VERSION }}
67+
if: runner.os == 'macOS'
68+
run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app
69+
- name: Set up Python ${{ env.PYTHON_VERSION }}
70+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
71+
with:
72+
python-version: ${{ env.PYTHON_VERSION }}
73+
allow-prereleases: true
74+
- name: Install Rust ${{ env.RUSTC_VERSION }}
75+
run: |
76+
rustup override set "$RUSTC_VERSION"
77+
rustup --version
78+
- name: Set up sccache
79+
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
80+
with:
81+
version: v0.16.0
82+
- name: Environment Information
83+
run: npx envinfo@7.21.0
84+
# This is needed due to https://github.com/nodejs/build/issues/3878
85+
- name: Cleanup
86+
if: runner.os == 'macOS'
87+
run: |
88+
echo "::group::Free space before cleanup"
89+
df -h
90+
echo "::endgroup::"
91+
echo "::group::Cleaned Files"
92+
93+
sudo rm -rf /Users/runner/Library/Android/sdk
94+
95+
echo "::endgroup::"
96+
echo "::group::Free space after cleanup"
97+
df -h
98+
echo "::endgroup::"
99+
- name: Build
100+
run: make -C node build-ci -j"$(getconf _NPROCESSORS_ONLN)" V=1 CONFIG_FLAGS="--error-on-warn --v8-enable-temporal-support"
101+
- name: Stress run ${{ inputs.test_path }} x${{ inputs.repeat }}
102+
shell: bash
103+
env:
104+
REPEAT: ${{ inputs.repeat }}
105+
JOBS: ${{ inputs.test_jobs }}
106+
TEST_ARGS: ${{ inputs.test_args }}
107+
TEST_PATH: ${{ inputs.test_path }}
108+
run: |
109+
cd node
110+
read -ra EXTRA_ARGS <<< "$TEST_ARGS"
111+
python3 tools/test.py \
112+
--repeat "$REPEAT" \
113+
-j "$JOBS" \
114+
-p actions \
115+
"${EXTRA_ARGS[@]}" \
116+
"$TEST_PATH"

CONTRIBUTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Contributing to Node.js
22

3+
> \[!TIP]
4+
> Contributing for the first time? Please read our
5+
> [Guide for First-Time Contributors](./doc/contributing/first-contributions.md) for tips
6+
> and answers to FAQs.
7+
38
Contributions to Node.js include code, documentation, answering user questions,
49
running the project's infrastructure, and advocating for all types of Node.js
510
users.

0 commit comments

Comments
 (0)