ci(plugin-ci): default to the Node plugins actually run on (20 → 24) - #35
Conversation
Node 20 reached end-of-life on 2026-04-30. No plugin repo overrides `node-version`, so all seven have been testing on an unsupported runtime for four months. Worse, 20 was never the right number. The host spawns out-of-process plugins as `process.execPath` -- the Electron binary -- under ELECTRON_RUN_AS_NODE=1, so a plugin's Node IS Electron's bundled Node. Measured directly on the host's Electron 43: node 24.17.0. CI was testing four majors below production, which means a green suite could not answer the question anyone actually has. The gap had already blocked work: jsdom 30 pulls undici 8, which calls `worker_threads.markAsUncloneable` (Node 22+). Production has it; only CI did not, so lvis-plugin-ep's Dependabot bump failed on a runtime no user runs. Proven before flipping: lvis-plugin-ep#226 pinned node-version: '24' for one repo and changed nothing else. The run installed v24.19.0 and the full suite passed in 41s on the same self-hosted runner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017EbNct32BA3E96EER8Y1eE
|
Correction to the PR body: this moves 6 repos, not 7.
Worth recording how the wrong number got in: my first sweep queried |
What
plugin-ci.ymlnode-versiondefault:'20'→'24'. One line, plus the comment recording why the number is what it is.No plugin repo overrides this input, so this moves all 7 at once — which is exactly why it was proven on one repo first.
Why
'20'was wrong on two independent axesIt is end-of-life. Per
nodejs/Release/schedule.json, v20 maintenance ended 2026-04-30. Four months of plugin CI has run on an unsupported runtime.It was never the right number. The host spawns out-of-process plugins as
process.execPath— the Electron binary — underELECTRON_RUN_AS_NODE=1(lvis-app/src/plugins/isolation/out-of-process-plugin.ts). A plugin's Node is Electron's bundled Node. Measured on the host's Electron 43 rather than read off a table:So CI was testing four majors below production. A green suite on 20 could not answer whether the plugin works where it runs.
This already cost real work
lvis-plugin-epDependabot #194 (jsdom 29 → 30) fails CI withTypeError: webidl.util.markAsUncloneable is not a function. jsdom 30 → undici 8 →worker_threads.markAsUncloneable, added in Node 22. Production has it. Only CI did not — the bump passed locally on Node 26 the whole time. A dependency was blocked by the test environment rather than by the code, and the red check was describing a runtime no user has.Proof before the flip
lvis-project/lvis-plugin-ep#226pinnednode-version: '24'for one repo and changed nothing else, so its result is evidence about the Node and not about anything bundled with it:ci / build-testpass, 41s, same self-hosted runnerAcquiring 24.19.0 - arm64 …→node: v24.19.0That last check matters: a
with:block that gets ignored produces a green run too. The number had to be read back out of the run.After this merges
CIon each plugin repo'smainand confirm all 7 are green on Node 24.'24'the override merely restates it, and an override that restates the default is how a stale pin outlives its reason.Maintenance
The comment ties the number to the host's Electron, not to "latest LTS". When lvis-app moves Electron majors, re-read Electron's bundled Node and move this with it.