Skip to content

Commit b26100b

Browse files
authored
add maximum node version in guardrails (#6788)
1 parent 8822838 commit b26100b

4 files changed

Lines changed: 102 additions & 25 deletions

File tree

.github/workflows/platform.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ jobs:
442442
# We'll run these separately for earlier (i.e. unsupported) versions
443443
integration-guardrails:
444444
strategy:
445+
fail-fast: false
445446
matrix:
446447
version: [14.0.0, 14, 16.0.0, 18.0.0, 20.0.0, 22.0.0, 24.0.0]
447448
runs-on: ubuntu-latest
@@ -462,6 +463,7 @@ jobs:
462463

463464
integration-guardrails-unsupported:
464465
strategy:
466+
fail-fast: false
465467
matrix:
466468
version: ['0.8', '0.10', '0.12', '4', '6', '8', '10', '12']
467469
runs-on: ubuntu-latest

integration-tests/init.spec.js

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict'
22

3+
const assert = require('assert')
34
const semver = require('semver')
45
const {
56
runAndCheckWithTelemetry: testFile,
@@ -14,7 +15,7 @@ const fs = require('fs')
1415
const DD_INJECTION_ENABLED = 'tracing'
1516
const DD_INJECT_FORCE = 'true'
1617
const DD_TRACE_DEBUG = 'true'
17-
const { NODE_VERSION } = require('../version')
18+
const { NODE_MAJOR, NODE_VERSION } = require('../version')
1819

1920
const telemetryAbort = ['abort', 'reason:incompatible_runtime', 'abort.runtime', '']
2021
const telemetryForced = ['complete', 'injection_forced:true']
@@ -99,46 +100,118 @@ function testRuntimeVersionChecks (arg, filename) {
99100
}
100101
}
101102

102-
if (!currentVersionIsSupported) {
103-
context('when node version is less than engines field', () => {
104-
useEnv({ NODE_OPTIONS })
103+
let pkgPath
104+
let pkgStr
105105

106-
it('should not initialize the tracer', () => doTest('false\n', []))
106+
before(() => {
107+
pkgPath = `${sandboxCwd()}/node_modules/dd-trace/package.json`
108+
pkgStr = fs.readFileSync(pkgPath, 'utf8')
109+
})
107110

108-
context('with DD_INJECTION_ENABLED', () => {
109-
useEnv({ DD_INJECTION_ENABLED })
111+
after(() => {
112+
fs.writeFileSync(pkgPath, pkgStr)
113+
})
110114

111-
context('without debug', () => {
112-
it('should not initialize the tracer', () => doTest('false\n', telemetryAbort))
115+
it('should be able to use the engines field', () => {
116+
const engines = require(`${sandboxCwd()}/node_modules/dd-trace/package.json`).engines.node
113117

114-
it('should initialize the tracer, if DD_INJECT_FORCE', () => doTestForced('true\n', telemetryForced))
115-
})
118+
assert.match(engines, /^>=\d+ <\d+$/)
119+
})
116120

117-
context('with debug', () => {
118-
useEnv({ DD_TRACE_DEBUG })
121+
context('when node version is too recent', () => {
122+
useEnv({ NODE_OPTIONS })
123+
124+
before(() => {
125+
const pkg = JSON.parse(pkgStr)
126+
pkg.engines.node = `>=${NODE_MAJOR - 1} <${NODE_MAJOR}`
127+
fs.writeFileSync(pkgPath, JSON.stringify(pkg))
128+
})
119129

120-
it('should not initialize the tracer', () =>
121-
doTest(`Aborting application instrumentation due to incompatible_runtime.
130+
it('should not initialize the tracer', () => doTest('false\n', []))
131+
132+
context('with DD_INJECTION_ENABLED', () => {
133+
useEnv({ DD_INJECTION_ENABLED })
134+
135+
context('without debug', () => {
136+
it('should not initialize the tracer', () => doTest('false\n', telemetryAbort))
137+
138+
it('should initialize the tracer, if DD_INJECT_FORCE', () => doTestForced('true\n', telemetryForced))
139+
})
140+
141+
context('with debug', () => {
142+
useEnv({ DD_TRACE_DEBUG })
143+
144+
it('should not initialize the tracer', () =>
145+
doTest(`Aborting application instrumentation due to incompatible_runtime.
122146
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
123-
>=18.
147+
>=${NODE_MAJOR - 1} <${NODE_MAJOR}.
124148
false
125149
`, telemetryAbort))
126150

127-
it('should initialize the tracer, if DD_INJECT_FORCE', () =>
128-
doTestForced(`Aborting application instrumentation due to incompatible_runtime.
151+
it('should initialize the tracer, if DD_INJECT_FORCE', () =>
152+
doTestForced(`Aborting application instrumentation due to incompatible_runtime.
129153
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
130-
>=18.
154+
>=${NODE_MAJOR - 1} <${NODE_MAJOR}.
131155
DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.
132156
Application instrumentation bootstrapping complete
133157
true
134158
`, telemetryForced))
135-
})
136159
})
137160
})
138-
} else {
139-
context('when node version is more than engines field', () => {
161+
})
162+
163+
context('when node version is too old', () => {
164+
useEnv({ NODE_OPTIONS })
165+
166+
before(() => {
167+
const pkg = JSON.parse(pkgStr)
168+
pkg.engines.node = `>=${NODE_MAJOR + 1} <${NODE_MAJOR + 2}`
169+
fs.writeFileSync(pkgPath, JSON.stringify(pkg))
170+
})
171+
172+
it('should not initialize the tracer', () => doTest('false\n', []))
173+
174+
context('with DD_INJECTION_ENABLED', () => {
175+
useEnv({ DD_INJECTION_ENABLED })
176+
177+
context('without debug', () => {
178+
it('should not initialize the tracer', () => doTest('false\n', telemetryAbort))
179+
180+
it('should initialize the tracer, if DD_INJECT_FORCE', () => doTestForced('true\n', telemetryForced))
181+
})
182+
183+
context('with debug', () => {
184+
useEnv({ DD_TRACE_DEBUG })
185+
186+
it('should not initialize the tracer', () =>
187+
doTest(`Aborting application instrumentation due to incompatible_runtime.
188+
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
189+
>=${NODE_MAJOR + 1} <${NODE_MAJOR + 2}.
190+
false
191+
`, telemetryAbort))
192+
193+
it('should initialize the tracer, if DD_INJECT_FORCE', () =>
194+
doTestForced(`Aborting application instrumentation due to incompatible_runtime.
195+
Found incompatible runtime Node.js ${process.versions.node}, Supported runtimes: Node.js \
196+
>=${NODE_MAJOR + 1} <${NODE_MAJOR + 2}.
197+
DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.
198+
Application instrumentation bootstrapping complete
199+
true
200+
`, telemetryForced))
201+
})
202+
})
203+
})
204+
205+
if (currentVersionIsSupported) {
206+
context('when node version is in range of the engines field', () => {
140207
useEnv({ NODE_OPTIONS })
141208

209+
before(() => {
210+
const pkg = JSON.parse(pkgStr)
211+
pkg.engines.node = '>=0 <1000'
212+
fs.writeFileSync(pkgPath, JSON.stringify(pkg))
213+
})
214+
142215
it('should initialize the tracer, if no DD_INJECTION_ENABLED', () => doTest('true\n', [], 'manual'))
143216

144217
context('with DD_INJECTION_ENABLED', () => {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
},
9696
"homepage": "https://github.com/DataDog/dd-trace-js#readme",
9797
"engines": {
98-
"node": ">=18"
98+
"node": ">=18 <26"
9999
},
100100
"files": [
101101
"/package.json",

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ function guard (fn) {
1414
var clobberBailout = false
1515
var forced = isTrue(process.env.DD_INJECT_FORCE)
1616
var engines = require('../../../../package.json').engines
17-
var minMajor = parseInt(engines.node.replace(/[^0-9]/g, ''))
17+
var versions = engines.node.match(/^>=(\d+) <(\d+)$/)
18+
var minMajor = versions[1]
19+
var nextMajor = versions[2]
1820
var version = process.versions.node
1921

2022
if (process.env.DD_INJECTION_ENABLED) {
@@ -40,7 +42,7 @@ function guard (fn) {
4042

4143
// If the runtime doesn't match the engines field in package.json, then we
4244
// should not initialize the tracer.
43-
if (!clobberBailout && NODE_MAJOR < minMajor) {
45+
if (!clobberBailout && (NODE_MAJOR < minMajor || NODE_MAJOR >= nextMajor)) {
4446
initBailout = true
4547
telemetry([
4648
{ name: 'abort', tags: ['reason:incompatible_runtime'] },

0 commit comments

Comments
 (0)