Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/actions/node/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ runs:
- if: steps.attempt.outcome == 'failure'
shell: bash
run: sleep 60
- if: steps.attempt.outcome == 'failure'
- id: retry
if: steps.attempt.outcome == 'failure'
uses: ./.github/actions/node/setup
with:
version: ${{ inputs.version }}
3 changes: 2 additions & 1 deletion .github/actions/node/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ runs:
}
case "$VERSION" in
eol) version=16 ;;
oldest) version=$(node_version 18) ;;
oldest) oldest_major=$(awk '/"node"/{match($0,/[0-9]+/);print substr($0,RSTART,RLENGTH);exit}' package.json)
version=$(node_version "$oldest_major") ;;
maintenance) version=$(node_version 20) ;;
active) version=$(node_version 24) ;;
latest) version=${LATEST_VERSION:-$(node_version 26)}
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/apm-integrations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jobs:
aerospike-version: ce-6.4.0.3
image: aerospike@sha256:f268d48f5075010ff268b29fbae28518418070dfb31935daa31f0b45c59f4da9 # ce-6.4.0.3
test-image: ubuntu-latest

runs-on: ${{ matrix.test-image }}
permissions:
id-token: write
Expand Down Expand Up @@ -332,7 +333,7 @@ jobs:
- "^3.0.7"
- ">=4.0.0 <4.2.0"
include:
- node-version: 18
- node-version: oldest
range: ">=4.2.0"
runs-on: ubuntu-latest
permissions:
Expand Down Expand Up @@ -1122,7 +1123,7 @@ jobs:
- node-version: 18
range: ">=6.1.0 <7.0.0"
range_clean: gte.6.16.0.and.lt.7.0.0
- node-version: "latest"
- node-version: latest
range: ""
range_clean: all
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18
22
23 changes: 12 additions & 11 deletions integration-tests/init.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const telemetryAbort = ['abort', 'reason:incompatible_runtime', 'abort.runtime',
const telemetryForced = ['complete', 'injection_forced:true']
const telemetryGood = ['complete', 'injection_forced:false']

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

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

context('when node version is too recent', () => {
context('when node version is too old', () => {
useEnv({ NODE_OPTIONS })

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

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

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

context('when node version is too old', () => {
context('when node version is too recent', () => {
useEnv({ NODE_OPTIONS })

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

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

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

before(() => {
const pkg = JSON.parse(pkgStr)
pkg.engines.node = '>=0 <1000'
pkg.engines.node = '>=0'
pkg.nodeMaxMajor = 1000
fs.writeFileSync(pkgPath, JSON.stringify(pkg))
})

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@
},
"homepage": "https://github.com/DataDog/dd-trace-js#readme",
"engines": {
"node": ">=18 <27"
"node": ">=18"
Comment thread
rochdev marked this conversation as resolved.
},
"nodeMaxMajor": 27,
"files": [
"/package.json",
"ci/**/*",
Expand Down
13 changes: 8 additions & 5 deletions packages/dd-trace/src/guardrails/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ function guard (fn) {
var initBailout = false
var clobberBailout = false
var forced = isTrue(process.env.DD_INJECT_FORCE)
var engines = require('../../../../package.json').engines
var versions = engines.node.match(/^>=(\d+) <(\d+)$/)
var pkg = require('../../../../package.json')
var engines = pkg.engines
var versions = engines.node.match(/^>=(\d+)$/)
var minMajor = versions[1]
var nextMajor = versions[2]
var nextMajor = pkg.nodeMaxMajor
var version = process.versions.node
var supportedRange = engines.node + ' <' + nextMajor

if (process.env.DD_INJECTION_ENABLED) {
// If we're running via single-step install, and we're in the app's
Expand All @@ -45,16 +47,17 @@ function guard (fn) {
// should not initialize the tracer.
if (!clobberBailout && (NODE_MAJOR < minMajor || NODE_MAJOR >= nextMajor)) {
initBailout = true
var runtimeInfo = 'Incompatible runtime Node.js ' + version + ', supported runtimes: Node.js ' + supportedRange
telemetry([
{ name: 'abort', tags: ['reason:incompatible_runtime'] },
{ name: 'abort.runtime', tags: [] }
], undefined, {
result: 'abort',
result_class: 'incompatible_runtime',
result_reason: 'Incompatible runtime Node.js ' + version + ', supported runtimes: Node.js ' + engines.node
result_reason: runtimeInfo
})
log.info('Aborting application instrumentation due to incompatible_runtime.')
log.info('Found incompatible runtime Node.js %s, Supported runtimes: Node.js %s.', version, engines.node)
log.info('Found incompatible runtime Node.js %s, Supported runtimes: Node.js %s.', version, supportedRange)
if (forced) {
log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
}
Expand Down
38 changes: 38 additions & 0 deletions packages/dd-trace/test/guardrails/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict'

const assert = require('node:assert/strict')
const { after, before, describe, it } = require('mocha')
const proxyquire = require('proxyquire')

const { NODE_MAJOR } = require('../../../../version')

describe('guard', () => {
let originalInjectionEnabled

before(() => {
originalInjectionEnabled = process.env.DD_INJECTION_ENABLED
delete process.env.DD_INJECTION_ENABLED
})

after(() => {
if (originalInjectionEnabled !== undefined) {
process.env.DD_INJECTION_ENABLED = originalInjectionEnabled
}
})

it('should abort when node version exceeds nodeMaxMajor', () => {
const guard = proxyquire('../../src/guardrails/index', {
'../../../../package.json': {
engines: { node: `>=${NODE_MAJOR}` },
nodeMaxMajor: NODE_MAJOR,
},
'./log': { info: () => {} },
'./telemetry': () => {},
})

let called = false
const result = guard(() => { called = true })
assert.strictEqual(called, false)
assert.strictEqual(result, undefined)
})
})
5 changes: 5 additions & 0 deletions packages/dd-trace/test/setup/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const semver = require('semver')
const sinon = require('sinon')
require('./core')

const { engines, nodeMaxMajor } = require('../../../../package.json')

const externals = require('../plugins/externals')
const runtimeMetrics = require('../../src/runtime_metrics')
const Nomenclature = require('../../src/service-naming')
Expand Down Expand Up @@ -258,6 +260,9 @@ function withVersions (plugin, modules, range, cb) {
range = undefined
}

if (!process.env.DD_INJECT_FORCE &&
!semver.satisfies(process.version, `${engines.node} <${nodeMaxMajor}`)) return

const instrumentations = typeof plugin === 'string' ? getInstrumentation(plugin) : [plugin]
const names = new Set(instrumentations.map(instrumentation => instrumentation.name))

Expand Down
6 changes: 5 additions & 1 deletion scripts/generate-supported-integrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,12 @@ function toCsv (rows) {
}

async function generateSupportedIntegrations () {
const pkg = JSON.parse(readFileSync(ROOT_PACKAGE, 'utf8'))
const plugins = readPluginMap()
const engines = parseEnginesRange(JSON.parse(readFileSync(ROOT_PACKAGE, 'utf8')).engines.node)
const engines = parseEnginesRange(pkg.engines.node)
if (engines.maxMajor === undefined && pkg.nodeMaxMajor !== undefined) {
engines.maxMajor = pkg.nodeMaxMajor - 1
}
const ranges = readInstrumentationRanges(engines)
const versions = JSON.parse(readFileSync(VERSIONS_PACKAGE, 'utf8')).dependencies ?? {}

Expand Down
Loading