chore(ci): move actions to the Node 24 runtime - #279
Open
WaylandYang wants to merge 2 commits into
Open
Conversation
GitHub is forcing Node 20 actions onto Node 24 and warning on every run: 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-python@v5 Bump every versioned action to its current major so the runtime is declared rather than coerced. actions/checkout v4 -> v7 actions/setup-node v4 -> v7 actions/setup-python v5 -> v7 astral-sh/setup-uv v6 -> v9 softprops/action-gh-release v2 -> v3 docker/setup-buildx-action v3 -> v4 docker/login-action v3 -> v4 docker/build-push-action v6 -> v7 Left alone deliberately: `dtolnay/rust-toolchain@stable` and `pypa/gh-action-pypi-publish@release/v1` are branch refs, not version tags, and `Swatinem/rust-cache@v2` is already current (v2.9.1). Checked the majors being crossed for behaviour changes beyond the runtime bump. Three could have bitten us and do not: - setup-node v7 removes the dummy NODE_AUTH_TOKEN export. publish-npm sets NODE_AUTH_TOKEN itself on the publish step, so the .npmrc reference still resolves. - setup-node v5/v6 changed automatic cache detection. Both call sites pass `cache: npm` explicitly, so the new default never applies. - setup-uv v8 dropped the old custom version-manifest format. Not used. One real behaviour change ships with this: setup-uv v9 enables caching by default, which is why upstream marked it breaking. It costs Actions cache storage on the two mcp-python legs. `enable-cache: false` restores the old behaviour if that is not wanted. actionlint reports no findings across all six workflows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The first attempt used `astral-sh/setup-uv@v9`, which failed to resolve: Unable to resolve action `astral-sh/setup-uv@v9`, unable to find version `v9` setup-uv published floating major tags through v7 but stopped from v8 onward — only exact `vX.Y.Z` tags exist now. Pin the exact release. Checked every other bumped ref against the GitHub refs API rather than assuming the major alias exists. All of them resolve, including the four in release.yml and the publish workflows that a pull request cannot exercise: action-gh-release@v3, docker/setup-buildx-action@v4, docker/login-action@v4, docker/build-push-action@v7. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Every workflow run currently carries this annotation:
Nothing is broken today — GitHub is coercing the runtime — but the coercion is temporary and the warning is on every run. This declares the runtime instead.
What moved
actions/checkoutactions/setup-nodeactions/setup-pythonastral-sh/setup-uvsoftprops/action-gh-releasedocker/setup-buildx-actiondocker/login-actiondocker/build-push-actionTarget versions came from each action's latest GitHub release rather than from memory.
Three are deliberately untouched:
dtolnay/rust-toolchain@stableandpypa/gh-action-pypi-publish@release/v1are branch refs, not version tags — there is no major to bump.Swatinem/rust-cache@v2is already current; its latest release is v2.9.1.setup-uvis the one pinned to an exact release rather than a major. It published floating major tags through v7 and stopped from v8 onward, so@v9does not exist — the first push of this PR used it and CI failed to resolve the action. There is a comment inci.ymlnoting why that line differs from the rest.Every ref in this PR has since been checked against the GitHub refs API, including the four that a pull request cannot exercise:
action-gh-release@v3,docker/setup-buildx-action@v4,docker/login-action@v4,docker/build-push-action@v7. All resolve. That rules out the one failure mode that actually occurred here, in the workflows where it would otherwise have surfaced during a release.Breaking changes across the majors being crossed
Most of these majors are only the node20 → node24 runtime move, which is the point of the PR. I read the release notes for each major being skipped to find anything else. Three had real behaviour changes, and none of them bite here:
setup-nodev7 removes the dummyNODE_AUTH_TOKENexport. This is the one that could have silently broken npm publishing.publish-npm.ymlsetsNODE_AUTH_TOKENitself on the publish step (line 45), so the.npmrcreference written byregistry-urlstill resolves. Had it relied on the action's export, releases would have started failing atnpm publishwith no CI signal beforehand.setup-nodev5 added automatic package-manager cache detection; v6 narrowed it to npm. Both call sites passcache: 'npm'explicitly, so the changed default never applies.setup-uvv8 removed the old custom version-manifest format. Not used here.One behaviour change that does ship
setup-uvv9 enables caching by default — that is why upstream marked it breaking, and the stated concern is Actions cache usage and therefore cost. It affects the twomcp-pythonmatrix legs. I kept the new default rather than pinning the old behaviour, since these jobs are short and the cache should help more than it costs, butenable-cache: falserestores the previous behaviour if you would rather not take it.Verification
rustcheck on this branch reports zero annotations; the equivalent run onmainstill carries the Node.js 20 warning. That is the whole point of the PR, confirmed rather than assumed.setup-node@v7still installs the older Node versions the TypeScript SDK is tested against.actionlintreports no findings across all six workflows. Worth noting it did not catch thesetup-uv@v9problem — it validates schema and expressions, not whether a ref exists upstream. CI caught that one.Residual risk.
release.yml,publish-npm.yml,publish-pypi.ymlandpublish-pypi-mcp.ymlfire on tags or release events, so a pull request cannot run them. Ref resolution for those is now verified against the API, and the compatibility notes above cover the behaviour changes, but the first real proof is the next release. If you would rather not carry even that, splitting the four release workflows into a follow-up and landing only the CI ones here is a reasonable trade.🤖 Generated with Claude Code