Skip to content

Stop offering Node majors that are not LTS - #326

Merged
Serraniel merged 1 commit into
mainfrom
ci/node-major-policy
Oct 21, 2026
Merged

Serraniel merged 1 commit into
mainfrom
ci/node-major-policy

Conversation

@Serraniel

Copy link
Copy Markdown
Owner

#323 is not a failing upgrade. It is a downgrade that the gate caught.

Node 25 has been end of life since June

From the node release schedule, which is
the authority rather than a guess:

Node became LTS maintenance end of life today, 2026-10-21
24 2025-10-28 2026-10-20 2028-04-30 LTS, in maintenance since yesterday
25 never 2026-04-01 2026-06-01 EOL for four months
26 2026-10-28 2027-10-20 2029-04-30 LTS in seven days

So #323 proposes a tag that is numerically newer and has a support window four
months shorter than the one it replaces. Odd-numbered Node majors never become
LTS at all.

scripts/check-toolchains.sh failed it in 12 seconds:

Dockerfile builds the client with Node 25; the workflows name 24

That is the gate working. Dependabot can only edit the Dockerfile, so the
only way to make #323 green was to raise NODE_VERSION to 25 everywhere — that
is, to adopt an unsupported runtime deliberately. I have not done that, and
#323 should be closed rather than fixed.

Why the Node major is not a free choice

The release builds the client twice: once on a runner to produce the signed
asset manifest, once inside the Dockerfile to produce the image. A bundler on
two different majors emits two different sets of content-hashed filenames.
v0.2.0 shipped exactly that, and sendan verify reported the project's own
image as not serving the published client — because it was not. See #260.

This is the third time

The rule was right both earlier times. It lived only in a commit message, which
is why the question came back.

The change

node majors are ignored in .github/dependabot.yml. Digest updates are
not, so security patches for the pinned line keep arriving by themselves —
only the major becomes a deliberate edit, and check-toolchains.sh already
forces all three references to move together.

CONTRIBUTING.md gains a Node versions section beside the Go one: the line
must be LTS on the day it is adopted, odd majors never qualify, and the schedule
is the authority.

docs/workflows/dependabot.md gains the general case it was missing. It
documented which dependencies are kept out of groups, which are forced into
them, and the overrides — but said nothing about what is ignored, so the
typescript pin from #93 was undocumented as well.

⚠️ The cost, stated plainly: nothing now raises the next Node major on its
own. That is the trade for not being offered a wrong answer every Monday. #325
carries it with the date — Node 26 becomes LTS on 2026-10-28, seven days from
now, and the issue lists what to verify, including that the content-hashed
filenames match between the two build paths.

Verified

check-toolchains.sh and check-workflows.py pass, and the ignore entry parses
as a single rule against node alone, leaving golang and the digest updates
untouched.

🤖 Generated with Claude Code

#323 proposed node:24-alpine to node:25-alpine. Node 25 reached end of life on
2026-06-01, four months ago; Node 24 is LTS and supported until 2028-04-30. The
tag is newer and the support window is shorter, so the bump was a downgrade
wearing an upgrade's title.

check-toolchains.sh caught it, as designed - the Dockerfile said 25 while the
workflows said 24 - and the pull request could not have been made green
honestly. Dependabot can only edit the Dockerfile, so the only way to pass was
to adopt 25 everywhere, which is the thing not to do.

This had already been decided once. bbcff84 took Node 24 over Dependabot's 26
in #278 because a toolchain that produces released artefacts belongs on a line
that is LTS today rather than in four weeks, and #165 merged Current before
that and had to be undone. The reasoning existed only in a commit message,
which is why the question came back a third time.

So: `node` majors are ignored, and digest updates are not, which leaves
security patches for the pinned line arriving on their own while the major
becomes a deliberate change. CONTRIBUTING.md gains the rule next to the Go
version section - the line must be LTS on the day it is adopted, odd-numbered
majors never become LTS, and the node release schedule is the authority rather
than a guess. docs/workflows/dependabot.md gains the general case, since it
documented grouping and overrides and said nothing about what is ignored, so
the typescript pin from #93 was undocumented too.

The cost is that nothing now raises the next major on its own. #325 carries it
with the date: Node 26 becomes LTS on 2026-10-28.

Verified: check-toolchains.sh and check-workflows.py pass, and the ignore entry
parses as one rule against `node` alone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Serraniel <mail@serraniel.dev>
@Serraniel
Serraniel merged commit 8e3a3db into main Oct 21, 2026
15 checks passed
@Serraniel
Serraniel deleted the ci/node-major-policy branch October 21, 2026 19:57
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