Bumps the pre-baked Woodpecker CI base image (Dockerfile.ci) from node:22-alpine to node:24-alpine (Active LTS). Comments in ci.yml/publish.yml updated for accuracy. No other behavior change.
Why now
This is the planned follow-up to the CI cache work (#635 consumer / #637 producer), deliberately sequenced after caching landed so the runtime-version change carries zero cache variables — if anything regresses, it's unambiguously the node bump, not the cache.
node:26 is intentionally held until it reaches LTS (Oct 2026): the Current line risks node-gyp native-module breakage on the musl runner, which compiles better-sqlite3, canvas, sharp, and node-pty from source.
Validation
⚠️ Note: ci-image.yml only rebuilds ci-base on push to main (Dockerfile.ci path filter) or tag — not on PRs — so this PR's own pipeline still pulls the existing node:22 image and does not exercise node:24. To avoid a blind merge, node:24-alpine was validated locally by building Dockerfile.ci and running the real pnpm install --frozen-lockfile --prefer-offline (compiling all native modules) on node:24-alpine + musl. On merge, the path filter triggers a fresh ci-base build and the next pipeline runs on node:24.
## What
Bumps the pre-baked Woodpecker CI base image (`Dockerfile.ci`) from `node:22-alpine` to `node:24-alpine` (Active LTS). Comments in `ci.yml`/`publish.yml` updated for accuracy. No other behavior change.
## Why now
This is the planned follow-up to the CI cache work (#635 consumer / #637 producer), deliberately sequenced **after** caching landed so the runtime-version change carries zero cache variables — if anything regresses, it's unambiguously the node bump, not the cache.
`node:26` is intentionally **held** until it reaches LTS (Oct 2026): the Current line risks node-gyp native-module breakage on the musl runner, which compiles `better-sqlite3`, `canvas`, `sharp`, and `node-pty` from source.
## Validation
⚠️ Note: `ci-image.yml` only rebuilds `ci-base` on **push to main** (Dockerfile.ci path filter) or tag — **not on PRs** — so this PR's own pipeline still pulls the existing node:22 image and does *not* exercise node:24. To avoid a blind merge, node:24-alpine was validated locally by building `Dockerfile.ci` and running the real `pnpm install --frozen-lockfile --prefer-offline` (compiling all native modules) on node:24-alpine + musl. On merge, the path filter triggers a fresh ci-base build and the next pipeline runs on node:24.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Follow-up to the CI cache work (#635/#637), sequenced separately so the
runtime-version change carries zero cache variables. node:24 is Active
LTS; node:26 is held until it reaches LTS (Oct 2026) since the Current
line risks node-gyp native-module breakage (better-sqlite3, canvas,
sharp, node-pty compile from source on the musl runner).
Only Dockerfile.ci's base changes; ci.yml/publish.yml comments updated
for accuracy. The ci-base image rebuilds automatically on merge (the
Dockerfile.ci path filter in ci-image.yml).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
Bumps the pre-baked Woodpecker CI base image (
Dockerfile.ci) fromnode:22-alpinetonode:24-alpine(Active LTS). Comments inci.yml/publish.ymlupdated for accuracy. No other behavior change.Why now
This is the planned follow-up to the CI cache work (#635 consumer / #637 producer), deliberately sequenced after caching landed so the runtime-version change carries zero cache variables — if anything regresses, it's unambiguously the node bump, not the cache.
node:26is intentionally held until it reaches LTS (Oct 2026): the Current line risks node-gyp native-module breakage on the musl runner, which compilesbetter-sqlite3,canvas,sharp, andnode-ptyfrom source.Validation
⚠️ Note:
ci-image.ymlonly rebuildsci-baseon push to main (Dockerfile.ci path filter) or tag — not on PRs — so this PR's own pipeline still pulls the existing node:22 image and does not exercise node:24. To avoid a blind merge, node:24-alpine was validated locally by buildingDockerfile.ciand running the realpnpm install --frozen-lockfile --prefer-offline(compiling all native modules) on node:24-alpine + musl. On merge, the path filter triggers a fresh ci-base build and the next pipeline runs on node:24.🤖 Generated with Claude Code