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: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ RUN cp ./src/handler.mjs /nodejs/node_modules/datadog-lambda-js

# Move dd-trace from devDependencies to production dependencies
# That way it is included in our layer, while keeping it an optional dependency for npm.
RUN DD_TRACE_VERSION=$(node -p "require('dd-trace/package.json').version") \
&& node ./scripts/move_ddtrace_dependency.js "$(cat package.json)" "$DD_TRACE_VERSION" > package-new.json
RUN node ./scripts/move_ddtrace_dependency.js "$(cat package.json)" "$(cat node_modules/dd-trace/package.json)" > package-new.json
RUN mv package-new.json package.json
RUN rm -rf node_modules

Expand Down
4 changes: 3 additions & 1 deletion integration_tests_local/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ dependency manifest mirrors the release build's full dependency closure —
production dependencies plus every package `scripts/move_ddtrace_dependency.js`
moves (dd-trace, @datadog/native-appsec, @datadog/pprof, @opentelemetry/api,
@opentelemetry/api-logs) — with versions pinned from the lockfile-resolved
`node_modules` set.
`node_modules` set, except dd-trace's native addons (@datadog/native-appsec,
@datadog/pprof), which are pinned to the versions dd-trace declares, as in the
release build.

The harness takes no flags or positional arguments — configuration is
environment-only, and an unexpected argument is rejected rather than ignored.
Expand Down
10 changes: 9 additions & 1 deletion integration_tests_local/prepare-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ const LAYER_MOVED_DEPENDENCIES = [
"@opentelemetry/api",
"@opentelemetry/api-logs",
];
// Like the release build, take dd-trace's native addons at the versions dd-trace
// declares rather than our hoisted devDependency pins.
const DD_TRACE_NATIVE_DEPENDENCIES = ["@datadog/native-appsec", "@datadog/pprof"];
const ddTraceOptionalDependencies = JSON.parse(
fs.readFileSync(path.join(repoDir, "node_modules", "dd-trace", "package.json"), "utf-8"),
).optionalDependencies;

function installedVersion(name) {
// Read the hoisted install location directly: require.resolve("<name>/package.json")
Expand All @@ -86,7 +92,9 @@ for (const name of Object.keys(pkg.dependencies || {})) {
dependencies[name] = installedVersion(name);
}
for (const name of LAYER_MOVED_DEPENDENCIES) {
dependencies[name] = installedVersion(name);
dependencies[name] = DD_TRACE_NATIVE_DEPENDENCIES.includes(name)
? ddTraceOptionalDependencies[name]
: installedVersion(name);
}

fs.writeFileSync(
Expand Down
27 changes: 20 additions & 7 deletions scripts/move_ddtrace_dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@
// dd-trace is pinned to the version installed at runtime rather than the range in the
// manifest: install_deps.sh restores package.json to the v6 line after installing, so on Node
// 18/20 the range here still says v6 while node_modules holds v5.
//
// The layer is installed with --ignore-optional, which drops dd-trace's native addons, so they
// are added back at the exact versions that dd-trace declares. Pinning them in our own
// devDependencies instead let them drift from the versions dd-trace calls into, e.g. dd-trace
// passing heapLimitExtensionSize 'auto' to a @datadog/pprof too old to accept it.

// USAGE: ./move_ddtrace_dependency.js "$(cat package.json)" <dd-trace version> > package.json
// USAGE: ./move_ddtrace_dependency.js "$(cat package.json)" "$(cat node_modules/dd-trace/package.json)" > package.json

const file = JSON.parse(process.argv[2]);
const ddTraceVersion = process.argv[3];

if (!ddTraceVersion) {
throw new Error('A resolved dd-trace version is required, e.g. $(node -p "require(\'dd-trace/package.json\').version")');
if (!process.argv[3]) {
throw new Error('The installed dd-trace package.json is required, e.g. "$(cat node_modules/dd-trace/package.json)"');
}
const ddTracePackage = JSON.parse(process.argv[3]);

moveDependency('dd-trace', ddTraceVersion)
moveDependency('@datadog/native-appsec')
moveDependency('@datadog/pprof')
moveDependency('dd-trace', ddTracePackage.version)
moveDependency('@datadog/native-appsec', ddTraceOptionalVersion('@datadog/native-appsec'))
moveDependency('@datadog/pprof', ddTraceOptionalVersion('@datadog/pprof'))
moveDependency('@opentelemetry/api')
moveDependency('@opentelemetry/api-logs')

Expand All @@ -27,3 +32,11 @@ function moveDependency (name, resolvedVersion) {
delete file.devDependencies[name];
file.dependencies[name] = resolvedVersion || declaredVersion;
}

function ddTraceOptionalVersion (name) {
const version = ddTracePackage.optionalDependencies[name];
if (!version) {
throw new Error(`dd-trace ${ddTracePackage.version} does not declare ${name} in optionalDependencies`);
}
return version;
}
Loading