Repository navigation
CI: actions on the Node 24 runtime; Node 22 or later - #55
Merged
jallers merged 2 commits intoNov 14, 2026
Merged
Conversation
Every CI and publish run now ends with a runner warning: "Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v4, actions/setup-node@v4, actions/upload-artifact@v4." The v4 majors declare `runs.using: node20`; the current majors (checkout v5+, setup-node v5+, upload-artifact v6+) declare node24, and all three are at v7. Both workflows move to v7. What changed between the majors crossed, checked against each action's action.yml and release notes: - checkout: inputs identical; v7 refuses a fork checkout under pull_request_target/workflow_run unless allow-unsafe-pr-checkout is set. CI runs on pull_request, so nothing changes. - setup-node: `cache: npm` is unchanged. v5 added automatic caching when package.json names a packageManager (it does not here); v7 no longer exports a dummy NODE_AUTH_TOKEN. npm 11.19 `npm ci` with the action's .npmrc and no NODE_AUTH_TOKEN was tested and works, and the stage step sets the variable itself as before, so trusted publishing is unaffected. publish.yml now sets package-manager-cache: false, as the action's trusted-publishing guide asks. - upload-artifact: v5 only bumped @actions/artifact, v6 moved to node24, v7 added an `archive` input that defaults to true. name/path are the same; the artifact is a zip as before. All three need runner 2.327.1 or later; the hosted runners are on 2.338.2. Node 24 has shipped npm 11.16 or later since 24.18.0, so `npm stage`'s floor (11.15) is met by setup-node alone; the explicit npm install stays as a guard against a lagging toolcache. Node floor: engines.node is now >=22 (was >=18). Node 18 reached end of life in April 2025 and Node 20 in April 2026. The matrix tests the maintained LTS lines, 22, 24 and 26, instead of 20, 22, 24. CHANGELOG records it as a breaking change for the next alpha. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016NSWj8b7T4dcswUnPdzYuv
tsup's target follows engines.node (node22, was node18), so the emitted syntax floor matches the claim; CHANGELOG's breaking line says so. 1.0.0-alpha.5 was published and tagged latest on 2026-11-14, so its heading loses "(unreleased)". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016NSWj8b7T4dcswUnPdzYuv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Does it make sense to point at new versions of the actions?
Yes, and it is low-risk: the runner is already executing the v4 actions on Node 24, it just complains about it on every run. Both the last CI run and the alpha.5 publish run end with this annotation (verbatim from the job logs of run 43599081847 and run 43594916940):
So moving to the majors that declare
node24themselves changes nothing about the runtime the code runs on today; it stops the warning and stops depending on the runner's forcing. The hosted runners are on 2.338.2; every bumped major needs 2.327.1 or later.What each action's own
action.ymland release notes sayruns.usingby majornode20; v5, v6, v7node24pull_request_target/workflow_rununlessallow-unsafe-pr-checkout: true(also backported to v4.4.0: the current runs already logallow-unsafe-pr-checkout: false). Input list v4 → v7 is otherwise identical. CI triggers onpull_request, so nothing changes.node20; v5, v6, v7node24package.jsonhas apackageManagerfield (ours has none), opt out withpackage-manager-cache: false. v6.0.0: automatic caching limited to npm; v6.1.0 dropped thealways-authinput and thealways-auth=line in.npmrc(npm 11 warns about that line on every command today). v7.0.0: ESM,cache-primary-key/cache-matched-keyoutputs, and no more dummyNODE_AUTH_TOKENexport (PR #1558, see below). Thecache: npminput is unchanged.node20; v6, v7node24@actions/artifact; v6.0.0 moved to node 24 (its notes: v5 "was by default still running on Node.js 20"), runner ≥ 2.327.1; v7.0.0 added anarchiveinput, defaulttrue, soname/pathbehave as before and the artifact is still a zip. Input list v4 → v7 differs only byarchive.Pinned by major tag, as before (the repo does not pin SHAs).
Trusted publishing after the bump
id-token: writeandenvironment: npmare untouched; the OIDC exchange is npm's, not the action's.NODE_AUTH_TOKEN:empty (noNPM_TOKENsecret is set) and staged with provenance via OIDC. That step sets the variable itself, so it is unaffected by setup-node v7 no longer exporting the placeholderXXXXX-XXXXX-XXXXX-XXXXXfor the other steps.npm install -g,npm ci,npm run verify) will now run with the action's.npmrc(//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}) and the variable unset. Tested locally with npm 11.19.1:npm cisucceeds with it unset and with it empty (npm 11 leaves an unknown${VAR}as-is; public reads do not need auth).npm stageneeds 11.15. Node 24 has shipped npm 11.16 or later since 24.18.0 (June 2026); the runner's toolcache gives 24.22.2 with npm 11.19.1. The explicitnpm install -g npm@^11.15.0stays as a guard against a lagging toolcache.package-manager-cache: falseto the publish job, as setup-node's trusted-publishing guide asks (no cache restore in the job that holds the OIDC token). It is a no-op today becausepackage.jsonhas nopackageManagerfield.Node floor: recommendation, Jim decides
Recommended and done in this PR:
engines.node>=22, matrix 22 / 24 / 26 on ubuntu, 24 on windows,tsuptargetnode22so the emitted syntax floor follows the claim, and a### Breakingline under a new1.0.0-alpha.6 (unreleased)CHANGELOG heading. The alpha.5 heading loses "(unreleased)": it is on npm aslatestsince 2026-11-14.Why 22 rather than keeping 20 or going to 24:
>=18promises support for two lines that get no security fixes, and testing 20 keeps a dead line in the matrix.>=22excludes nobody;>=24would exclude gh-v1's floor for no gain.package.json,README.md,tsup.config.tsand the alpha.6 CHANGELOG entry, and put 20 back in the matrix; the workflow bump stands on its own.Checks
npm run verifylocally: typecheck, build, 24 files / 168 tests pass (Node 22.23.4), with thenode22target; the CommonJS test passes on its own too.🤖 Generated with Claude Code
https://claude.ai/code/session_016NSWj8b7T4dcswUnPdzYuv