diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..19f4066 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,346 @@ + +name: "CI: Build & Test" +on: + push: + branches: + - main + - release/** + pull_request: + +jobs: + job_lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out current commit + uses: actions/checkout@v4 + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version-file: "package.json" + - name: Install dependencies + run: yarn install --ignore-engines --ignore-scripts --frozen-lockfile + - name: Lint + run: yarn lint + + job_compile: + name: Compile Binary (v${{ matrix.node }}) ${{ matrix.target_platform || matrix.os }}, ${{ matrix.arch || matrix.container }}, ${{ contains(matrix.container, 'alpine') && 'musl' || 'glibc' }} + runs-on: ${{ matrix.os }} + container: + image: ${{ matrix.container }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + # x64 glibc + - os: ubuntu-22.04 + node: 18 + binary: linux-x64-glibc-108 + - os: ubuntu-22.04 + node: 20 + binary: linux-x64-glibc-115 + - os: ubuntu-22.04 + node: 22 + binary: linux-x64-glibc-127 + - os: ubuntu-22.04 + node: 24 + binary: linux-x64-glibc-137 + + # x64 musl + - os: ubuntu-22.04 + container: node:18-alpine3.17 + node: 18 + binary: linux-x64-musl-108 + - os: ubuntu-22.04 + container: node:20-alpine3.17 + node: 20 + binary: linux-x64-musl-115 + - os: ubuntu-22.04 + container: node:22-alpine3.18 + node: 22 + binary: linux-x64-musl-127 + - os: ubuntu-22.04 + container: node:24-alpine3.20 + node: 24 + binary: linux-x64-musl-137 + + # arm64 glibc + - os: ubuntu-22.04 + arch: arm64 + node: 18 + binary: linux-arm64-glibc-108 + - os: ubuntu-22.04 + arch: arm64 + node: 20 + binary: linux-arm64-glibc-115 + - os: ubuntu-22.04 + arch: arm64 + node: 22 + binary: linux-arm64-glibc-127 + - os: ubuntu-22.04 + arch: arm64 + node: 24 + binary: linux-arm64-glibc-137 + + # arm64 musl + - os: ubuntu-22.04 + arch: arm64 + container: node:18-alpine3.17 + node: 18 + binary: linux-arm64-musl-108 + - os: ubuntu-22.04 + arch: arm64 + container: node:20-alpine3.17 + node: 20 + binary: linux-arm64-musl-115 + - os: ubuntu-22.04 + arch: arm64 + container: node:22-alpine3.18 + node: 22 + binary: linux-arm64-musl-127 + - os: ubuntu-22.04 + arch: arm64 + container: node:24-alpine3.20 + node: 24 + binary: linux-arm64-musl-137 + + # macos x64 + - os: macos-13 + node: 18 + arch: x64 + binary: darwin-x64-108 + - os: macos-13 + node: 20 + arch: x64 + binary: darwin-x64-115 + - os: macos-13 + node: 22 + arch: x64 + binary: darwin-x64-127 + - os: macos-13 + node: 24 + arch: x64 + binary: darwin-x64-137 + + # macos arm64 + - os: macos-13 + arch: arm64 + node: 18 + target_platform: darwin + binary: darwin-arm64-108 + - os: macos-13 + arch: arm64 + node: 20 + target_platform: darwin + binary: darwin-arm64-115 + - os: macos-13 + arch: arm64 + node: 22 + target_platform: darwin + binary: darwin-arm64-127 + - os: macos-13 + arch: arm64 + node: 24 + target_platform: darwin + binary: darwin-arm64-137 + + # windows x64 + - os: windows-2022 + node: 18 + arch: x64 + binary: win32-x64-108 + - os: windows-2022 + node: 20 + arch: x64 + binary: win32-x64-115 + - os: windows-2022 + node: 22 + arch: x64 + binary: win32-x64-127 + - os: windows-2022 + node: 24 + arch: x64 + binary: win32-x64-137 + + steps: + - name: Setup (alpine) + if: contains(matrix.container, 'alpine') + run: | + apk add --no-cache build-base git g++ make curl python3 + ln -sf python3 /usr/bin/python + + - name: Check out current commit + uses: actions/checkout@v4 + + # Note: On alpine images, this does nothing + # The node version will be the one that is installed in the image + # If you want to change the node version, you need to change the image + # For non-alpine images, this will install the correct version of node + - name: Setup Node + uses: actions/setup-node@v4 + if: contains(matrix.container, 'alpine') == false + with: + node-version: ${{ matrix.node }} + + - name: Increase yarn network timeout on Windows + if: contains(matrix.os, 'windows') + run: yarn config set network-timeout 600000 -g + + - name: Install dependencies + run: yarn install --ignore-engines --ignore-scripts --frozen-lockfile + + - name: Configure safe directory + run: | + git config --global --add safe.directory "*" + + - name: Setup python + uses: actions/setup-python@v5 + if: ${{ !contains(matrix.container, 'alpine') }} + id: python-setup + with: + python-version: "3.9.13" + + - name: Setup (arm64| ${{ contains(matrix.container, 'alpine') && 'musl' || 'glibc' }}) + if: matrix.arch == 'arm64' && !contains(matrix.container, 'alpine') && matrix.target_platform != 'darwin' + run: | + sudo apt-get update + sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu + + - name: Setup Musl + if: contains(matrix.container, 'alpine') + run: | + curl -OL https://musl.cc.timfish.dev/aarch64-linux-musl-cross.tgz + tar -xzvf aarch64-linux-musl-cross.tgz + $(pwd)/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc --version + + # configure node-gyp + - name: Configure node-gyp + if: matrix.arch != 'arm64' + run: yarn build:bindings:configure + + - name: Configure node-gyp (arm64, ${{ contains(matrix.container, 'alpine') && 'musl' || 'glibc' }}) + if: matrix.arch == 'arm64' && matrix.target_platform != 'darwin' + run: yarn build:bindings:configure:arm64 + + - name: Configure node-gyp (arm64, darwin) + if: matrix.arch == 'arm64' && matrix.target_platform == 'darwin' + run: yarn build:bindings:configure:arm64 + + # build bindings + - name: Build Bindings + if: matrix.arch != 'arm64' + run: | + yarn build:bindings + + - name: Build Bindings (arm64, ${{ contains(matrix.container, 'alpine') && 'musl' || 'glibc' }}) + if: matrix.arch == 'arm64' && contains(matrix.container, 'alpine') && matrix.target_platform != 'darwin' + run: | + CC=$(pwd)/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc \ + CXX=$(pwd)/aarch64-linux-musl-cross/bin/aarch64-linux-musl-g++ \ + BUILD_ARCH=arm64 \ + yarn build:bindings + + - name: Build Bindings (arm64, ${{ contains(matrix.container, 'alpine') && 'musl' || 'glibc' }}) + if: matrix.arch == 'arm64' && !contains(matrix.container, 'alpine') && matrix.target_platform != 'darwin' + run: | + CC=aarch64-linux-gnu-gcc \ + CXX=aarch64-linux-gnu-g++ \ + BUILD_ARCH=arm64 \ + yarn build:bindings:arm64 + + - name: Build Bindings (arm64, darwin) + if: matrix.arch == 'arm64' && matrix.target_platform == 'darwin' + run: | + BUILD_PLATFORM=darwin \ + BUILD_ARCH=arm64 \ + yarn build:bindings:arm64 + + - name: Build + run: yarn build:lib + + - name: Archive Binary + uses: actions/upload-artifact@v4 + with: + name: stack-trace-${{ matrix.binary }} + path: ${{ github.workspace }}/lib/stack-trace-${{matrix.binary}}.node + if-no-files-found: error + + job_build: + name: Build Package + needs: [job_compile] + runs-on: ubuntu-latest + steps: + - name: Check out current commit + uses: actions/checkout@v4 + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version-file: "package.json" + + - name: Install dependencies + run: yarn install --ignore-engines --ignore-scripts --frozen-lockfile + + - name: Build TypeScript + run: yarn build:lib + + - name: Extract Prebuilt Binaries + uses: actions/download-artifact@v4 + with: + pattern: stack-trace-* + path: ${{ github.workspace }}/lib/ + merge-multiple: true + + - name: Pack tarball + run: yarn build:tarball + + - name: Archive artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ github.sha }} + retention-days: 90 + path: ${{ github.workspace }}/*.tgz + + job_test_bindings: + name: Test (v${{ matrix.node }}) ${{ matrix.os }} + needs: [job_build] + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ + ubuntu-24.04, + ubuntu-22.04, + ubuntu-22.04-arm, + macos-latest, # macOS arm64 + macos-13, # macOS x64 + windows-latest, + ] + node: [18, 20, 22, 24] + steps: + - name: Check out current commit + uses: actions/checkout@v4 + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + - name: Install dependencies + run: yarn install --ignore-engines --ignore-scripts --frozen-lockfile + - name: Download Tarball + uses: actions/download-artifact@v4 + with: + name: ${{ github.sha }} + - name: Run tests + run: yarn test + + job_required_jobs_passed: + name: All required jobs passed + needs: [job_lint, job_test_bindings] + # Always run this, even if a dependent job failed + if: always() + runs-on: ubuntu-latest + steps: + - name: Check for failures + if: contains(needs.*.result, 'failure') + run: | + echo "One of the dependent jobs have failed. You may need to re-run it." && exit 1 diff --git a/.gitignore b/.gitignore index cf7a18c..9e91cfa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ build/ lib/ /*.tgz +test/yarn.lock diff --git a/README.md b/README.md index 7abdbc5..e5c1011 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ registerThread(); Watchdog thread: ```ts -const { captureStackTrace } = require("@sentry-internal/node-native-stacktrace"); +const { captureStackTrace } = require( + "@sentry-internal/node-native-stacktrace", +); const stacks = captureStackTrace(); console.log(stacks); @@ -26,58 +28,32 @@ Results in: ```js { - '0': [ - { - function: 'from', - filename: 'node:buffer', - lineno: 298, - colno: 28 - }, - { - function: 'pbkdf2Sync', - filename: 'node:internal/crypto/pbkdf2', - lineno: 78, - colno: 17 - }, - { - function: 'longWork', - filename: '/app/test.js', - lineno: 20, - colno: 29 - }, - { - function: '?', - filename: '/app/test.js', - lineno: 24, - colno: 1 - } - ], - '2': [ - { - function: 'from', - filename: 'node:buffer', - lineno: 298, - colno: 28 - }, - { - function: 'pbkdf2Sync', - filename: 'node:internal/crypto/pbkdf2', - lineno: 78, - colno: 17 - }, - { - function: 'longWork', - filename: '/app/worker.js', - lineno: 10, - colno: 29 - }, - { - function: '?', - filename: '/app/worker.js', - lineno: 14, - colno: 1 - } - ] + '0': ' at from (node:buffer:299:28)\n' + + ' at pbkdf2Sync (node:internal/crypto/pbkdf2:78:17)\n' + + ' at longWork (/Users/tim/test/test/long-work.js:6:25)\n' + + ' at ? (/Users/tim/test/test/stack-traces.js:11:1)\n' + + ' at ? (node:internal/modules/cjs/loader:1734:14)\n' + + ' at ? (node:internal/modules/cjs/loader:1899:10)\n' + + ' at ? (node:internal/modules/cjs/loader:1469:32)\n' + + ' at ? (node:internal/modules/cjs/loader:1286:12)\n' + + ' at traceSync (node:diagnostics_channel:322:14)\n' + + ' at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)\n' + + ' at executeUserEntryPoint (node:internal/modules/run_main:152:5)\n' + + ' at ? (node:internal/main/run_main_module:33:47)', + '2': ' at from (node:buffer:299:28)\n' + + ' at pbkdf2Sync (node:internal/crypto/pbkdf2:78:17)\n' + + ' at longWork (/Users/tim/test/test/long-work.js:6:25)\n' + + ' at ? (/Users/tim/test/test/worker.js:6:1)\n' + + ' at ? (node:internal/modules/cjs/loader:1734:14)\n' + + ' at ? (node:internal/modules/cjs/loader:1899:10)\n' + + ' at ? (node:internal/modules/cjs/loader:1469:32)\n' + + ' at ? (node:internal/modules/cjs/loader:1286:12)\n' + + ' at traceSync (node:diagnostics_channel:322:14)\n' + + ' at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)\n' + + ' at executeUserEntryPoint (node:internal/modules/run_main:152:5)\n' + + ' at ? (node:internal/main/worker_thread:212:26)\n' + + ' at [nodejs.internal.kHybridDispatch] (node:internal/event_target:827:20)\n' + + ' at ? (node:internal/per_context/messageport:23:28)' } ``` diff --git a/module.cc b/module.cc index f1536f9..2620cc5 100644 --- a/module.cc +++ b/module.cc @@ -2,6 +2,7 @@ #include #include #include +#include using namespace v8; using namespace node; @@ -23,76 +24,62 @@ static std::unordered_map threads = {}; // Function to be called when an isolate's execution is interrupted static void ExecutionInterrupted(Isolate *isolate, void *data) { - auto promise = static_cast> *>(data); + auto promise = static_cast *>(data); auto stack = StackTrace::CurrentStackTrace(isolate, kMaxStackFrames, StackTrace::kDetailed); if (stack.IsEmpty()) { - promise->set_value(Array::New(isolate, 0)); + promise->set_value(""); return; } - auto frames = Array::New(isolate, stack->GetFrameCount()); + std::ostringstream stack_stream; - for (int i = 0; i < stack->GetFrameCount(); i++) { + auto length = stack->GetFrameCount(); + for (int i = 0; i < length; i++) { auto frame = stack->GetFrame(isolate, i); auto fn_name = frame->GetFunctionName(); + // Build stack trace line in JavaScript format: + // " at functionName(filename:line:column)" + stack_stream << " at "; if (frame->IsEval()) { - fn_name = - String::NewFromUtf8(isolate, "[eval]", NewStringType::kInternalized) - .ToLocalChecked(); + stack_stream << "[eval]"; } else if (fn_name.IsEmpty() || fn_name->Length() == 0) { - fn_name = String::NewFromUtf8(isolate, "?", NewStringType::kInternalized) - .ToLocalChecked(); + stack_stream << "?"; } else if (frame->IsConstructor()) { - fn_name = String::NewFromUtf8(isolate, "[constructor]", - NewStringType::kInternalized) - .ToLocalChecked(); + stack_stream << "[constructor]"; + } else { + v8::String::Utf8Value utf8_fn(isolate, fn_name); + stack_stream << (*utf8_fn ? *utf8_fn : "?"); } - auto frame_obj = Object::New(isolate); - frame_obj - ->Set(isolate->GetCurrentContext(), - String::NewFromUtf8(isolate, "function", - NewStringType::kInternalized) - .ToLocalChecked(), - fn_name) - .Check(); - - frame_obj - ->Set(isolate->GetCurrentContext(), - String::NewFromUtf8(isolate, "filename", - NewStringType::kInternalized) - .ToLocalChecked(), - frame->GetScriptName()) - .Check(); - - frame_obj - ->Set( - isolate->GetCurrentContext(), - String::NewFromUtf8(isolate, "lineno", NewStringType::kInternalized) - .ToLocalChecked(), - Integer::New(isolate, frame->GetLineNumber())) - .Check(); + stack_stream << " ("; - frame_obj - ->Set( - isolate->GetCurrentContext(), - String::NewFromUtf8(isolate, "colno", NewStringType::kInternalized) - .ToLocalChecked(), - Integer::New(isolate, frame->GetColumn())) - .Check(); + auto script_name = frame->GetScriptName(); + if (!script_name.IsEmpty()) { + v8::String::Utf8Value utf8_filename(isolate, script_name); + stack_stream << (*utf8_filename ? *utf8_filename : ""); + } else { + stack_stream << ""; + } - frames->Set(isolate->GetCurrentContext(), i, frame_obj).Check(); + int line_number = frame->GetLineNumber(); + int column_number = frame->GetColumn(); + + stack_stream << ":" << line_number << ":" << column_number << ")"; + + if (i < length - 1) { + stack_stream << "\n"; + } } - promise->set_value(frames); + promise->set_value(stack_stream.str()); } // Function to capture the stack trace of a single isolate -Local CaptureStackTrace(Isolate *isolate) { - std::promise> promise; +std::string CaptureStackTrace(Isolate *isolate) { + std::promise promise; auto future = promise.get_future(); // The v8 isolate must be interrupted to capture the stack trace @@ -105,7 +92,7 @@ Local CaptureStackTrace(Isolate *isolate) { void CaptureStackTraces(const FunctionCallbackInfo &args) { auto capture_from_isolate = args.GetIsolate(); - using ThreadResult = std::tuple>; + using ThreadResult = std::tuple; std::vector> futures; // We collect the futures into a vec so they can be processed in parallel @@ -128,13 +115,17 @@ void CaptureStackTraces(const FunctionCallbackInfo &args) { // JavaScript object Local result = Object::New(capture_from_isolate); for (auto &future : futures) { - auto [thread_name, frames] = future.get(); + auto [thread_name, stack_string] = future.get(); auto key = String::NewFromUtf8(capture_from_isolate, thread_name.c_str(), NewStringType::kNormal) .ToLocalChecked(); - result->Set(capture_from_isolate->GetCurrentContext(), key, frames).Check(); + auto value = String::NewFromUtf8(capture_from_isolate, stack_string.c_str(), + NewStringType::kNormal) + .ToLocalChecked(); + + result->Set(capture_from_isolate->GetCurrentContext(), key, value).Check(); } args.GetReturnValue().Set(result); diff --git a/package.json b/package.json index 21325d8..a6759b4 100644 --- a/package.json +++ b/package.json @@ -21,17 +21,18 @@ "build:dev": "yarn clean && yarn build:bindings:configure && yarn build", "build:tarball": "npm pack", "clean": "node-gyp clean && rm -rf lib && rm -rf build", - "test": "vitest run --silent=false --disable-console-intercept" + "test": "node ./test/prepare.mjs && vitest run --silent=false --disable-console-intercept" }, "volta": { "node": "24.1.0" }, "dependencies": { "detect-libc": "^2.0.4", - "node-abi": "^4.9.0" + "node-abi": "^3.73.0" }, "devDependencies": { "@sentry-internal/eslint-config-sdk": "^9.22.0", + "@sentry/core": "^9.22.0", "@types/node": "^18.19.1", "@types/node-abi": "^3.0.3", "clang-format": "^1.8.0", @@ -49,4 +50,4 @@ "/scripts/check-build.mjs", "/scripts/copy-target.mjs" ] -} +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index e21d3da..314656b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,16 +11,9 @@ const arch = process.env['BUILD_ARCH'] || _arch(); const abi = getAbi(versions.node, 'node'); const identifier = [platform, arch, stdlib, abi].filter(c => c !== undefined && c !== null).join('-'); -type StackFrame = { - function: string; - filename: string; - lineno: number; - colno: number; -}; - interface Native { registerThread(threadName: string): void; - captureStackTrace(): Record; + captureStackTrace(): Record; getThreadsLastSeen(): Record; } @@ -180,7 +173,7 @@ export function registerThread(threadName: string = String(threadId)): void { /** * Captures stack traces for all registered threads. */ -export function captureStackTrace(): Record { +export function captureStackTrace(): Record { return native.captureStackTrace(); } diff --git a/test/e2e.test.mjs b/test/e2e.test.mjs index fba60ee..11af071 100644 --- a/test/e2e.test.mjs +++ b/test/e2e.test.mjs @@ -1,22 +1,25 @@ import { spawnSync } from 'node:child_process'; import { join } from 'node:path'; -import { beforeAll, describe, expect, test } from 'vitest'; -import { installTarballAsDependency } from './prepare.mjs'; +import { createStackParser, nodeStackLineParser } from '@sentry/core'; +import { describe, expect, test } from 'vitest'; const __dirname = import.meta.dirname || new URL('.', import.meta.url).pathname; +const defaultStackParser = createStackParser(nodeStackLineParser()); -describe('e2e Tests', { timeout: 20000 }, () => { - beforeAll(() => { - installTarballAsDependency(__dirname); - }); +function parseStacks(stacks) { + return Object.fromEntries( + Object.entries(stacks).map(([id, stack]) => [id, defaultStackParser(stack)]), + ); +} +describe('e2e Tests', { timeout: 20000 }, () => { test('Capture stack trace from multiple threads', () => { const testFile = join(__dirname, 'stack-traces.js'); const result = spawnSync('node', [testFile]) - expect(result.status).toBe(0); + expect(result.status).toEqual(0); - const stacks = JSON.parse(result.stdout.toString()); + const stacks = parseStacks(JSON.parse(result.stdout.toString())); expect(stacks['0']).toEqual(expect.arrayContaining([ { @@ -24,18 +27,24 @@ describe('e2e Tests', { timeout: 20000 }, () => { filename: expect.any(String), lineno: expect.any(Number), colno: expect.any(Number), + in_app: false, + module: undefined, }, { function: 'longWork', filename: expect.stringMatching(/long-work.js$/), lineno: expect.any(Number), colno: expect.any(Number), + in_app: true, + module: undefined, }, { function: '?', filename: expect.stringMatching(/stack-traces.js$/), lineno: expect.any(Number), colno: expect.any(Number), + in_app: true, + module: undefined, }, ])); @@ -45,29 +54,35 @@ describe('e2e Tests', { timeout: 20000 }, () => { filename: expect.any(String), lineno: expect.any(Number), colno: expect.any(Number), + in_app: false, + module: undefined, }, { function: 'longWork', filename: expect.stringMatching(/long-work.js$/), lineno: expect.any(Number), colno: expect.any(Number), + in_app: true, + module: undefined, }, { function: '?', filename: expect.stringMatching(/worker.js$/), lineno: expect.any(Number), colno: expect.any(Number), + in_app: true, + module: undefined, }, ])); }); - test('detect stalled thread', { timeout: 20000 }, () => { + test('Detect stalled thread', { timeout: 20000 }, () => { const testFile = join(__dirname, 'stalled.js'); const result = spawnSync('node', [testFile]); - expect(result.status).toBe(0); + expect(result.status).toEqual(0); - const stacks = JSON.parse(result.stdout.toString()); + const stacks = parseStacks(JSON.parse(result.stdout.toString())); expect(stacks['0']).toEqual(expect.arrayContaining([ { @@ -75,18 +90,24 @@ describe('e2e Tests', { timeout: 20000 }, () => { filename: expect.any(String), lineno: expect.any(Number), colno: expect.any(Number), + in_app: false, + module: undefined, }, { function: 'longWork', filename: expect.stringMatching(/long-work.js$/), lineno: expect.any(Number), colno: expect.any(Number), + in_app: true, + module: undefined, }, { function: '?', filename: expect.stringMatching(/stalled.js$/), lineno: expect.any(Number), colno: expect.any(Number), + in_app: true, + module: undefined, }, ])); diff --git a/test/prepare.mjs b/test/prepare.mjs index e146c5f..eb2ca66 100644 --- a/test/prepare.mjs +++ b/test/prepare.mjs @@ -9,7 +9,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); const env = {...process.env, NODE_OPTIONS: '--no-deprecation'}; -export function installTarballAsDependency(root) { +function installTarballAsDependency(root) { const pkgJson = require('../package.json'); const normalizedName = pkgJson.name.replace('@', '').replace('/', '-'); @@ -17,7 +17,7 @@ export function installTarballAsDependency(root) { if (!existsSync(tarball)) { console.error(`Tarball not found: '${tarball}'`); - console.error(`Run 'yarn build && yarn build:tarball' first`); + console.error('Run \'yarn build && yarn build:tarball\' first'); process.exit(1); } @@ -41,5 +41,7 @@ export function installTarballAsDependency(root) { writeFileSync(join(root, 'package.json'), modified); console.log('Installing dependencies...'); - execSync('yarn install', { cwd: root }); + execSync('yarn install', { cwd: root, stdio: 'inherit' }); } + +installTarballAsDependency(__dirname); diff --git a/test/yarn.lock b/test/yarn.lock deleted file mode 100644 index 1779b92..0000000 --- a/test/yarn.lock +++ /dev/null @@ -1,27 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@sentry-internal/node-native-stacktrace@file:../sentry-internal-node-native-stacktrace-0.1.0.tgz": - version "0.1.0" - resolved "file:../sentry-internal-node-native-stacktrace-0.1.0.tgz#9f528856b2eecdefad847e171435f0d33d2375f5" - dependencies: - detect-libc "^2.0.4" - node-abi "^4.9.0" - -detect-libc@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.4.tgz#f04715b8ba815e53b4d8109655b6508a6865a7e8" - integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== - -node-abi@^4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-4.9.0.tgz#ca6dabf7991e54bf3ba6d8d32641e1b84f305263" - integrity sha512-0isb3h+AXUblx5Iv0mnYy2WsErH+dk2e9iXJXdKAtS076Q5hP+scQhp6P4tvDeVlOBlG3ROKvkpQHtbORllq2A== - dependencies: - semver "^7.6.3" - -semver@^7.6.3: - version "7.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== diff --git a/yarn.lock b/yarn.lock index 4f2c2ad..b7f8779 100644 --- a/yarn.lock +++ b/yarn.lock @@ -388,6 +388,11 @@ resolved "https://registry.yarnpkg.com/@sentry-internal/typescript/-/typescript-9.22.0.tgz#7bce764807c0bb122126f29af74fc43bf863039c" integrity sha512-pqeMOKuzUwpMXh12ONbWUtpJ9Tey+UYnLgqPVXZEnB4vpZfJ/y4mdHsNaEXxgGLWZ+wvvSdYJB9GsGBl0iSJrQ== +"@sentry/core@^9.22.0": + version "9.25.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-9.25.0.tgz#354b9d500075b0db1decc533c16fe0566a30c21b" + integrity sha512-k0AgzR6RIf6OEwkVz09zer8GcK1s7RothlS1R6Z4x1wAJ+brtx4HqWnbLp05LDNDNrjTzK30HXvuCGGusnZuig== + "@types/estree@1.0.7", "@types/estree@^1.0.0": version "1.0.7" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8" @@ -2284,12 +2289,12 @@ negotiator@^1.0.0: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== -node-abi@^4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-4.9.0.tgz#ca6dabf7991e54bf3ba6d8d32641e1b84f305263" - integrity sha512-0isb3h+AXUblx5Iv0mnYy2WsErH+dk2e9iXJXdKAtS076Q5hP+scQhp6P4tvDeVlOBlG3ROKvkpQHtbORllq2A== +node-abi@^3.73.0: + version "3.75.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.75.0.tgz#2f929a91a90a0d02b325c43731314802357ed764" + integrity sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg== dependencies: - semver "^7.6.3" + semver "^7.3.5" node-gyp@^11.2.0: version "11.2.0" @@ -2656,7 +2661,7 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.2.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4, semver@^7.6.3: +semver@^7.2.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: version "7.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==