Skip to content

Move CI off EOL Node 18 to a single .nvmrc pin (24.22.0 LTS) - #59

Open
coder9io wants to merge 2 commits into
mainfrom
coder9io/issue-58
Open

coder9io wants to merge 2 commits into
mainfrom
coder9io/issue-58

Conversation

@coder9io

@coder9io coder9io commented Oct 21, 2026 •

Copy link
Copy Markdown

Refs the eMudhra blocklist upgrade. This is a partial fix: no Node release contains the blocklist yet.

What

  • Pin development Node to 24.22.0 LTS in .nvmrc: adds .nvmrc as the single Node pin for the repo.
  • ci: read Node version from .nvmrc instead of EOL 18.19.0: actions/setup-node@v2 with node-version: 18.19.0 becomes actions/setup-node@v4 with node-version-file: .nvmrc. Checkout now runs first because setup-node has to read the file.

Why

CI ran Node 18.19.0. The 18.x line is end-of-life and will never get the backport of nodejs/node@d9a3f3d (nodejs/node#66871, merged 2026-10-20T16:43Z).

As of 2026-10-21 the fix is in no published release:

  • The latest releases per nodejs.org/dist/index.json are v26.12.0 (2026-10-14), v24.22.0 (2026-10-14) and v22.23.3 (2026-09-23).
  • GET /repos/nodejs/node/compare/v26.12.0...d9a3f3d returns diverged, so that tag does not contain the fix.

This PR does the migration that doesn't depend on upstream. Once a patched 24.x ships, the remaining bump is a one-line .nvmrc change with no workflow edit.

Node execution surfaces (inventory)

Surface Before After
CI build/test (.github/workflows/build.yml) 18.19.0 (EOL) .nvmrc → 24.22.0
Local development unpinned .nvmrc → 24.22.0
Package publishing manual npm publish, no workflow developer's Node (follows .nvmrc)
Containers / Dockerfiles none none
engines.node none none (left unset; see below)
playground/* demo apps, not in CI, no pins unchanged
Production runtime the customer's app process (library); outbound TLS via undici in src/levitate/events.ts unchanged: customers must upgrade their own Node

I didn't add engines.node. Customers supply the runtime, and npm only warns on engines, so it would not enforce the fix.

TLS evidence (v24.22.0, default verification)

v24.22.0 https://dv-g3b-emudhra.we-have-a-problem.com/ ACCEPTED 200
v24.22.0 https://nodejs.org/ ACCEPTED 307

The compromised chain is still accepted on 24.22.0. That is expected and is why the issue stays open.

Tests

No test is added: this change is version pins only.

Run locally on Node 24.22.0:

  • npm run build passes.
  • npx vitest run tests/express.test.ts tests/enabled.test.ts tests/nestjs passes (12/12).

The MySQL, Prisma and Next.js suites need services and are left to CI, which now runs them on 24.22.0. The PR has 2 commits; the tree passes those tests at each one.

Remaining (before this issue can close)

Bump .nvmrc to the first 24.x release containing d9a3f3d or its official backport, and verify containment from the release notes or tag. Then re-run the TLS probe and expect the eMudhra host to be rejected and a normal host accepted.

Refs #58 (one part; the issue stays open)

Agent usage


Opened by coder9io. Review comments and CI results on this PR are picked up automatically.

Node 18 is end-of-life and will not receive the eMudhra SPKI blocklist
(nodejs/node#66871). Pin the current Active LTS so contributors and CI
share one version; it is bumped to the first 24.x release containing
the blocklist once one is published.
CI pinned Node 18.19.0, an end-of-life line that will never get the
eMudhra intermediate blocklist. Read .nvmrc so CI and local development
share one pin and the follow-up bump to a patched release is a one-line
change outside the workflow. Checkout moves first because setup-node
needs the file; setup-node v4 replaces the deprecated v2.
@coder9io coder9io added urgent Requires urgent attention security Security vulnerability or incident labels Oct 21, 2026

@reviewer9io reviewer9io left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the complete CI/runtime-pin change at d51d0a34871da7aeff24c21127c7a16e049cce57, including checkout/setup ordering and the build/test consumers. No actionable blockers found.

Fresh Node 24.22.0 validation: locked npm ci, CJS/ESM/declaration build, 12 existing Express/Nest/disabled-mode tests, and two added probes passed. The probes verify the workflow pin and deterministic async-label isolation through overlapping requests and rejection. Remote CodeQL checks succeeded.

Limits: MySQL/Prisma integration, Next.js/browser suites, hosted Build execution and live TLS were not run. The library code and lockfile are unchanged. The documented certificate-blocklist follow-up and customer runtime upgrades remain separate from this CI migration.

@nishantmodak

Copy link
Copy Markdown
Member

@coder9io Do not mark this Ready to merge under security issue #58. The library still supports customer runtimes that accept the compromised chain, while this PR only changes development CI to an unpatched release. Wait for official patched releases, define supported fixed engine minima, pin CI to exact versions, run the full test matrix and TLS probe, then publish a remediated package after approval.

@coder9io

Copy link
Copy Markdown
Author

@nishantmodak Question before I continue:

Which Node lines should @last9/openapm support once patched releases ship? This sets the engines.node minima, e.g. ^22.x.y || ^24.x.y || >=26.x.y, or 24+ only. Also, should this PR stay open as draft and be extended then, or be closed in favour of one remediation PR?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Security vulnerability or incident urgent Requires urgent attention

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants