Skip to content

Run the Node 22.13.0 engines floor in a separate CI job - #7

Merged
bdruth merged 1 commit into
mainfrom
bead/myusage-60f
Sep 20, 2026
Merged

bdruth merged 1 commit into
mainfrom
bead/myusage-60f

Conversation

@bdruth

@bdruth bdruth commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

What changed and why

  • Adds a verify-node-floor job to .github/workflows/ci.yml. It runs corepack enable, yarn install --immutable and yarn test on Node 22.13.0.
  • package.json says engines.node >=22.13.0, but CI only ran Node 22 latest, so nothing exercised the floor.
  • yarn test is the coverage gate, so the floor now has to hit 100% per file too.
  • verify, release, permissions and concurrency are untouched. The diff is 19 added lines and none removed.

Decisions to look at

Decision What I did Cost or alternative
Separate job, not a matrix Left verify alone and added verify-node-floor A matrix renames the checks to verify (22) and verify (22.13.0). main requires one named exactly verify, so it would never report and every PR would block. Cost: the floor job isn't required, so a red floor won't block a merge.
Floor steps: install and test only Left typecheck, lint and check:package to verify tsc and biome are native binaries behind a Node launcher, and check:package only builds and lists the package. All three gave identical output on 22.13.0 and 26.8.2, so running them on the floor would cost CI minutes and probably tell us nothing new.
Dev tools vs the floor Read the engines field of the 76 installed packages vite and vitest accept 22.13.0 (both need 22.12.0 or later on the 22 line), and coverage-v8 declares none. Six transitive packages (node-gyp, nopt, abbrev, proc-log, which, undici) want a newer Node, but they only hang off macOS-only fsevents, and they installed fine on 22.13.0 here. Nothing blocks the floor.
Exact pin node-version: "22.13.0", with a comment to keep it equal to engines.node Manual sync whenever engines.node moves.
Release job Unchanged, still needs: verify A red floor won't block a tag release. Wiring the floor into needs or branch protection is a separate call.

Verified

Local runs on macOS arm64 with the official Node 22.13.0 tarball from nodejs.org, sha256 checked against its SHASUMS256.txt, used inside the worktree and deleted afterwards. Same commit throughout, a fresh node_modules per Node, HOME and XDG dirs sandboxed, CI=true.

Floor steps on Node v22.13.0:

$ corepack enable            exit 0
$ yarn install --immutable   exit 0   (yarn.lock unchanged)
$ yarn typecheck             exit 0
$ yarn lint                  exit 0   (Checked 29 files. No fixes applied.)
$ yarn test                  exit 0
$ yarn check:package         exit 0   (check-package: OK - 9 files in dist/, 12 in the npm package, none are test or support files)

yarn test coverage summary, same commit on both Nodes (8 files, 148 tests, passing on both):

Metric Node 22.13.0 Node 26.8.2 (this machine)
Statements 100% (237/237) 100% (237/237)
Branches 100% (197/197) 100% (197/197)
Functions 100% (44/44) 100% (44/44)
Lines 100% (208/208) 100% (208/208)

Identical totals, so coverage doesn't vary between these two versions. The only output difference is that 22.13.0 prints the node:sqlite ExperimentalWarning.

Negative check, one release below the floor: Node 22.12.0 (same checksum routine), running vitest run --coverage directly:

Error: No such built-in module: node:sqlite
Test Files  1 failed | 7 passed (8)
Statements   : 74.68% ( 177/237 )
Branches     : 77.66% ( 153/197 )
Functions    : 70.45% ( 31/44 )
Lines        : 75% ( 156/208 )
exit 1

Source for the boundary: Node's v22.13.0 changelog lists "unflag sqlite module" (nodejs/node#55890), and the v22.12.0 docs still gate it behind --experimental-sqlite.

Workflow checks:

$ actionlint .github/workflows/ci.yml     exit 0 (actionlint 1.7.12)
jobs after: verify, verify-node-floor, release
release: needs=verify, same if and permissions
ci.yml minus the added block == HEAD:     byte for byte identical
git diff --stat: 1 file changed, 19 insertions(+)
package.json, yarn.lock, vitest.config.ts: unchanged
guardrail-scan.sh staged and tree:        no leaks found, denylist applied, exit 0

First run on GitHub (run 35486171971, commit a9fa525):

verify              pass      same name as before
verify-node-floor   pass      setup-node acquired Node 22.13.0 (x64), log prints "node: v22.13.0"
leak-scan           pass
release             skipped   tag pushes only

In the floor job's log: install took 7s, yarn test ran 8 files and 148 tests, printed the node:sqlite ExperimentalWarning, and the coverage table shows 100% on each of the 7 source files.

Test review

No tests were added or changed, so no test review ran.

Not verified

  • One GitHub run so far. I haven't seen a re-run, or a run on a tag push.
  • I didn't read branch protection. The verify and leak-scan requirement comes from the task brief.
  • I didn't check whether Yarn fetches the node-gyp tree on ubuntu (77 packages added there, 78 on macOS). The install passed either way.

AI leveraged

AI leveraged:

  • Plan: Sonnet 5 via Claude Code (bead-drain loop orchestrator)
  • Implement: Sonnet 5 via Claude Code (single pipeline worker; this unit has no separate stages)
  • Review: Sonnet 5 via Claude Code (orchestrator re-runs build, tests and CI checks independently before the bead moves to review)
  • Human-written code: none

Tracked under bead myusage-60f

🤖 Generated with Claude Code

package.json requires node >=22.13.0 but CI only tested Node 22 latest.
Add a verify-node-floor job (install + the coverage gate) pinned to 22.13.0.

It is a separate job, not a matrix on verify: main requires a check named
exactly "verify", and a matrix would rename it to "verify (22)".
@bdruth
bdruth merged commit baa7f2d into main Sep 20, 2026
4 checks passed
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