diff --git a/.gitea/workflows/gates.yml b/.gitea/workflows/gates.yml index cf0b360..6b5397d 100644 --- a/.gitea/workflows/gates.yml +++ b/.gitea/workflows/gates.yml @@ -50,10 +50,12 @@ env: # Exact patch, not a floating "24" (milestone-14 ruling 12): the bundled npm # and the emitted bundle change under a floating major. NODE_VERSION: "24.19.0" + # node-v24.19.0-linux-x64.tar.gz, as nodejs.org's SHASUMS256.txt lists it. + NODE_TARBALL_SHA256: "f625d97cd707df4ff96254916fbc5ff014f09c09effe5a1e0ca8f6d41a8789d4" # The npm the cut runs and the npm CI runs must be one version: npm writes the # admin bundle whose bytes the release hashes are pinned to before CI ever - # rebuilds them. The runner image ships the npm that comes with the node - # above, so this pin is asserted, not installed. + # rebuilds them. The tarball above bundles this npm, so this pin is asserted, + # not installed. NPM_VERSION: "11.17.0" # There is deliberately no CI_VERSION literal here. Ruling 2 allows the # version to exist in the tag and in build.zig.zon and nowhere else, and @@ -138,9 +140,17 @@ jobs: steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - # The runner image ships this Node and npm on PATH; the assertion below is - # what pins them. setup-node is not used: it looks for Node in an empty - # tool cache and downloads it again on every run. + # Installed from the official tarball, pinned by its digest: the runner + # image's Node moves with the image tag, and a rebuilt image on a newer + # Node failed the assertion below on 2026-10-22. + - name: Install the pinned Node + run: | + curl -fsSLo "${RUNNER_TEMP:?}/node.tar.gz" "https://nodejs.org/dist/v${NODE_VERSION:?}/node-v${NODE_VERSION:?}-linux-x64.tar.gz" + echo "${NODE_TARBALL_SHA256:?} ${RUNNER_TEMP:?}/node.tar.gz" | sha256sum -c - + mkdir "${RUNNER_TEMP:?}/node" + tar -xzf "${RUNNER_TEMP:?}/node.tar.gz" -C "${RUNNER_TEMP:?}/node" --strip-components=1 + echo "${RUNNER_TEMP:?}/node/bin" >> "${GITHUB_PATH:?}" + - name: Cache npm downloads uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 19a0b1f..860ea03 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -68,6 +68,7 @@ env: ZIG_TARBALL_SHA256: "70e49664a74374b48b51e6f3fdfbf437f6395d42509050588bd49abe52ba3d00" # Exact patch, not a floating "24" (ruling 12). NODE_VERSION: "24.19.0" + NODE_TARBALL_SHA256: "f625d97cd707df4ff96254916fbc5ff014f09c09effe5a1e0ca8f6d41a8789d4" NPM_VERSION: "11.17.0" # The author's commit- and tag-signing key. `git verify-tag` alone proves @@ -271,9 +272,17 @@ jobs: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: ./zig-out/bin/release resolve - # The runner image ships this Node and npm on PATH; the assertion below is - # what pins them. setup-node is not used: it looks for Node in an empty - # tool cache and downloads it again on every run. + # Installed from the official tarball, pinned by its digest: the runner + # image's Node moves with the image tag, and a rebuilt image on a newer + # Node failed the assertion below on 2026-10-22. + - name: Install the pinned Node + run: | + curl -fsSLo "${RUNNER_TEMP:?}/node.tar.gz" "https://nodejs.org/dist/v${NODE_VERSION:?}/node-v${NODE_VERSION:?}-linux-x64.tar.gz" + echo "${NODE_TARBALL_SHA256:?} ${RUNNER_TEMP:?}/node.tar.gz" | sha256sum -c - + mkdir "${RUNNER_TEMP:?}/node" + tar -xzf "${RUNNER_TEMP:?}/node.tar.gz" -C "${RUNNER_TEMP:?}/node" --strip-components=1 + echo "${RUNNER_TEMP:?}/node/bin" >> "${GITHUB_PATH:?}" + - name: Cache npm downloads uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: