diff --git a/docs/supporting-a-new-node-version.md b/docs/supporting-a-new-node-version.md index bd4068d03eb5..d38b3e245f93 100644 --- a/docs/supporting-a-new-node-version.md +++ b/docs/supporting-a-new-node-version.md @@ -93,15 +93,10 @@ Reference: [#20710](https://github.com/getsentry/sentry-javascript/pull/20710) - [ ] `@sentry-internal/node-native-stacktrace` in `packages/node-native/package.json` - [ ] Run `yarn install` to update `yarn.lock` -3. Register the new ABI in the profiling pruner. In - `packages/profiling-node/scripts/prune-profiler-binaries.js`: - - [ ] Add the Node major to ABI mapping to the `NODE_TO_ABI` object (e.g. `26: '147'`). - - [ ] Add the corresponding `else if (NODE.startsWith('26'))` branch. - -4. Allow the new major in the profiling integration, in `packages/profiling-node/src/integration.ts`: +3. Allow the new major in the profiling integration, in `packages/profiling-node/src/integration.ts`: - [ ] Add the version number to the `if (![16, 18, 20, 22, 24, 26].includes(NODE_MAJOR))` guard - [ ] Add the version to the supported-versions list in the `console.warn` message below the guard (the string that reads `...prebuilt support for the following LTS versions of Node.js: 16, 18, 20, 22, 24.`) -5. Handle deprecation warnings. Each new Node version tends to deprecate APIs the SDK (or its dependencies) still use, which can break tests that assert on clean stderr or console output. +4. Handle deprecation warnings. Each new Node version tends to deprecate APIs the SDK (or its dependencies) still use, which can break tests that assert on clean stderr or console output. -6. Fix version-specific test failures, some integrations or test dependencies may not yet work on the new version. +5. Fix version-specific test failures, some integrations or test dependencies may not yet work on the new version. diff --git a/packages/profiling-node/README.md b/packages/profiling-node/README.md index 078911c27a3f..be1e4dbfe658 100644 --- a/packages/profiling-node/README.md +++ b/packages/profiling-node/README.md @@ -234,46 +234,8 @@ require('esbuild').build({ Once you run `node esbuild.serverless.js` esbuild wil bundle and output the files to ./dist folder, but note that all of the binaries will be copied. This is wasteful as you will likely only need one of these libraries to be available during -runtime. - -> **Deprecation notice:** This script will be removed in the next major version. If you depend on it, please comment on -> [this issue](https://github.com/getsentry/sentry-javascript/issues/20567). - -To prune the other libraries, profiling-node ships with a small utility script that helps you prune unused binaries: - -```bash -npx --package=@sentry/profiling-node sentry-prune-profiler-binaries -``` - -Use `--help` to see a list of available options or `--dry-run` if you want it to log the binaries that would have been -deleted. - -Example of only preserving a binary to run node16 on linux x64 musl. - -```bash -npx --package=@sentry/profiling-node sentry-prune-profiler-binaries --target_dir_path=./dist --target_platform=linux --target_node=16 --target_stdlib=musl --target_arch=x64 -``` - -Which will output something like - -``` -Sentry: pruned ./dist/sentry_cpu_profiler-darwin-x64-108-IFGH3SUR.node (90.41 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-darwin-x64-93-Q7KBVHSP.node (74.16 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-arm64-glibc-108-NXSISRTB.node (52.17 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-arm64-glibc-83-OEQT5HUK.node (52.08 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-arm64-glibc-93-IIXXW2PN.node (52.06 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-arm64-musl-108-DSILNYHA.node (48.46 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-arm64-musl-83-4CNOBNC3.node (48.37 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-arm64-musl-93-JA5PKNWQ.node (48.38 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-x64-glibc-108-NXSISRTB.node (52.17 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-x64-glibc-83-OEQT5HUK.node (52.08 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-x64-glibc-93-IIXXW2PN.node (52.06 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-x64-musl-108-CX7SL27U.node (51.50 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-linux-x64-musl-83-YD7ZQK2E.node (51.53 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-win32-x64-108-P7V3URQV.node (181.50 KiB) -Sentry: pruned ./dist/sentry_cpu_profiler-win32-x64-93-3PKQDSGE.node (181.50 KiB) -✅ Sentry: pruned 15 binaries, saved 1.06 MiB in total. -``` +runtime. Since the binaries follow the `sentry_cpu_profiler----.node` naming scheme, you can +delete the ones that do not match your target runtime as part of your build step to reduce the deployment size. ### Environment flags diff --git a/packages/profiling-node/package.json b/packages/profiling-node/package.json index f42315675c1a..ae8b355ed7a2 100644 --- a/packages/profiling-node/package.json +++ b/packages/profiling-node/package.json @@ -22,9 +22,6 @@ } } }, - "bin": { - "sentry-prune-profiler-binaries": "scripts/prune-profiler-binaries.js" - }, "engines": { "node": ">=20.19.0 <22.0.0 || >=22.12.0 <23.0.0 || >=23.2.0" }, @@ -33,8 +30,7 @@ }, "files": [ "/build", - "package.json", - "/scripts/prune-profiler-binaries.js" + "package.json" ], "scripts": { "clean": "rm -rf build", diff --git a/packages/profiling-node/scripts/prune-profiler-binaries.js b/packages/profiling-node/scripts/prune-profiler-binaries.js deleted file mode 100755 index fc45fbcbe35a..000000000000 --- a/packages/profiling-node/scripts/prune-profiler-binaries.js +++ /dev/null @@ -1,204 +0,0 @@ -#! /usr/bin/env node - -// This is a build script, so some logging is desirable as it allows -// us to follow the code path that triggered the error. -/* eslint-disable no-console */ -const fs = require('fs'); - -let SOURCE_DIR, PLATFORM, ARCH, STDLIB, NODE, HELP; - -for (let i = 0; i < process.argv.length; i++) { - const arg = process.argv[i]; - if (arg.startsWith('--target_dir_path=')) { - SOURCE_DIR = arg.split('=')[1]; - continue; - } - - if (arg.startsWith('--target_platform=')) { - PLATFORM = arg.split('=')[1]; - continue; - } - - if (arg.startsWith('--target_arch=')) { - ARCH = arg.split('=')[1]; - continue; - } - - if (arg.startsWith('--target_stdlib=')) { - STDLIB = arg.split('=')[1]; - continue; - } - - if (arg.startsWith('--target_node=')) { - NODE = arg.split('=')[1]; - continue; - } - - if (arg === '--help' || arg === '-h') { - HELP = true; - continue; - } -} - -if (HELP) { - console.log( - `\nSentry: Prune profiler binaries\n -Usage: sentry-prune-profiler-binaries --target_dir_path=... --target_platform=... --target_arch=... --target_stdlib=...\n -Arguments:\n ---target_dir_path: Path to the directory containing the final bundled code. If you are using webpack, this would be the equivalent of output.path option.\n ---target_node: The major node version the code will be running on. Example: 16, 18, 20...\n ---target_platform: The platform the code will be running on. Example: linux, darwin, win32\n ---target_arch: The architecture the code will be running on. Example: x64, arm64\n ---target_stdlib: The standard library the code will be running on. Example: glibc, musl\n ---dry-run: Do not delete any files, just print the files that would be deleted.\n ---help: Print this help message.\n`, - ); - process.exit(0); -} - -console.warn( - '[Sentry] Warning: This script will be removed in the next major version. See: https://github.com/getsentry/sentry-javascript/issues/20567', -); - -const ARGV_ERRORS = []; - -const NODE_TO_ABI = { - 16: '93', - 18: '108', - 20: '115', - 22: '127', - 24: '137', - 26: '147', -}; - -if (NODE) { - if (NODE_TO_ABI[NODE]) { - NODE = NODE_TO_ABI[NODE]; - } else if (NODE.startsWith('16')) { - NODE = NODE_TO_ABI['16']; - } else if (NODE.startsWith('18')) { - NODE = NODE_TO_ABI['18']; - } else if (NODE.startsWith('20')) { - NODE = NODE_TO_ABI['20']; - } else if (NODE.startsWith('22')) { - NODE = NODE_TO_ABI['22']; - } else if (NODE.startsWith('24')) { - NODE = NODE_TO_ABI['24']; - } else if (NODE.startsWith('26')) { - NODE = NODE_TO_ABI['26']; - } else { - ARGV_ERRORS.push( - `❌ Sentry: Invalid node version passed as argument, please make sure --target_node is a valid major node version. Supported versions are ${Object.keys( - NODE_TO_ABI, - ).join(', ')}.`, - ); - } -} - -if (!SOURCE_DIR) { - ARGV_ERRORS.push( - '❌ Sentry: Missing target_dir_path argument. target_dir_path should point to the directory containing the final bundled code. If you are using webpack, this would be the equivalent of output.path option.', - ); -} - -if (!PLATFORM && !ARCH && !STDLIB) { - ARGV_ERRORS.push( - `❌ Sentry: Missing argument values, pruning requires either --target_platform, --target_arch or --target_stdlib to be passed as argument values.\n Example: sentry-prune-profiler-binaries --target_platform=linux --target_arch=x64 --target_stdlib=glibc\n -If you are unsure about the execution environment, you can opt to skip some values, but at least one value must be passed.`, - ); -} - -if (ARGV_ERRORS.length > 0) { - console.log(ARGV_ERRORS.join('\n')); - process.exit(1); -} - -const SENTRY__PROFILER_BIN_REGEXP = /sentry_cpu_profiler-.*\.node$/; - -async function findSentryProfilerBinaries(source_dir) { - const binaries = new Set(); - const queue = [source_dir]; - - while (queue.length > 0) { - const dir = queue.pop(); - - for (const file of fs.readdirSync(dir)) { - if (SENTRY__PROFILER_BIN_REGEXP.test(file)) { - binaries.add(`${dir}/${file}`); - continue; - } - - if (fs.statSync(`${dir}/${file}`).isDirectory()) { - if (file === 'node_modules') { - continue; - } - - queue.push(`${dir}/${file}`); - } - } - } - - return binaries; -} - -function bytesToHumanReadable(bytes) { - if (bytes < 1024) { - return `${bytes} Bytes`; - } else if (bytes < 1048576) { - return `${(bytes / 1024).toFixed(2)} KiB`; - } else { - return `${(bytes / 1048576).toFixed(2)} MiB`; - } -} - -async function prune(binaries) { - let bytesSaved = 0; - let removedBinariesCount = 0; - - const conditions = [PLATFORM, ARCH, STDLIB, NODE].filter(n => !!n); - - for (const binary of binaries) { - if (conditions.every(condition => binary.includes(condition))) { - continue; - } - - const stats = fs.statSync(binary); - bytesSaved += stats.size; - removedBinariesCount++; - - if (process.argv.includes('--dry-run')) { - console.log(`Sentry: would have pruned ${binary} (${bytesToHumanReadable(stats.size)})`); - continue; - } - - console.log(`Sentry: pruned ${binary} (${bytesToHumanReadable(stats.size)})`); - fs.unlinkSync(binary); - } - - if (removedBinariesCount === 0) { - console.log( - '❌ Sentry: no binaries pruned, please make sure target argument values are valid or use --help for more information.', - ); - return; - } - - if (process.argv.includes('--dry-run')) { - console.log( - `✅ Sentry: would have pruned ${removedBinariesCount} ${ - removedBinariesCount === 1 ? 'binary' : 'binaries' - } and saved ${bytesToHumanReadable(bytesSaved)}.`, - ); - return; - } - - console.log( - `✅ Sentry: pruned ${removedBinariesCount} ${ - removedBinariesCount === 1 ? 'binary' : 'binaries' - }, saved ${bytesToHumanReadable(bytesSaved)} in total.`, - ); -} - -(async () => { - const binaries = await findSentryProfilerBinaries(SOURCE_DIR); - await prune(binaries); -})(); diff --git a/packages/profiling-node/test/prune-profiler-binaries.test.ts b/packages/profiling-node/test/prune-profiler-binaries.test.ts deleted file mode 100644 index 174eab6a9879..000000000000 --- a/packages/profiling-node/test/prune-profiler-binaries.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import * as os from 'node:os'; -import * as path from 'node:path'; -import { describe, expect, it } from 'vitest'; - -describe('prune-profiler-binaries', () => { - it('should check if the node version is valid', () => { - const currentNode = process.version.split('v')[1]; - const result = spawnSync( - 'node', - [ - path.join(__dirname, '../scripts/prune-profiler-binaries.js'), - '--target_platform=linux', - '--target_arch=x64', - '--target_stdlib=glibc', - `--target_dir_path=${os.tmpdir()}`, - `--target_node=${currentNode}`, - ], - { encoding: 'utf8' }, - ); - - expect(result.stdout).not.toContain('Invalid node version passed as argument'); - }); -});