Skip to content

Commit 7d08df6

Browse files
ci(engines): widen engines.node to >=18 in CI to keep Node 18/20 jobs running (#9145)
* ci(engines): widen engines.node to >=18 in CI to keep Node 18/20 jobs running engines.node is bumped to >=22 to match the supported runtime range. The runtime guard (packages/dd-trace/src/guardrails/index.js) and the withVersions test helper both read engines.node and bail when the running major is below it, so on Node 18/20 every suite would silently skip (withVersions returns early, the init guard short-circuits, mocha reports 0 passing). CI widens engines.node back to >=18 at the action level (right after actions/setup-node) via scripts/ci/widen-engines-for-ci.js, so Node 18/20 jobs keep exercising real tests. The on-disk package.json that ships is unchanged (engines.node stays >=22). Co-authored-by: Cursor <cursoragent@cursor.com> * ci(engines): only widen engines.node on Node 18/20 jobs The widen step lives in the shared node/setup action, so it ran on every CI job, including integration-guardrails-unsupported, which installs Node 0.8 through 14 on purpose to verify the runtime guard aborts. Two problems: the script used a node:-prefixed require (unsupported before Node 14.18) so it crashed and failed those jobs, and even had it run, rewriting engines.node there would undermine a test that relies on the shipped >=22. Gate the step in the action so it only runs when the installed major is 18 or 20 (the supported majors the >=22 bump newly excludes). Every other version, including the unsupported matrix, keeps the shipped >=22 and the script is never parsed by a runtime too old to run it. Co-authored-by: Cursor <cursoragent@cursor.com> * ci(node): pin oldest alias to Node 18 instead of deriving from engines.node Commit 1a79e10 (prepare to drop Node 18/20) changed the `oldest` version alias to read the minimum major out of package.json engines.node. With engines.node now bumped to >=22, `oldest` resolved to Node 22, which dropped Node 18 from the matrix and shifted the child_process job's legs to {22,20,24,26}. The resulting leg order (Node 22 first, then 20) destabilized the Bluebird global-Promise tests on the Node 20 leg, which pass on master's {18,20,24,26}. Pin `oldest` back to a literal 18 so CI keeps testing the oldest version we still exercise, decoupled from the shipped engines floor. This restores the matrix and leg order to match master; the widen step still restores >=18 on the 18/20 legs. Co-authored-by: Cursor <cursoragent@cursor.com> * add early return --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2d62430 commit 7d08df6

2 files changed

Lines changed: 55 additions & 2 deletions

File tree

.github/actions/node/setup/action.yml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ runs:
2727
}
2828
case "$VERSION" in
2929
eol) version=16 ;;
30-
oldest) oldest_major=$(awk '/"node"/{match($0,/[0-9]+/);print substr($0,RSTART,RLENGTH);exit}' package.json)
31-
version=$(node_version "$oldest_major") ;;
30+
# Pinned to 18 rather than derived from package.json engines.node: CI keeps testing the
31+
# oldest version we still exercise (18) even though the shipped engines floor is now >=22.
32+
# See the Widen engines.node for CI step below, which restores >=18 on the 18/20 legs.
33+
oldest) version=$(node_version 18) ;;
3234
maintenance) version=$(node_version 20) ;;
3335
active) version=$(node_version 24) ;;
3436
latest) version=${LATEST_VERSION:-$(node_version 26)}
@@ -44,6 +46,22 @@ runs:
4446
node-version: ${{ steps.node-version.outputs.version }}
4547
registry-url: ${{ inputs.registry-url || 'https://registry.npmjs.org' }}
4648

49+
# The shipped package.json pins engines.node to the supported runtime range, but CI keeps
50+
# running the full suite on Node 18/20. Widen the field to >=18 for this checkout so the
51+
# runtime guard and the withVersions test helper don't bail and silently skip those jobs.
52+
# Gate on the major so this never runs on the ancient runtimes the guardrails-unsupported
53+
# job installs (those must keep seeing the shipped >=22 so the guard aborts), and so the
54+
# script is only ever parsed by a Node version new enough to run it.
55+
- name: Widen engines.node for CI
56+
shell: bash
57+
run: |
58+
MAJOR=$(node -e "process.stdout.write(String(parseInt(process.versions.node)))")
59+
if [ "$MAJOR" = "18" ] || [ "$MAJOR" = "20" ]; then
60+
node scripts/ci/widen-engines-for-ci.js
61+
else
62+
echo "Leaving engines.node unchanged on Node $(node -v) (only widened on Node 18/20)."
63+
fi
64+
4765
# Persist the resolved version so subsequent runs within this 60-minute window can reuse it.
4866
- name: Save resolved version
4967
if: steps.node-version-cache.outputs.cache-hit != 'true'

scripts/ci/widen-engines-for-ci.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env node
2+
3+
'use strict'
4+
5+
// CI-only helper. The shipped package.json pins `engines.node` to the supported
6+
// runtime range (`>=22`), but CI still runs the full suite on Node 18 and 20 to
7+
// keep those jobs exercising real tests. The runtime guard
8+
// (packages/dd-trace/src/guardrails/index.js) and the `withVersions` test helper
9+
// both read `engines.node` and bail when the running major is below it, which would
10+
// silently skip every suite on those majors. Widening the field to `>=18` for the
11+
// CI checkout keeps those jobs honest without touching what we publish.
12+
//
13+
// The node/setup action gates this step so it only runs on the supported majors the
14+
// `>=22` bump newly excludes (18 and 20); it is never invoked on the ancient runtimes
15+
// the `integration-guardrails-unsupported` job installs, which must keep seeing the
16+
// shipped `>=22` so the guard aborts.
17+
18+
const fs = require('node:fs')
19+
const path = require('node:path')
20+
21+
const CI_MIN_NODE = '>=18'
22+
23+
const packageJsonPath = path.join(__dirname, '..', '..', 'package.json')
24+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
25+
26+
const before = pkg.engines.node
27+
if (before === CI_MIN_NODE) return
28+
29+
pkg.engines.node = CI_MIN_NODE
30+
const after = pkg.engines.node
31+
32+
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n')
33+
34+
// eslint-disable-next-line no-console
35+
console.log(`Widened engines.node for CI: ${before} -> ${after}`)

0 commit comments

Comments
 (0)