Repository navigation
ci: move the web lane to Node 24 (newest active LTS) - #1045
engrams-agent[bot] wants to merge 1 commit into
Conversation
Node 20 reached end of life on 2026-04-30, so the `web (pnpm)` lane has been building and testing the SPA on an unsupported runtime. Move it to 24, and move `flake.nix` with it so `nix develop` matches CI. Why 24 and not 25 or 26: only even majors become LTS. 24 entered LTS on 2025-10-28 and stays in active support until 2026-10-20 (EOL 2028-04-30). 25 is a Current-only line that already went EOL on 2026-06-01, and 26 does not become LTS until 2026-10-28. This also unblocks #940 (jsdom 29 -> 30). jsdom 30 raised its floor to `^22.22.2 || ^24.15.0 || >=26.0.0` because it depends on undici 8, which calls `worker_threads.markAsUncloneable` — a function Node 20 does not have. On Node 20 every one of the 52 vitest files dies at worker startup with `TypeError: webidl.util.markAsUncloneable is not a function`, so the jsdom bump cannot go green until this lands. `node-version: 24` resolves the latest 24.x, which satisfies jsdom's `^24.15.0`.
|
✅ engrams review — complete. 0 findings posted. · View details |
|
The latest Buf updates on your PR. Results from workflow CI / buf (pull_request).
|
Dependabot proposed `node:25-alpine`, which fails the image build: /bin/sh: corepack: not found ERROR: failed to solve: process "/bin/sh -c corepack enable && corepack prepare pnpm@9 --activate" did not complete successfully: exit code: 127 Node stopped distributing corepack in v25 (nodejs/node#57617, nodejs/node#59835), and `web.Dockerfile` used it to install pnpm. Retargeting to 24 rather than 25 for two reasons beyond the build. Only even Node majors become LTS: 25 is a Current-only line that reached EOL on 2026-06-01, so it was already unsupported when the bump was proposed. 24 is the newest active-LTS line (LTS 2025-10-28, maintenance 2026-10-20, EOL 2028-04-30), and it is what #1045 moves the CI web lane to — so the image and the lane that typechecks the SPA stay on the same major. Corepack is dropped rather than reinstated with `npm i -g corepack`. Node 24 still ships it, so `corepack enable` would work today, but it is gone from every later line — keeping it just moves this same failure to the next even LTS. `npm install -g pnpm@9` reaches the same pinned pnpm directly, and npm is already in the base image. Also refreshes the dangling `rust:1.95-slim` reference in coordinator.Dockerfile's glibc comment, which the 1.96 bump left behind.
|
Closing this as obsolete —
So the substantive diff here is empty against The dependent also cleared without it: #940 (jsdom 29.1.1 → 30.0.1) merged 2026-08-08, which was the reason this PR existed. The Node floor jsdom 30 needs ( No action needed and nothing to salvage. Deleting the For the record, since this PR is where the Node policy was written down: the next move on this axis is Node 26, and it is not due yet. Per |
Pull request was closed
Prerequisite for the jsdom 30 bump (#940), and a fix for an end-of-life
runtime in its own right.
Why
Node 20 reached end of life on 2026-04-30. The
web (pnpm)lane has beenbuilding and testing the SPA on an unsupported runtime since then.
flake.nixmoves too, sonix developmatches CI instead of sitting on 22.Why 24
Only even Node majors become LTS. From the upstream release schedule:
24 is the newest line in active LTS. 22 is already in maintenance, and 26 is
not LTS until 2026-10-28.
Worth flagging because it comes up in #130: Dependabot proposed
node:25-alpinefor the web image there. 25 is a Current-only line that wasalready EOL when the PR was opened, and it is also where Node stopped
distributing
corepack, which is what breaks that PR's image build. I amhandling that separately on #130 and adding an ignore rule so odd majors stop
being proposed.
What this unblocks
#940 bumps jsdom 29.1.1 → 30.0.1. jsdom 30's only breaking change is a Node
floor raise to
^22.22.2 || ^24.15.0 || >=26.0.0, because it depends onundici 8, which calls
worker_threads.markAsUncloneable— absent on Node 20:pnpm does not enforce
engines(there is noengine-strictanywhere in therepo), so the install succeeds and the violation only surfaces at test runtime.
On Node 20 all 52 vitest files die at worker startup:
node-version: 24resolves the latest 24.x, which satisfies^24.15.0.What a reviewer should look at closely
v20.20.2 and I have no way to install 24 here, so CI is the authority. The
detector puts
test_web=Truefor aci.ymlchange, so the web lane runs onthis PR and is the real check.
docker/web.Dockerfileis deliberately not in this PR. It is Dependabot'sdocker ecosystem and chore(docker): bump the docker-base group across 1 directory with 4 updates #130 already owns that hunk; changing it here would just
conflict. It is still on
node:20-alpineuntil chore(docker): bump the docker-base group across 1 directory with 4 updates #130 lands.orchestrator/andcli/are Bun, andweb/package.jsondeclares no
enginesorpackageManager.After this merges I will re-trigger CI on #940.