From 2a06239676120513fc382b03e9896c5a5cada3d8 Mon Sep 17 00:00:00 2001 From: m5r Date: Wed, 21 Oct 2026 18:53:42 +0200 Subject: [PATCH] ci: use the runner image's node instead of setup-node, which downloaded it again on every run --- .gitea/workflows/gates.yml | 21 +++++++++++---------- .gitea/workflows/release.yml | 12 +++++++----- .gitea/workflows/site.yml | 8 ++------ tools/cut.zig | 6 +++--- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/.gitea/workflows/gates.yml b/.gitea/workflows/gates.yml index ab9cd6e..b274616 100644 --- a/.gitea/workflows/gates.yml +++ b/.gitea/workflows/gates.yml @@ -52,8 +52,8 @@ env: NODE_VERSION: "24.19.0" # 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. setup-node installs the npm that ships with the node above, - # so this pin is asserted, not installed. + # rebuilds them. The runner image ships the npm that comes with the node + # above, 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 @@ -126,20 +126,21 @@ jobs: # 1536Mi dind limit, and it runs no docker command — so it overlaps the # heavy runner's zig and image work instead of queueing behind it. runs-on: ubuntu-24.04-light - # The slowest green run took 4 minutes. A stalled Node download leaves setup-node - # holding an open socket after its retry succeeds, so the step never exits: - # without a limit the job held the runner for over an hour. + # The slowest green run took 4 minutes. Without a limit, a request stalled + # on the network once held the runner for over an hour. timeout-minutes: 8 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - - name: Set up Node - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 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. + - name: Cache npm downloads + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: - node-version: ${{ env.NODE_VERSION }} - cache: npm - cache-dependency-path: admin/package-lock.json + path: ~/.npm + key: npm-${{ runner.os }}-${{ hashFiles('admin/package-lock.json') }} # The bundle is a release input whose hash is pinned before this run # exists, so a runner on a different node or npm must fail here rather diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 9f08d58..19a0b1f 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -271,12 +271,14 @@ jobs: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: ./zig-out/bin/release resolve - - name: Set up Node - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 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. + - name: Cache npm downloads + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: - node-version: ${{ env.NODE_VERSION }} - cache: npm - cache-dependency-path: admin/package-lock.json + path: ~/.npm + key: npm-${{ runner.os }}-${{ hashFiles('admin/package-lock.json') }} # The same pinned toolchain and normalized environment as the frontend # job in gates.yml: the cut pinned the bundle's bytes into flake.nix diff --git a/.gitea/workflows/site.yml b/.gitea/workflows/site.yml index 11378a4..c393b90 100644 --- a/.gitea/workflows/site.yml +++ b/.gitea/workflows/site.yml @@ -26,7 +26,6 @@ concurrency: cancel-in-progress: false env: - NODE_VERSION: "24.19.0" # The newest wrangler older than npm's release-age floor on the day it was pinned. WRANGLER_VERSION: "4.148.0" @@ -37,11 +36,8 @@ jobs: steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - - name: Set up Node - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: ${{ env.NODE_VERSION }} - + # Node is the one the runner image puts on PATH. setup-node is not used: + # it looks for Node in an empty tool cache and downloads it again. - name: Build working-directory: website run: | diff --git a/tools/cut.zig b/tools/cut.zig index f636d01..4022d18 100644 --- a/tools/cut.zig +++ b/tools/cut.zig @@ -1659,9 +1659,9 @@ fn toolchainParity(ctx: *Ctx) ![]const u8 { return CheckFailed; }; - // `node --version` prints `v24.19.0`; the workflow pins the number the way - // setup-node takes it, without the `v`. `npm --version` and `zig version` - // print the bare number already. + // `node --version` prints `v24.19.0`; the workflow pins the bare number, + // without the `v`. `npm --version` and `zig version` print the bare number + // already. try assertVersion(ctx, "node", &.{ "node", "--version" }, "v", pins.node); try assertVersion(ctx, "npm", &.{ "npm", "--version" }, "", pins.npm);