Skip to content

feat(release): take an optional node-version input for every job that sets up Node - #115

Merged
NSchatz merged 1 commit into
mainfrom
ci/release-node-version
Nov 10, 2026
Merged

NSchatz merged 1 commit into
mainfrom
ci/release-node-version

Conversation

@NSchatz

@NSchatz NSchatz commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

What

release.yml takes an optional node-version input: the Node line every job that sets up Node runs on, which is version, release and finalize. Each job's actions/setup-node reads ${{ inputs.node-version || '<the line it ran on before>' }}: 22 in version, 24 in release and finalize. A new step in the version job, The node-version input must be 24 or later, refuses any value that is not a version of Node 24 or later, before setup-node, the install, the tag or the publish. The input reaches setup-node and one env: entry only, never shell text. CHANGELOG.md's Unreleased section and the README caller example say how a caller uses it.

Why

A package whose engines.node starts above 22 has its version job refused by pnpm at pnpm install --frozen-lockfile (ERR_PNPM_UNSUPPORTED_ENGINE) on every push to its main, because that job set up Node 22 with no input to change it. With this, such a caller passes with: { node-version: "24" } and installs, builds and publishes on 24 in all three jobs.

The value is held to 24 or later because the release job publishes on it, and the npm every Node 22 release bundles is below the publish floor (the rule that keeps the release job on Node 24 or later). Checking in the version job stops the run before anything is tagged; release and finalize both need version, so neither runs on a refused value.

Proof

  • New test/release-node-version.test.mjs, on the shared workflow reader: the input is optional with an empty default; every job that sets up Node does so once, from the input, falling back to its old line; the check runs unconditionally and precedes setup-node, pnpm install and release-tag.mjs; release and finalize need version; the input appears only in the three setup-node lines and the one env entry. It also runs the check's own script with bash: empty, 24, 24.18.0, 24.x, v24, v26.1, 26, 30.0.0 pass; 22, 22.14.0, v22, 23.11.1, 8, lts/*, node, latest, >=24, 24, 24; true, 24.1.2.3 are refused.
  • Mutations: one setup-node put back on a literal "24" fails two tests; the check's floor lowered to 22 fails one.
  • test/environment-gate.test.mjs AC11 lists the new input and pins its type and empty default; AC10 records the new suite as reading the workflow through the shared reader.
  • Gate, locally: actionlint 1.7.12 with shellcheck 0.11.0 clean; node --test "test/*.test.mjs" 1208 of 1208 pass; check-no-emdash.mjs OK; package-lists.mjs OK.

Choices

  • A new node-version string input, the same name and shape the gate-* workflows took in the last reference, rather than reading a node-versions list as ci.yml's prepublish does: release.yml has no node-versions input, and adding a list only to read its first entry would be a second spelling of one setting.
  • The default is empty rather than "22" (the gate-* default), because the three jobs ran on two different lines and one literal default would have moved release and finalize off 24. Empty keeps each job exactly where it was, so no caller has to act.
  • A value below 24 is refused rather than applied to version only, so one input means one line for the whole run, and the release job can never be handed a Node whose npm is below the publish floor. Aliases such as lts/* and ranges such as >=24 are refused too, because what they resolve to is not fixed; publish-floor.mjs still checks the real npm at publish time.
  • ci.yml is not touched.

Kind: code

https://claude.ai/code/session_016orFiR8mq7oCYo77QDTw2U

… sets up Node

release.yml set Node up on fixed lines: 22 in the version job, 24 in the
release and finalize jobs. A package whose engines.node starts above 22
has its version job refused by pnpm at pnpm install --frozen-lockfile
(ERR_PNPM_UNSUPPORTED_ENGINE) on every push to main, with no way to ask
for another line.

The new node-version input defaults to empty, which keeps each job on the
line it ran on before, so no caller changes. A value applies to all three
jobs. It must be a version of Node 24 or later, because the release job
publishes on it, and the version job refuses anything else before it sets
Node up, installs, tags or publishes. The input reaches setup-node and
one env entry only, never shell text.

Claude-Session: https://claude.ai/code/session_016orFiR8mq7oCYo77QDTw2U
@NSchatz
NSchatz merged commit 402d4e1 into main Nov 10, 2026
10 checks passed
@NSchatz
NSchatz deleted the ci/release-node-version branch November 10, 2026 04:22
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