diff --git a/.github/actions/build-shared/action.yml b/.github/actions/build-shared/action.yml new file mode 100644 index 00000000000000..757440f1f36812 --- /dev/null +++ b/.github/actions/build-shared/action.yml @@ -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 {}).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" diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml index 34104d1db676b8..816c95235dcf6a 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -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: @@ -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 }} @@ -104,6 +106,9 @@ concurrency: env: FLAKY_TESTS: keep_retrying + # Latest OpenSSL major.minor cycle we support running tests with. + # The nixpkgs updater regenerates the OpenSSL matrix using this value. + SUPPORTED_OPENSSL_VERSION: '4.0' permissions: contents: read @@ -153,50 +158,68 @@ jobs: 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: - name: tarballs - path: tarballs - - - name: Extract tarball + persist-credentials: false + sparse-checkout: .github/actions + - uses: ./.github/actions/build-shared if: ${{ github.event_name != 'workflow_dispatch' }} - 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 + system: ${{ matrix.system }} + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} - - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17 + # 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: - name: nodejs - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + persist-credentials: false + sparse-checkout: tools/nix + sparse-checkout-cone-mode: false + - id: query + run: | + matrix=$(jq -c . tools/nix/openssl-matrix.json) + echo "matrix=$matrix" >> "$GITHUB_OUTPUT" - - name: Configure sccache - if: github.base_ref == 'main' || github.ref_name == 'main' - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + # 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-tarball + - 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: - 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 {}).sccache'); - - - name: Build Node.js and run tests - 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" + 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; }" diff --git a/tools/dep_updaters/update-nixpkgs-pin.sh b/tools/dep_updaters/update-nixpkgs-pin.sh index 6c23905ef0e093..4d1f2dc7006ef5 100755 --- a/tools/dep_updaters/update-nixpkgs-pin.sh +++ b/tools/dep_updaters/update-nixpkgs-pin.sh @@ -5,6 +5,8 @@ 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" +TEST_SHARED_WORKFLOW_FILE="$BASE_DIR/.github/workflows/test-shared.yml" NIXPKGS_REPO=$(grep 'repo =' "$NIXPKGS_PIN_FILE" | awk -F'"' '{ print $2 }') CURRENT_VERSION_SHA1=$(grep 'rev =' "$NIXPKGS_PIN_FILE" | awk -F'"' '{ print $2 }') @@ -25,12 +27,22 @@ 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" +SUPPORTED_OPENSSL_VERSION=$(sed -nE "s/^[[:space:]]*SUPPORTED_OPENSSL_VERSION:[[:space:]]*'([^']+)'[[:space:]]*$/\1/p" "$TEST_SHARED_WORKFLOW_FILE" | head -n1) + +if [ -z "$SUPPORTED_OPENSSL_VERSION" ]; then + echo "Could not resolve SUPPORTED_OPENSSL_VERSION from $TEST_SHARED_WORKFLOW_FILE" >&2 + exit 1 +fi + +SUPPORTED_OPENSSL_VERSION="$SUPPORTED_OPENSSL_VERSION" \ + "$BASE_DIR/tools/nix/collect-openssl-matrix.sh" | jq . > "$OPENSSL_MATRIX_FILE" + cat -< $today or .extendedSupport == true) + | .cycle as $v + | ($nix + | map(select(.version | test("^" + ($v | gsub("\\."; "\\.")) + "([.a-z]|$)"))) + | first) as $m + | select($m != null) + | select($m.version != $default_version) + | { + version: $m.version, + attr: $m.attr, + "continue-on-error": (cycle_tuple($v) > cycle_tuple($supported)) + } + ]' diff --git a/tools/nix/openssl-matrix.json b/tools/nix/openssl-matrix.json new file mode 100644 index 00000000000000..de19bcfbcb3657 --- /dev/null +++ b/tools/nix/openssl-matrix.json @@ -0,0 +1,22 @@ +[ + { + "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.0.19", + "attr": "openssl_3", + "continue-on-error": false + }, + { + "version": "1.1.1w", + "attr": "openssl_1_1", + "continue-on-error": false + } +]