Skip to content

Commit 1a79e10

Browse files
rochdevclaude
andauthored
ci: prepare infrastructure for dropping Node.js 18/20 in v6 (#9033)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 48609bd commit 1a79e10

10 files changed

Lines changed: 78 additions & 23 deletions

File tree

.github/actions/node/action.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ runs:
1818
- if: steps.attempt.outcome == 'failure'
1919
shell: bash
2020
run: sleep 60
21-
- if: steps.attempt.outcome == 'failure'
21+
- id: retry
22+
if: steps.attempt.outcome == 'failure'
2223
uses: ./.github/actions/node/setup
2324
with:
2425
version: ${{ inputs.version }}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ runs:
2727
}
2828
case "$VERSION" in
2929
eol) version=16 ;;
30-
oldest) version=$(node_version 18) ;;
30+
oldest) oldest_major=$(awk '/"node"/{match($0,/[0-9]+/);print substr($0,RSTART,RLENGTH);exit}' package.json)
31+
version=$(node_version "$oldest_major") ;;
3132
maintenance) version=$(node_version 20) ;;
3233
active) version=$(node_version 24) ;;
3334
latest) version=${LATEST_VERSION:-$(node_version 26)}

.github/workflows/apm-integrations.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ jobs:
5858
aerospike-version: ce-6.4.0.3
5959
image: aerospike@sha256:f268d48f5075010ff268b29fbae28518418070dfb31935daa31f0b45c59f4da9 # ce-6.4.0.3
6060
test-image: ubuntu-latest
61+
6162
runs-on: ${{ matrix.test-image }}
6263
permissions:
6364
id-token: write
@@ -332,7 +333,7 @@ jobs:
332333
- "^3.0.7"
333334
- ">=4.0.0 <4.2.0"
334335
include:
335-
- node-version: 18
336+
- node-version: oldest
336337
range: ">=4.2.0"
337338
runs-on: ubuntu-latest
338339
permissions:
@@ -1122,7 +1123,7 @@ jobs:
11221123
- node-version: 18
11231124
range: ">=6.1.0 <7.0.0"
11241125
range_clean: gte.6.16.0.and.lt.7.0.0
1125-
- node-version: "latest"
1126+
- node-version: latest
11261127
range: ""
11271128
range_clean: all
11281129
runs-on: ubuntu-latest

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
18
1+
22

