Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/actions/build-shared/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Build Node.js (shared libraries)
description: >
Downloads the slim tarball built by the `build-tarball` job, extracts it,
installs Nix (+ cachix + sccache), then builds Node.js and runs the CI
test suite inside the pinned nix-shell.

inputs:
system:
description: System label (e.g. x86_64-linux, aarch64-darwin).
required: true
extra-nix-args:
description: Additional arguments appended to the nix-shell invocation.
required: false
default: ''
cachix-auth-token:
description: Cachix auth token for nodejs.cachix.org.
required: false
default: ''

runs:
using: composite
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
if: ${{ github.event_name != 'workflow_dispatch' }}
with:
name: tarballs
path: tarballs

- name: Extract tarball
if: ${{ github.event_name != 'workflow_dispatch' }}
shell: bash
run: |
tar xzf tarballs/*.tar.gz -C "$RUNNER_TEMP"
echo "TAR_DIR=$RUNNER_TEMP/$(basename tarballs/*.tar.gz .tar.gz)" >> "$GITHUB_ENV"

- uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
with:
extra_nix_config: sandbox = true

- uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
with:
name: nodejs
authToken: ${{ inputs.cachix-auth-token }}

- name: Configure sccache
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
core.exportVariable('SCCACHE_GHA_ENABLED', 'on');
core.exportVariable('ACTIONS_CACHE_SERVICE_V2', 'on');
core.exportVariable('ACTIONS_RESULTS_URL', process.env.ACTIONS_RESULTS_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
core.exportVariable('NIX_SCCACHE', '(import <nixpkgs> {}).sccache');

- name: Build Node.js and run tests
shell: bash
run: |
nix-shell \
-I "nixpkgs=$TAR_DIR/tools/nix/pkgs.nix" \
--pure --keep TAR_DIR --keep FLAKY_TESTS \
--keep SCCACHE_GHA_ENABLED --keep ACTIONS_CACHE_SERVICE_V2 --keep ACTIONS_RESULTS_URL --keep ACTIONS_RUNTIME_TOKEN \
--arg loadJSBuiltinsDynamically false \
--arg useSeparateDerivationForV8 true \
--arg ccache "${NIX_SCCACHE:-null}" \
--arg devTools '[]' \
--arg benchmarkTools '[]' \
${{ endsWith(inputs.system, '-darwin') && '--arg withAmaro false --arg withLief false --arg withSQLite false --arg withFFI false --arg extraConfigFlags ''["--without-inspector" "--without-node-options"]'' \' || '\' }}
${{ inputs.extra-nix-args }} \
--run '
make -C "$TAR_DIR" run-ci -j4 V=1 TEST_CI_ARGS="-p actions --measure-flakiness 9 --skip-tests=$CI_SKIP_TESTS"
' "$TAR_DIR/shell.nix"
120 changes: 92 additions & 28 deletions .github/workflows/test-shared.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ on:
- vcbuild.bat
- .**
- '!.github/workflows/test-shared.yml'
- '!.github/actions/build-shared/**'
types: [opened, synchronize, reopened, ready_for_review]
push:
branches:
Expand Down Expand Up @@ -97,6 +98,7 @@ on:
- vcbuild.bat
- .**
- '!.github/workflows/test-shared.yml'
- '!.github/actions/build-shared/**'

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
Expand Down Expand Up @@ -144,59 +146,121 @@ jobs:
include:
- runner: ubuntu-24.04
system: x86_64-linux
- runner: ubuntu-24.04-arm
system: aarch64-linux
# built separately in build-aarch64-linux-v8
# - runner: ubuntu-24.04-arm
# system: aarch64-linux
- runner: macos-15-intel
system: x86_64-darwin
- runner: macos-latest
system: aarch64-darwin
name: '${{ matrix.system }}: with shared libraries'
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
if: ${{ github.event_name != 'workflow_dispatch' }}
with:
persist-credentials: false
sparse-checkout: .github/actions
- uses: ./.github/actions/build-shared
if: ${{ github.event_name != 'workflow_dispatch' }}
with:
system: ${{ matrix.system }}
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}

build-aarch64-linux-v8:
needs: build-tarball
runs-on: ubuntu-24.04-arm
name: 'aarch64-linux: Cache V8 build'
steps:
- name: Check if Cachix is available
id: cachix-check
run: echo 'IS_AVAILABLE=${{ secrets.CACHIX_AUTH_TOKEN && 'true' }}' >> "$GITHUB_OUTPUT"

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
if: ${{ steps.cachix-check.outputs.IS_AVAILABLE == 'true' }}
with:
name: tarballs
path: tarballs

- name: Extract tarball
if: ${{ github.event_name != 'workflow_dispatch' }}
if: ${{ steps.cachix-check.outputs.IS_AVAILABLE == 'true' }}
shell: bash
run: |
tar xzf tarballs/*.tar.gz -C "$RUNNER_TEMP"
echo "TAR_DIR=$RUNNER_TEMP/$(basename tarballs/*.tar.gz .tar.gz)" >> "$GITHUB_ENV"

- uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
if: ${{ steps.cachix-check.outputs.IS_AVAILABLE == 'true' }}
with:
extra_nix_config: sandbox = true

- uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
if: ${{ steps.cachix-check.outputs.IS_AVAILABLE == 'true' }}
with:
name: nodejs
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}

- name: Configure sccache
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
- name: Build V8 derivation
if: ${{ steps.cachix-check.outputs.IS_AVAILABLE == 'true' }}
run: |
nix-build "$(
nix-instantiate -E "builtins.filter (p: p.pname == ''v8'') (import $TAR_DIR/shell.nix { useSeparateDerivationForV8=true; }).buildInputs"
)"

# Builds the matrix for `build-openssl` from tools/nix/openssl-matrix.json.
# Output shape:
# [{ "version": "3.6.1", "attr": "openssl_3_6", "continue-on-error": false }, ...]
collect-openssl-versions:
if: github.event.pull_request.draft == false
runs-on: ubuntu-slim
outputs:
matrix: ${{ steps.query.outputs.matrix }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
script: |
core.exportVariable('SCCACHE_GHA_ENABLED', 'on');
core.exportVariable('ACTIONS_CACHE_SERVICE_V2', 'on');
core.exportVariable('ACTIONS_RESULTS_URL', process.env.ACTIONS_RESULTS_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
core.exportVariable('NIX_SCCACHE', '(import <nixpkgs> {}).sccache');

- name: Build Node.js and run tests
persist-credentials: false
sparse-checkout: tools/nix/openssl-matrix.json
sparse-checkout-cone-mode: false
- id: query
run: |
nix-shell \
-I "nixpkgs=$TAR_DIR/tools/nix/pkgs.nix" \
--pure --keep TAR_DIR --keep FLAKY_TESTS \
--keep SCCACHE_GHA_ENABLED --keep ACTIONS_CACHE_SERVICE_V2 --keep ACTIONS_RESULTS_URL --keep ACTIONS_RUNTIME_TOKEN \
--arg loadJSBuiltinsDynamically false \
--arg useSeparateDerivationForV8 true \
--arg ccache "${NIX_SCCACHE:-null}" \
--arg devTools '[]' \
--arg benchmarkTools '[]' \
${{ endsWith(matrix.system, '-darwin') && '--arg withAmaro false --arg withLief false --arg withSQLite false --arg withFFI false --arg extraConfigFlags ''["--without-inspector" "--without-node-options"]'' \' || '\' }}
--run '
make -C "$TAR_DIR" run-ci -j4 V=1 TEST_CI_ARGS="-p actions --measure-flakiness 9 --skip-tests=$CI_SKIP_TESTS"
' "$TAR_DIR/shell.nix"
{
echo 'matrix<<EOF'
cat tools/nix/openssl-matrix.json
echo 'EOF'
} >> "$GITHUB_OUTPUT"

# Builds and tests Node.js with shared libraries against every supported
# OpenSSL release version available in the repo-pinned nixpkgs. The default
# shared `openssl` from tools/nix/sharedLibDeps.nix is overridden per matrix
# entry, while all other shared libs remain at their defaults. Only runs on
# a single runner/system (aarch64-linux) to keep the matrix to a minimum.
build-openssl:
needs:
- build-aarch64-linux-v8
- collect-openssl-versions
strategy:
fail-fast: false
matrix:
openssl: ${{ fromJSON(needs.collect-openssl-versions.outputs.matrix) }}
name: 'aarch64-linux: with shared ${{ matrix.openssl.attr }} (${{ matrix.openssl.version }})'
runs-on: ubuntu-24.04-arm
continue-on-error: ${{ matrix.openssl['continue-on-error'] }}
env:
OPENSSL_ATTR: ${{ matrix.openssl.attr }}
OPENSSL_VERSION: ${{ matrix.openssl.version }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: .github/actions
- uses: ./.github/actions/build-shared
with:
system: aarch64-linux
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
# Override just the `openssl` attr of the default shared-lib set with
# the matrix-selected nixpkgs attribute (e.g. `openssl_3_6`). All
# other shared libs (brotli, cares, libuv, …) keep their defaults.
# `permittedInsecurePackages` whitelists just the matrix-selected
# release (e.g. `openssl-1.1.1w`) so EOL-with-extended-support
# cycles evaluate without relaxing nixpkgs' meta check globally.
extra-nix-args: --arg sharedLibDeps "(import $TAR_DIR/tools/nix/sharedLibDeps.nix {}) // { openssl = (import $TAR_DIR/tools/nix/pkgs.nix { config.permittedInsecurePackages = [ \"openssl-$OPENSSL_VERSION\" ]; }).$OPENSSL_ATTR; }"
5 changes: 4 additions & 1 deletion tools/dep_updaters/update-nixpkgs-pin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set -ex

BASE_DIR=$(cd "$(dirname "$0")/../.." && pwd)
NIXPKGS_PIN_FILE="$BASE_DIR/tools/nix/pkgs.nix"
OPENSSL_MATRIX_FILE="$BASE_DIR/tools/nix/openssl-matrix.json"

NIXPKGS_REPO=$(grep 'repo =' "$NIXPKGS_PIN_FILE" | awk -F'"' '{ print $2 }')
CURRENT_VERSION_SHA1=$(grep 'rev =' "$NIXPKGS_PIN_FILE" | awk -F'"' '{ print $2 }')
Expand All @@ -25,12 +26,14 @@ TMP_FILE=$(mktemp)
sed "s/$CURRENT_VERSION_SHA1/$NEW_UPSTREAM_SHA1/;s/$CURRENT_TARBALL_HASH/$NEW_TARBALL_HASH/" "$NIXPKGS_PIN_FILE" > "$TMP_FILE"
mv "$TMP_FILE" "$NIXPKGS_PIN_FILE"

"$BASE_DIR/tools/nix/collect-openssl-matrix.sh" | jq . > "$OPENSSL_MATRIX_FILE"

cat -<<EOF
All done!

Please git add and commit the new version:

$ git add $NIXPKGS_PIN_FILE
$ git add $NIXPKGS_PIN_FILE $OPENSSL_MATRIX_FILE
$ git commit -m 'tools: bump nixpkgs-unstable pin to $NEW_VERSION'
EOF

Expand Down
65 changes: 65 additions & 0 deletions tools/nix/collect-openssl-matrix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/bin/sh
#
# Emits the JSON source data of OpenSSL releases to test Node.js against with
# shared libraries.
#
# This helper is used by tools/dep_updaters/update-nixpkgs-pin.sh to
# regenerate tools/nix/openssl-matrix.json.
#
# Output (stdout): a JSON array with shape
# [{ "version": "3.6.1", "attr": "openssl_3_6", "continue-on-error": false }, ...]
#
# Usage: ./tools/nix/collect-openssl-matrix.sh

set -eu

# Latest OpenSSL major.minor cycle we support
# running tests with. Newer cycles are emitted
# with "continue-on-error": true.
SUPPORTED_OPENSSL_VERSION=4.0

here=$(cd -- "$(dirname -- "$0")" && pwd)

# 1. Enumerate every `openssl_N` / `openssl_N_M` attribute exposed by the
# repo-pinned nixpkgs. `tryEval` skips aliases that raise (e.g.
# `openssl_3_0` → renamed to `openssl_3`) so we only keep attributes
# that resolve to a real derivation with a `.version`.
nix_json=$(nix-instantiate --eval --strict --json -E "
let
pkgs = import $here/pkgs.nix {};
names = builtins.filter
(n: builtins.match \"openssl_[0-9]+(_[0-9]+)?\" n != null)
(builtins.attrNames pkgs);
safe = builtins.filter (n:
let t = builtins.tryEval pkgs.\${n}; in
t.success && (builtins.tryEval t.value.version).success) names;
in map (n: { attr = n; version = pkgs.\${n}.version; }) safe
")

# 2. Fetch OpenSSL release versions from endoflife.date, keep entries that
# are either not past EOL or still under extended support, then pick the
# first nix attr whose `.version` starts with the release version
# followed by `.` / letter / end-of-string (so "3.6" matches "3.6.1",
# "1.1.1" matches "1.1.1w", and "1.1" does NOT swallow "1.1.1").
# Releases without a matching nix attr are dropped.
curl -sf https://endoflife.date/api/openssl.json \
| jq -c \
--argjson nix "$nix_json" \
--arg supported "$SUPPORTED_OPENSSL_VERSION" '
(now | strftime("%Y-%m-%d")) as $today |
# Compare OpenSSL major.minor cycles as numeric tuples.
def cycle_tuple($v):
($v | split(".") | map(tonumber));
[ .[]
| select(.eol == false or .eol > $today or .extendedSupport == true)
| .cycle as $v
| ($nix
| map(select(.version | test("^" + ($v | gsub("\\."; "\\.")) + "([.a-z]|$)")))
| first) as $m
| select($m != null)
| {
version: $m.version,
attr: $m.attr,
"continue-on-error": (cycle_tuple($v) > cycle_tuple($supported))
}
]'
27 changes: 27 additions & 0 deletions tools/nix/openssl-matrix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[
{
"version": "4.0.0",
"attr": "openssl_4_0",
"continue-on-error": false
},
{
"version": "3.6.1",
"attr": "openssl_3_6",
"continue-on-error": false
},
{
"version": "3.5.5",
"attr": "openssl_3_5",
"continue-on-error": false
},
{
"version": "3.0.19",
"attr": "openssl_3",
"continue-on-error": false
},
{
"version": "1.1.1w",
"attr": "openssl_1_1",
"continue-on-error": false
}
]
Loading