Skip to content

Chore: Bump CI Node.js from 20 to 24 - #7219

Closed
Gykes wants to merge 1 commit into
stashapp:developfrom
Gykes:bump-node-24
Closed

Chore: Bump CI Node.js from 20 to 24#7219
Gykes wants to merge 1 commit into
stashapp:developfrom
Gykes:bump-node-24

Conversation

@Gykes

@Gykes Gykes commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Why

Node 20 is past end-of-life and no longer receives security updates, so CI should move off it.

The generate job in build.yml was the only remaining Node 20 pin. The compiler image that the cross-compile jobs run in has been on node:24-bookworm for a while already (docker/compiler/Dockerfile), so this just brings the one native job in line with the toolchain the rest of the build already uses. Node 24 is the current active LTS.

What changed

  • .github/workflows/build.ymlnode-version: '20''24'
  • ui/v2.5/package.jsonengines.node ">= 20"">= 24"

The engines bump matters as much as the workflow one. With a floor of >= 20, a contributor on a newer Node can use language features the CI runner cannot parse, so the build passes locally and fails only in CI with an error that looks unrelated to their change.

That is not hypothetical — it is currently happening on #7207, where a regex using inline modifier groups ((?i:...)) fails the generate job:

Invalid regular expression: /((?i:3DSVR|T28|...))/: Invalid group
    at new RegExp (<anonymous>)
    at Array.literalRegExp (rollup/dist/es/shared/node-entry.js:16595:22)

Rollup reconstructs regex literals with new RegExp() in the host Node process, so whether the build succeeds depends entirely on the runner's V8 version. Modifier groups landed in V8 12.5, so they parse on Node 23+ and throw on Node 20.

To be clear, this PR does not fix #7207 — that regex has a separate bug and needs changing on its own merits. This only removes the version skew that made the failure confusing.

Testing

Ran the full UI pipeline on a modern Node against current develop:

  • pnpm run check (tsc --noEmit) — clean
  • pnpm run lint (biome + stylelint) — clean
  • pnpm run build (vite) — built in 15.91s

No lockfile or dependency changes; pnpm install --frozen-lockfile resolves unchanged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GoAD2nqsMqbkNGdzSBJJ6q

Node 20 is past end-of-life and is no longer receiving security updates.

The `generate` job was the only place still pinning Node 20; the compiler
image used by the cross-compile jobs has been on node:24-bookworm for a
while (docker/compiler/Dockerfile), so this aligns CI with the toolchain
the rest of the build already uses.

Also raises the `engines` floor in ui/v2.5/package.json to match. The
previous `>= 20` let contributors build locally on a newer Node with
language features the CI runner could not parse, producing failures that
only appeared in CI -- most recently a regex using inline modifier groups
`(?i:...)`, which parse on Node 23+ but throw "Invalid group" on Node 20
when rollup reconstructs the literal at build time.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GoAD2nqsMqbkNGdzSBJJ6q
@Gykes

Gykes commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator Author

sigh you ask CC one question and it goes on a rampage.

@Gykes Gykes closed this Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant