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
1 change: 1 addition & 0 deletions .github/actions/install-dependencies/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ runs:
echo 'paths<<EOF'
node -e 'const { workspaces } = require("./package.json"); for (const dir of [".", ...workspaces]) console.log(require("path").resolve(dir, "node_modules"))'
echo '~/.cache/mongodb-binaries'
echo '~/.cache/prisma'
echo 'EOF'
} >> "$GITHUB_OUTPUT"
shell: bash
Expand Down
7 changes: 7 additions & 0 deletions .github/actions/install-playwright/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ runs:
playwright
apt

# `--with-deps` names packages that the runner image already has (glib, mesa, nss, ...), and `apt-get install` would
# upgrade them to the latest Ubuntu update. That is half of the download on a cold cache, and the image versions work.
- name: Keep installed apt packages
if: steps.playwright-version.outputs.version != ''
run: echo 'APT::Get::Upgrade "false";' | sudo tee /etc/apt/apt.conf.d/99-no-upgrade > /dev/null
shell: bash

# Downloads only the browsers and apt packages that are not on the cache volume yet. `npx` runs outside the repo,
# so it can't pick up a `playwright` that a parallel `pnpm install` is still linking.
- name: Install Playwright
Expand Down
109 changes: 35 additions & 74 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ jobs:
run: pnpm run lint:es-compatibility
- name: Lint types
run: pnpm run lint:types
- name: Check for circular dependencies
run: pnpm run circularDepCheck
- name: Check for dts files that reference stuff in the temporary build folder
run: |
if grep -r --include "*.d.ts" --exclude-dir ".nx" 'import("@sentry(-internal)?/[^/]*/build' .; then
echo "Found illegal TypeScript import statement."
exit 1
fi
- name: Check Playwright versions
run: |
version=$(node -p "require('./dev-packages/test-utils/package.json').devDependencies['@playwright/test']")
Expand All @@ -354,7 +362,8 @@ jobs:
job_check_lockfile:
name: Check lockfile
needs: [job_get_metadata]
timeout-minutes: 10
# `pnpm dedupe --check` fetches metadata for every package from npm, so this job can take 8+ min on PRs.
timeout-minutes: 20
runs-on: namespace-profile-sentry-javascript
if: |
needs.job_get_metadata.outputs.changed_deps == 'true' ||
Expand Down Expand Up @@ -406,27 +415,6 @@ jobs:
- name: Check file formatting
run: pnpm run format:check

job_circular_dep_check:
name: Circular Dependency Check
needs: [job_get_metadata, job_build]
timeout-minutes: 10
runs-on:
namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript${{ github.event_name == 'pull_request'
&& '-pr' || '' }}
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v7
with:
ref: ${{ env.HEAD_COMMIT }}
- name: Set up Node
uses: actions/setup-node@v7
with:
node-version-file: 'package.json'
- name: Restore caches
uses: ./.github/actions/restore-cache
- name: Run madge
run: pnpm run circularDepCheck

job_artifacts:
name: Upload Artifacts
needs: [job_get_metadata, job_build, job_build_layer, job_build_bundles, job_build_tarballs]
Expand Down Expand Up @@ -772,35 +760,8 @@ jobs:
overwrite: true
retention-days: 7

job_check_for_faulty_dts:
name: Check for faulty .d.ts files
needs: [job_get_metadata, job_build]
runs-on:
namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript${{ github.event_name == 'pull_request'
&& '-pr' || '' }}
timeout-minutes: 5
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v7
with:
ref: ${{ env.HEAD_COMMIT }}
- name: Set up Node
uses: actions/setup-node@v7
with:
node-version-file: 'package.json'
- name: Restore caches
uses: ./.github/actions/restore-cache
- name: Check for dts files that reference stuff in the temporary build folder
run: |
if grep -r --include "*.d.ts" --exclude-dir ".nx" 'import("@sentry(-internal)?/[^/]*/build' .; then
echo "Found illegal TypeScript import statement."
exit 1
fi

job_node_integration_tests:
name:
Node (${{ matrix.node }})${{ (matrix.typescript && format(' (TS {0})', matrix.typescript)) || '' }} Integration
Tests (${{ matrix.shard }}/3)
name: Node (${{ matrix.node }}) Integration Tests (${{ matrix.shard }}/3)
needs: [job_get_metadata, job_build]
if: needs.job_build.outputs.changed_node_integration == 'true' || github.event_name != 'pull_request'
runs-on:
Expand All @@ -812,19 +773,6 @@ jobs:
matrix:
node: [20.19, 22, 24, 26]
shard: [1, 2, 3]
typescript:
- false
include:
# Only check typescript for latest version (to streamline CI)
- node: 24
typescript: '5.0'
shard: 1
- node: 24
typescript: '5.0'
shard: 2
- node: 24
typescript: '5.0'
shard: 3
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v7
Expand All @@ -850,11 +798,6 @@ jobs:
- name: Restore caches
uses: ./.github/actions/restore-cache

- name: Overwrite typescript version
if: matrix.typescript == '5.0'
run: node ./scripts/use-ts-5_0.js
working-directory: dev-packages/node-integration-tests

- name: Run integration tests
working-directory: dev-packages/node-integration-tests
run: pnpm run test --shard=${{ matrix.shard }}/3
Expand Down Expand Up @@ -1083,9 +1026,10 @@ jobs:
if:
always() && needs.job_build_tarballs.result == 'success' && needs.job_build.outputs.e2e-matrix !='{"include":[]}'
needs: [job_get_metadata, job_build, job_build_layer, job_build_tarballs]
# Most apps finish in under a minute on 4 vCPUs, so they run on 2. Apps that take longer set `sentryTest.runner`.
runs-on:
namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript-e2e${{ github.event_name ==
'pull_request' && '-pr' || '' }}
${{ matrix.runner || 'namespace-profile-sentry-javascript-small' }};overrides.cache-tag=sentry-javascript-e2e${{
github.event_name == 'pull_request' && '-pr' || '' }}
timeout-minutes: 15
env:
# We just use a dummy DSN here, only send to the tunnel anyhow
Expand Down Expand Up @@ -1115,9 +1059,10 @@ jobs:
runtime: ${{ matrix.runtime }}
deno-version: ${{ matrix.deno-version }}

# Installs Playwright while the app builds. Keep it right before the build: the runner sets up a background
# composite action's steps from the job's shared `github` context, which fails with "Collection was modified" if
# a foreground step starts at that moment. Starting next to `download-artifact` also made it fail to read the event file.
# Installs Playwright while the app installs and builds. Keep it right before the install: the runner sets up a
# background composite action's steps from the job's shared `github` context, which fails with "Collection was
# modified" if a foreground step starts at that moment. Starting next to `download-artifact` also made it fail to
# read the event file.
- name: Install Playwright
id: install-playwright
background: true
Expand All @@ -1126,6 +1071,23 @@ jobs:
browsers: chromium
cwd: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}

# Every build command runs `pnpm install`, so installing first makes that a no-op. Some downloads from the npm
# registry crawl at tens of kB/s for the whole 7 minutes of the build step, and pnpm does not give up on a slow
# download. Another attempt reuses what is already in the store and opens new connections.
# The hoisted variant installs with another node linker, so installing first would only redo the install.
- name: Install E2E app dependencies
if: ${{ !contains(matrix.build-command, 'hoisted') }}
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 7
run: |
for attempt in 1 2; do
timeout 150 pnpm install && exit 0
echo "::warning::pnpm install attempt $attempt failed or did not finish in 150 s, retrying"
done
pnpm install
env:
SENTRY_E2E_WORKSPACE_ROOT: ${{ github.workspace }}

- name: Build E2E app
working-directory: ${{ runner.temp }}/test-application
timeout-minutes: 7
Expand Down Expand Up @@ -1216,7 +1178,6 @@ jobs:
job_lint,
job_check_lockfile,
job_check_format,
job_circular_dep_check,
job_size_check,
]
# Always run this, even if a dependent job failed
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/enforce-license-compliance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ on:
- v9
- v8

# Cancel in progress workflows on pull_requests.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
enforce-license-compliance:
runs-on: namespace-profile-sentry-javascript
Expand Down
4 changes: 4 additions & 0 deletions dev-packages/e2e-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ For example, if something is changed in the browser package, only E2E test apps
You can add additional information about the test (e.g. canary versions, optional in CI) by adding `sentryTest` in the `package.json`
of a test application.

The required E2E jobs run on 2 vCPUs (`namespace-profile-sentry-javascript-small`). If an app's job takes longer than
about 90 seconds, set `"sentryTest": { "runner": "namespace-profile-sentry-javascript" }` to run it and its variants on
4 vCPUs.

If you add Sentry dependencies to your test application, set the dependency versions to `latest || *` in order
for it to work with both regular and prerelease versions:

Expand Down
8 changes: 4 additions & 4 deletions dev-packages/e2e-tests/lib/getTestMatrix.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ function addIncludesForTestApp(testApp, includes, { optionalMode }) {
const shouldSkip = packageJson.sentryTest?.skip || false;
const isOptional = packageJson.sentryTest?.optional || false;
const variants = (optionalMode ? packageJson.sentryTest?.optionalVariants : packageJson.sentryTest?.variants) || [];
const runner = packageJson.sentryTest?.runner;
const baseInclude = { 'test-application': testApp, ...(runner ? { runner } : {}) };

if (shouldSkip) {
return;
}

// Add the basic test-application itself, if it is in the current mode
if (optionalMode === isOptional) {
includes.push({
'test-application': testApp,
});
includes.push(baseInclude);
}

variants.forEach(variant => {
Expand All @@ -94,7 +94,7 @@ function addIncludesForTestApp(testApp, includes, { optionalMode }) {
// Don't leak the `skip` flag into the matrix include.
const { skip: _skip, ...variantConfig } = variant;
includes.push({
'test-application': testApp,
...baseInclude,
...variantConfig,
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "NODE_VERSION=22 pnpm test:build",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,8 @@ test.describe('Lambda layer', () => {
const transactionEvent = await transactionEventPromise;

expect(transactionEvent.contexts?.trace?.status).toBe('ok');
expect(transactionEvent.timestamp! - transactionEvent.start_timestamp!).toBeGreaterThanOrEqual(0.2);
// Node timers can fire up to a millisecond early, so the 200 ms callback delay can measure as 199.x ms
expect(transactionEvent.timestamp! - transactionEvent.start_timestamp!).toBeGreaterThanOrEqual(0.19);
});

test('sets error status when a callback-style handler calls back with an error after it returned', async ({
Expand All @@ -360,7 +361,7 @@ test.describe('Lambda layer', () => {
const [errorEvent, transactionEvent] = await Promise.all([errorEventPromise, transactionEventPromise]);

expect(transactionEvent.contexts?.trace?.status).toBe('internal_error');
expect(transactionEvent.timestamp! - transactionEvent.start_timestamp!).toBeGreaterThanOrEqual(0.2);
expect(transactionEvent.timestamp! - transactionEvent.start_timestamp!).toBeGreaterThanOrEqual(0.19);
expect(errorEvent.contexts?.trace?.trace_id).toBe(transactionEvent.contexts?.trace?.trace_id);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@
},
"volta": {
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
},
"volta": {
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@
},
"volta": {
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@
},
"volta": {
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"optionalVariants": [
{
"build-command": "pnpm test:build-latest",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "pnpm test:build-webpack",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,8 @@
},
"volta": {
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "pnpm test:build-webpack",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "pnpm test:build-webpack",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "pnpm test:build-webpack",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "pnpm test:build-webpack",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "pnpm test:build-15",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"extends": "../../package.json"
},
"sentryTest": {
"runner": "namespace-profile-sentry-javascript",
"variants": [
{
"build-command": "pnpm test:build-15",
Expand Down
Loading
Loading