integration-tests/init.spec.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const telemetryAbort = ['abort', 'reason:incompatible_runtime', 'abort.runtime',
1414
const telemetryForced = ['complete', 'injection_forced:true']
1515
const telemetryGood = ['complete', 'injection_forced:false']
1616

17-
const { engines } = require('../package.json')
17+
const { engines, nodeMaxMajor: MAX_NODE_MAJOR } = require('../package.json')
1818
const {
1919
runAndCheckWithTelemetry: testFile,
2020
useEnv,
@@ -122,15 +122,15 @@ function testRuntimeVersionChecks (arg, filename) {
122122
it('should be able to use the engines field', () => {
123123
const engines = require(`${sandboxCwd()}/node_modules/dd-trace/package.json`).engines.node
124124

125-
assert.match(engines, /^>=\d+ <\d+$/)
125+
assert.match(engines, /^>=\d+$/)
126126
})
127127

128-
context('when node version is too recent', () => {
128+
context('when node version is too old', () => {
129129
useEnv({ NODE_OPTIONS })
130130

131131
before(() => {
132132
const pkg = JSON.parse(pkgStr)
133-
pkg.engines.node = `>=${NODE_MAJOR - 1} <${NODE_MAJOR}`
133+
pkg.engines.node = `>=${NODE_MAJOR + 1}`
134134
fs.writeFileSync(pkgPath, JSON.stringify(pkg))
135135
})
136136

@@ -151,14 +151,14 @@ function testRuntimeVersionChecks (arg, filename) {
151151
it('should not initialize the tracer', () =>
152152
doTest(`Aborting application instrumentation due to incompatible_runtime.
153153
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
154-
>=${NODE_MAJOR - 1} <${NODE_MAJOR}.
154+
>=${NODE_MAJOR + 1} <${MAX_NODE_MAJOR}.
155155
false
156156
`, telemetryAbort))
157157

158158
it('should initialize the tracer, if DD_INJECT_FORCE', () =>
159159
doTestForced(`Aborting application instrumentation due to incompatible_runtime.
160160
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
161-
>=${NODE_MAJOR - 1} <${NODE_MAJOR}.
161+
>=${NODE_MAJOR + 1} <${MAX_NODE_MAJOR}.
162162
DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.
163163
Application instrumentation bootstrapping complete
164164
true
@@ -167,12 +167,12 @@ true
167167
})
168168
})
169169

170-
context('when node version is too old', () => {
170+
context('when node version is too recent', () => {
171171
useEnv({ NODE_OPTIONS })
172172

173173
before(() => {
174174
const pkg = JSON.parse(pkgStr)
175-
pkg.engines.node = `>=${NODE_MAJOR + 1} <${NODE_MAJOR + 2}`
175+
pkg.nodeMaxMajor = NODE_MAJOR
176176
fs.writeFileSync(pkgPath, JSON.stringify(pkg))
177177
})
178178

@@ -193,14 +193,14 @@ true
193193
it('should not initialize the tracer', () =>
194194
doTest(`Aborting application instrumentation due to incompatible_runtime.
195195
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
196-
>=${NODE_MAJOR + 1} <${NODE_MAJOR + 2}.
196+
${engines.node} <${NODE_MAJOR}.
197197
false
198198
`, telemetryAbort))
199199

200200
it('should initialize the tracer, if DD_INJECT_FORCE', () =>
201201
doTestForced(`Aborting application instrumentation due to incompatible_runtime.
202202
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
203-
>=${NODE_MAJOR + 1} <${NODE_MAJOR + 2}.
203+
${engines.node} <${NODE_MAJOR}.
204204
DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.
205205
Application instrumentation bootstrapping complete
206206
true
@@ -215,7 +215,8 @@ true
215215

216216
before(() => {
217217
const pkg = JSON.parse(pkgStr)
218-
pkg.engines.node = '>=0 <1000'
218+
pkg.engines.node = '>=0'
219+
pkg.nodeMaxMajor = 1000
219220
fs.writeFileSync(pkgPath, JSON.stringify(pkg))
220221
})
221222

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@
131131
},
132132
"homepage": "https://github.com/DataDog/dd-trace-js#readme",
133133
"engines": {
134-
"node": ">=18 <27"
134+
"node": ">=18"
135135
},
136+
"nodeMaxMajor": 27,
136137
"files": [
137138
"/package.json",
138139
"ci/**/*",

packages/dd-trace/src/guardrails/index.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ function guard (fn) {
1414
var initBailout = false
1515
var clobberBailout = false
1616
var forced = isTrue(process.env.DD_INJECT_FORCE)
17-
var engines = require('../../../../package.json').engines
18-
var versions = engines.node.match(/^>=(\d+) <(\d+)$/)
17+
var pkg = require('../../../../package.json')
18+
var engines = pkg.engines
19+
var versions = engines.node.match(/^>=(\d+)$/)
1920
var minMajor = versions[1]
20-
var nextMajor = versions[2]
21+
var nextMajor = pkg.nodeMaxMajor
2122
var version = process.versions.node
23+
var supportedRange = engines.node + ' <' + nextMajor
2224

2325
if (process.env.DD_INJECTION_ENABLED) {
2426
// If we're running via single-step install, and we're in the app's
@@ -45,16 +47,17 @@ function guard (fn) {
4547
// should not initialize the tracer.
4648
if (!clobberBailout && (NODE_MAJOR < minMajor || NODE_MAJOR >= nextMajor)) {
4749
initBailout = true
50+
var runtimeInfo = 'Incompatible runtime Node.js ' + version + ', supported runtimes: Node.js ' + supportedRange
4851
telemetry([
4952
{ name: 'abort', tags: ['reason:incompatible_runtime'] },
5053
{ name: 'abort.runtime', tags: [] }
5154
], undefined, {
5255
result: 'abort',
5356
result_class: 'incompatible_runtime',
54-
result_reason: 'Incompatible runtime Node.js ' + version + ', supported runtimes: Node.js ' + engines.node
57+
result_reason: runtimeInfo
5558
})
5659
log.info('Aborting application instrumentation due to incompatible_runtime.')
57-
log.info('Found incompatible runtime Node.js %s, Supported runtimes: Node.js %s.', version, engines.node)
60+
log.info('Found incompatible runtime Node.js %s, Supported runtimes: Node.js %s.', version, supportedRange)
5861
if (forced) {
5962
log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
6063
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict'
2+
3+
const assert = require('node:assert/strict')
4+
const { after, before, describe, it } = require('mocha')
5+
const proxyquire = require('proxyquire')
6+
7+
const { NODE_MAJOR } = require('../../../../version')
8+
9+
describe('guard', () => {
10+
let originalInjectionEnabled
11+
12+
before(() => {
13+
originalInjectionEnabled = process.env.DD_INJECTION_ENABLED
14+
delete process.env.DD_INJECTION_ENABLED
15+
})
16+
17+
after(() => {
18+
if (originalInjectionEnabled !== undefined) {
19+
process.env.DD_INJECTION_ENABLED = originalInjectionEnabled
20+
}
21+
})
22+
23+
it('should abort when node version exceeds nodeMaxMajor', () => {
24+
const guard = proxyquire('../../src/guardrails/index', {
25+
'../../../../package.json': {
26+
engines: { node: `>=${NODE_MAJOR}` },
27+
nodeMaxMajor: NODE_MAJOR,
28+
},
29+
'./log': { info: () => {} },
30+
'./telemetry': () => {},
31+
})
32+
33+
let called = false
34+
const result = guard(() => { called = true })
35+
assert.strictEqual(called, false)
36+
assert.strictEqual(result, undefined)
37+
})
38+
})

packages/dd-trace/test/setup/mocha.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const semver = require('semver')
1313
const sinon = require('sinon')
1414
require('./core')
1515

16+
const { engines, nodeMaxMajor } = require('../../../../package.json')
17+
1618
const externals = require('../plugins/externals')
1719
const { resolvePluginVersions } = require('../plugins/versions')
1820
const runtimeMetrics = require('../../src/runtime_metrics')
@@ -259,6 +261,9 @@ function withVersions (plugin, modules, range, cb) {
259261
range = undefined
260262
}
261263

264+
if (!process.env.DD_INJECT_FORCE &&
265+
!semver.satisfies(process.version, `${engines.node} <${nodeMaxMajor}`)) return
266+
262267
const instrumentations = typeof plugin === 'string' ? getInstrumentation(plugin) : [plugin]
263268
const names = new Set(instrumentations.map(instrumentation => instrumentation.name))
264269

scripts/generate-supported-integrations.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,12 @@ function toCsv (rows) {
200200
}
201201

202202
async function generateSupportedIntegrations () {
203+
const pkg = JSON.parse(readFileSync(ROOT_PACKAGE, 'utf8'))
203204
const plugins = readPluginMap()
204-
const engines = parseEnginesRange(JSON.parse(readFileSync(ROOT_PACKAGE, 'utf8')).engines.node)
205+
const engines = parseEnginesRange(pkg.engines.node)
206+
if (engines.maxMajor === undefined && pkg.nodeMaxMajor !== undefined) {
207+
engines.maxMajor = pkg.nodeMaxMajor - 1
208+
}
205209
const ranges = readInstrumentationRanges(engines)
206210
const versions = JSON.parse(readFileSync(VERSIONS_PACKAGE, 'utf8')).dependencies ?? {}
207211

0 commit comments

Comments
 (0)