Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
ef5596b
test(replay): Fix flaky EventBufferCompressionWorker size limit test …
sentry-junior[bot] Oct 22, 2026
8042719
test(browser): Fix flaky long task, pageload cancellation and CLS tim…
sentry-junior[bot] Oct 22, 2026
c88b69f
feat(server-utils): Record Workers AI Clairic calls as gen_ai.extract…
andreiborza Oct 22, 2026
d476963
test(cloudflare): Add Workers AI E2E test for Clairic (#25625)
andreiborza Oct 22, 2026
f15e256
ci: Always report optional E2E results and update the report on re-ru…
andreiborza Oct 22, 2026
09fb95c
fix(node): Read module versions from the isolated layouts of pnpm and…
JPeer264 Oct 22, 2026
40eff80
chore: Use the isolated pnpm node_modules layout (#25368)
JPeer264 Oct 22, 2026
21f2cf1
chore: Pin pnpm 10 in Volta and remove .npmrc (#25641)
JPeer264 Oct 22, 2026
3aafe9e
ci(e2e): rightsize namespace runner jobs
sentry-junior[bot] Oct 22, 2026
5521cfc
feat(cloudflare): instrument Workers KV bindings (#25488)
faizansaiyed123 Oct 23, 2026
00a2101
ci: Show an unknown status for optional E2E jobs without a final resu…
andreiborza Oct 23, 2026
4149e90
ci: Stop uploading duplicate tarballs to the release artifact
s1gr1d Oct 23, 2026
a4cf21f
fix(replay): Apply attribute masking to breadcrumb messages (#25180)
msonnb Oct 23, 2026
6df508e
test(nextjs): Bump nextjs-16 E2E app to Next.js 16.4.2 (#25686)
mydea Oct 23, 2026
35402a9
reword and improve
s1gr1d Oct 23, 2026
20f6d1f
Merge branch 'develop' into sig/fix-release-artifact-tgz-glob
s1gr1d Oct 23, 2026
3a12a73
ci: Prepare required workflows for develop merge queue (#25642)
nicohrubec Oct 23, 2026
da1ebe8
chore: Add external contributor to CHANGELOG.md (#25675)
javascript-sdk-gitflow[bot] Oct 23, 2026
ad7ce98
fix(build): Make CJS re-exports visible to Node ESM imports (#25599)
s1gr1d Oct 23, 2026
56f0489
fix(deps): Allow `@opentelemetry/api` 1.9 again (#25684)
andreiborza Oct 23, 2026
7fb94b4
Merge pull request #25688 from getsentry/sig/fix-release-artifact-tgz…
s1gr1d Oct 23, 2026
dddb532
chore(deps): Bump next from 16.3.8 to 16.4.1 in /dev-packages/e2e-tes…
dependabot[bot] Oct 23, 2026
07b8868
Merge pull request #25706 from getsentry/sig/manual-develop-sync-11.9.0
s1gr1d Oct 23, 2026
8758c57
Merge pull request #25639 from seongwon030/fix/react-router-encoded-p…
seongwon030 Oct 23, 2026
b59c0ea
chore: Add external contributor to CHANGELOG.md (#25710)
javascript-sdk-gitflow[bot] Oct 23, 2026
067ae23
fix(node): Skip spans for outgoing requests to Sentry via `undici` fe…
Lms24 Oct 23, 2026
9927b7c
Merge pull request #25652 from getsentry/dependabot/npm_and_yarn/remi…
dependabot[bot] Oct 23, 2026
86758ce
chore(deps-dev): Bump next from 15.5.27 to 15.5.28 in /packages/nextj…
dependabot[bot] Oct 23, 2026
469262e
fix(server-utils): Keep OpenRouter evaluation confidence and legend o…
RulaKhaled Oct 23, 2026
aa9ffcc
feat(nextjs): Warn when Next.js production builds miss the instrument…
s1gr1d Oct 23, 2026
8dae2b1
Merge pull request #25555 from kunal649/kunal/fix/fetch-error-relativ…
kunal649 Oct 23, 2026
6def2d7
fix(tanstackstart-react): Unminify server errors in Nitro builds (#25…
s1gr1d Oct 23, 2026
e1026aa
test(tanstackstart-react): Add source map E2E app (#25363)
s1gr1d Oct 23, 2026
e8f4a71
fix(node): Use the request method for Hapi routes with multiple metho…
s1gr1d Oct 23, 2026
250547c
fix(hono): Make the Hono middleware types compile on Hono 5 (#25452)
s1gr1d Oct 23, 2026
fd6c0e1
ref(hono): Share the middleware classification (#25453)
s1gr1d Oct 23, 2026
8496ec1
fix(node): Flush buffered streamed spans on process exit (#25539)
logaretm Oct 23, 2026
ff07646
test(e2e): Pull Supabase images from GHCR (#25718)
andreiborza Oct 23, 2026
e7782f9
chore: Add external contributor to CHANGELOG.md (#25713)
javascript-sdk-gitflow[bot] Oct 23, 2026
9d42fea
feat(core): Add managed tunnel helpers that derive the tunnel path fr…
logaretm Oct 23, 2026
3ea9dc3
chore(ci): remove PR review reminders (#25711)
nicohrubec Oct 23, 2026
bb32a5c
ref(core): Add shared `ServerRequestOptions` type across runtimes (#2…
isaacs Oct 23, 2026
ad1bd23
feat(bun): Add incoming request options and sessions to `bunServerInt…
isaacs Oct 23, 2026
5b2de99
feat(node): Add `onSpanEnd` to `httpIntegration` (#25581)
isaacs Oct 23, 2026
2a53357
fix(cloudflare): Bind a default re-export with `var` in the Vite tran…
isaacs Oct 23, 2026
21a9938
feat(bun): Inject debug IDs and upload source maps in `sentryBunPlugi…
isaacs Oct 23, 2026
eff54dd
chore(ci): remove browser flaky-test detector workflow (#25712)
nicohrubec Oct 24, 2026
a734d03
test(cloudflare): Check that Durable Object invocations end when the …
JPeer264 Oct 25, 2026
03e18ae
fix(cloudflare): Skip comments when locating the `default` keyword in…
sentry-junior[bot] Oct 26, 2026
7dfffba
feat(cloudflare): Add incoming request span options to `httpServerInt…
isaacs Oct 26, 2026
bd2b387
feat(node, bun, deno, cloudflare): Align portable exports across serv…
isaacs Oct 26, 2026
ad71ef6
feat(cloudflare): Let users configure the channel integrations (#25584)
isaacs Oct 26, 2026
908fa35
fix(cloudflare): Do not add back channel integrations the user remove…
isaacs Oct 26, 2026
2af4685
ref(deno): Use a shared request handler wrapper for `Deno.serve` (#25…
isaacs Oct 26, 2026
c125a5d
ref(bun): Use the shared request handler wrapper for `Bun.serve` (#25…
isaacs Oct 26, 2026
ccab113
feat: Make span origins spec compliant (#25602)
mydea Oct 27, 2026
84f5d12
fix(bun): Add systemErrorIntegration to default integrations (#25681)
mydea Oct 27, 2026
8eb2615
chore(deps-dev): Bump hono from 4.13.9 to 4.13.11 in /packages/hono (…
dependabot[bot] Oct 27, 2026
0b5f66e
chore(deps-dev): Bump es-check from 7.2.1 to 9.8.1 (#25656)
dependabot[bot] Oct 27, 2026
d43db06
chore(deps): Bump zod from 4.5.4 to 4.6.6 in /dev-packages/e2e-tests/…
dependabot[bot] Oct 27, 2026
7e387ae
chore(deps): Bump zod from 4.5.4 to 4.6.6 in /dev-packages/e2e-tests/…
dependabot[bot] Oct 27, 2026
7d1f14f
ref(server-utils): Use `GEN_AI_EXTRACT` op from `@sentry/conventions`…
sentry-junior[bot] Oct 27, 2026
fe317e0
feat(deps): Bump fastify from 5.12.5 to 5.12.7 (#25654)
dependabot[bot] Oct 27, 2026
3710736
fix(feedback): Wait for frames without the form before capturing the …
larcane97 Oct 27, 2026
e50326b
chore: Add external contributor to CHANGELOG.md (#25759)
javascript-sdk-gitflow[bot] Oct 27, 2026
869b92c
test(nextjs): Unpin nextjs-16-cf-workers latest variant back to next@…
sentry-junior[bot] Oct 27, 2026
2181398
fix(server-utils): Use cumulative input and cache token counts from s…
pcbeingused333 Oct 27, 2026
b5ddf23
chore: Add external contributor to CHANGELOG.md (#25762)
javascript-sdk-gitflow[bot] Oct 27, 2026
d9dc0ee
docs: Update contribution guidelines (#25714)
s1gr1d Oct 27, 2026
3654acc
test(node): Retry stalled npm installs in integration test setup (#25…
mydea Oct 27, 2026
71f4be9
feat(nuxt): Start the server SDK on the Nuxt Vite server (experimenta…
s1gr1d Oct 27, 2026
63f337d
fix(core): allow project arrays in framework build options (#25534)
nicohrubec Oct 27, 2026
70b6218
feat: Export the Node bundler plugins from SDKs that wrap @sentry/nod…
timfish Oct 27, 2026
fea30a2
fix(core): Drop sampled-out errors before they take a promise buffer …
logaretm Oct 27, 2026
7030f21
Remove permissions from settings.json (#25766)
cleptric Oct 27, 2026
fe5b952
feat(server-utils): Emit `execute_tool` spans for Anthropic's `beta.s…
RulaKhaled Oct 27, 2026
86b2c2b
fix(core): Preserve AI proxy property references (#22474)
psh4607 Oct 27, 2026
e13255f
chore: Add external contributor to CHANGELOG.md (#25769)
javascript-sdk-gitflow[bot] Oct 27, 2026
10056d4
test(e2e): Assert source map upload and stripping with a shared helpe…
timfish Oct 27, 2026
1043c1c
fix(server-utils): Cap the runs the LangChain callback handler keeps …
RulaKhaled Oct 27, 2026
9ea9532
docs(changelog): Clarify React Router framework mode minimum in 11.0.…
sentry-junior[bot] Oct 27, 2026
c573f4e
chore: Update PR template and prompt agent to use it (#25763)
s1gr1d Oct 27, 2026
1177c46
chore(deps-dev): Bump zod from 3.25.76 to 4.6.7 (#25655)
dependabot[bot] Oct 27, 2026
a023a7b
feat: Accept `tunnel: true` in `init` to enable the managed tunnel (#…
logaretm Oct 27, 2026
24b8f2e
feat(tanstackstart-react): Serve the managed tunnel from the server e…
logaretm Oct 27, 2026
620f9f8
test: Check that runtimes drop the server spans of managed tunnel req…
logaretm Oct 27, 2026
7ba1c78
feat(sveltekit): Serve the managed tunnel from `sentryHandle` under t…
logaretm Oct 27, 2026
d68032b
feat(nuxt, nitro): Serve the managed tunnel before the app's server m…
logaretm Oct 27, 2026
6cf9887
feat(astro): Serve the managed tunnel from the Sentry middleware (#25…
logaretm Oct 27, 2026
90af3d8
feat(remix): Serve the managed tunnel from the Remix 3 router middlew…
logaretm Oct 27, 2026
6e0e59b
feat(react-router): Serve the managed tunnel from a route in the serv…
logaretm Oct 27, 2026
99314fa
docs: Use dark-mode-aware Sentry logo in READMEs (#25775)
sentry-junior[bot] Oct 27, 2026
a1967fe
feat(solidstart): Serve the managed tunnel on SolidStart v1 (#25423)
logaretm Oct 27, 2026
f8b8d40
fix(core): End node:http client spans when the response is destroyed …
4ktLuffy Oct 27, 2026
a6c28d0
chore: Add external contributor to CHANGELOG.md (#25787)
javascript-sdk-gitflow[bot] Oct 27, 2026
f75f15b
fix(react): Avoid double slashes in manifest route names (#25770)
msonnb Oct 28, 2026
be8a27e
chore: Replace Volta with pnpm-managed node versions (#25689)
sentry-junior[bot] Oct 28, 2026
3cb76b2
test(react-router): Use a separate URL per loader error test in instr…
mydea Oct 28, 2026
7def1fe
fix(browser): Preserve empty stacks in continuous profiles (#25764)
msonnb Oct 28, 2026
a6aa2e2
chore: Add catch-all rule for shared packages in CODEOWNERS (#25789)
msonnb Oct 28, 2026
ba78a68
ci(size-limit): Measure bundles when increases are accepted (#25788)
nicohrubec Oct 28, 2026
8e7a3a9
feat(react-router): Support renderToReadableStream in createSentryHan…
lfantone Oct 28, 2026
ede0062
chore: Add external contributor to CHANGELOG.md (#25791)
javascript-sdk-gitflow[bot] Oct 28, 2026
be6a16f
fix(server-utils): Keep OpenAI streamed tool calls that have no index…
pcbeingused333 Oct 28, 2026
408951e
chore(deps): Bump rrweb to 2.45.0 (#25794)
Lms24 Oct 28, 2026
aaef171
fix(opentelemetry): Convert OpenTelemetry performance.now() timestamp…
mydea Oct 28, 2026
48cfd48
fix(server-utils): Nest Flue runs on Node under the request that disp…
RulaKhaled Oct 28, 2026
5074c24
test(e2e): Add node-flue-send-to-sentry test app (#25550)
RulaKhaled Oct 28, 2026
07c8900
ci: Upload the weekly flaky test report as an artifact (#25814)
sentry-junior[bot] Oct 28, 2026
3c3d423
test(cloudflare): Fix flaky D1 query span naming test (#25810)
sentry-junior[bot] Oct 28, 2026
11c1245
test: Fix unit test timeouts from cold dynamic imports (#25811)
sentry-junior[bot] Oct 28, 2026
3c40df4
ci: Remove temporary pull_request trigger from optional E2E workflow …
sentry-junior[bot] Oct 28, 2026
0b43124
test(nextjs): Raise @opennextjs/cloudflare floor for nextjs-16 (#25682)
mydea Oct 28, 2026
cd780cb
ci: Fail the optional E2E report job when it cannot update the PR com…
mydea Oct 28, 2026
cf1324d
test(e2e): Fix optional Anthropic and OpenAI decisions apps (#25795)
mydea Oct 28, 2026
1ffbccd
fix(browser): resolve request URLs against location.href in tracing (…
kunal649 Oct 28, 2026
73eb37d
fix(server-utils): Use the stored pi-durable session id as conversati…
andreiborza Oct 28, 2026
c5c2a3a
fix(nuxt,nitro): Accept Nitro 3 betas without narrowing peer support …
msonnb Oct 28, 2026
bc102c2
fix(node): Set the eve conversation id on model.started for eve 0.84+…
mydea Oct 28, 2026
90bd261
fix(server-utils): Record AI SDK tool spans for tools run outside its…
mydea Oct 28, 2026
2be8554
test(e2e): Pin @mastra/deployer in node-mastra to match @mastra/core …
mydea Oct 28, 2026
7e6148e
feat: Polish the public tunnel API and export it on Server SDKs (#25783)
logaretm Oct 28, 2026
cad66c7
test: Wire the managed tunnel by hand in Node, Cloudflare and Next.js…
logaretm Oct 28, 2026
e17a480
fix(remix): Drop Remix 3 release candidates from the peer range (#25808)
chargome Oct 28, 2026
6efffd8
test(remix): Cover prefetched navigations in the Remix 3 E2E app (#25…
chargome Oct 28, 2026
c6ac34c
test(cloudflare): Bump agents and MCP SDK in cloudflare-mcp-agent e2e…
mydea Oct 28, 2026
90a71e7
feat(server-utils): Instrument together-ai 1.x (#25823)
chargome Oct 28, 2026
0e2b465
chore: Merge master into develop
andreiborza Oct 28, 2026
0455361
Merge pull request #25833 from getsentry/ab/merge-master-into-develop
andreiborza Oct 28, 2026
612654c
meta(changelog): Update changelog for 11.10.0
andreiborza Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function fetchOpenAlerts() {
}

// Resolve a dependency's installed directory, preferring the consumer's nested node_modules and
// falling back to the hoisted root node_modules (`node-linker=hoisted` in .npmrc hoists most deps to the root).
// falling back to the hoisted root node_modules (`nodeLinker: hoisted` in pnpm-workspace.yaml hoists most deps to the root).
function resolveDepDir(name, baseDir) {
const candidates = [join(baseDir, 'node_modules', name), join(REPO_ROOT, 'node_modules', name)];
return candidates.find(dir => existsSync(join(dir, 'package.json')));
Expand Down
2 changes: 1 addition & 1 deletion .claude/CLOUD.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ These cannot live in the repo and must be set once per environment:

## Notes

- Node/pnpm versions come from `package.json` (Volta locally). In the cloud we use the sandbox Node runtime, and the setup script installs the pinned pnpm version when the sandbox has none.
- Node.js/pnpm versions come from `package.json` (`devEngines.runtime` and `packageManager`, managed by pnpm locally). In the cloud we use the sandbox Node.js runtime, and the setup script installs the pinned pnpm version when the sandbox has none.
- The full production `pnpm run build` is not run at startup; `build:dev` (transpile + types) is enough for editing and running unit tests. Run `pnpm run build` manually if you need bundles.
32 changes: 0 additions & 32 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,5 @@
]
}
]
},
"permissions": {
"allow": [
"Bash(find:*)",
"Bash(ls:*)",
"Bash(git status:*)",
"Bash(git log:*)",
"Bash(git diff:*)",
"Bash(git show:*)",
"Bash(git branch:*)",
"Bash(git remote:*)",
"Bash(git tag:*)",
"Bash(git stash list:*)",
"Bash(git rev-parse:*)",
"Bash(gh pr view:*)",
"Bash(gh pr list:*)",
"Bash(gh pr checks:*)",
"Bash(gh pr diff:*)",
"Bash(gh issue view:*)",
"Bash(gh issue list:*)",
"Bash(gh run view:*)",
"Bash(gh run list:*)",
"Bash(gh run logs:*)",
"Bash(gh repo view:*)",
"Bash(pnpm:*)",
"WebFetch(domain:github.com)",
"WebFetch(domain:docs.sentry.io)",
"WebFetch(domain:develop.sentry.dev)",
"Bash(grep:*)",
"Bash(mv:*)"
],
"deny": []
}
}
4 changes: 4 additions & 0 deletions .cursor/BUGBOT.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ Keep reviews high-signal. Prefer actionable, high-confidence findings over specu
- When calling any `startSpan` API (`startInactiveSpan`, `startSpanManual`, etc), always ensure that the following span attributes are set:
- `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN` (`'sentry.origin'`) with a proper span origin
- a proper origin must only contain [a-z], [A-Z], [0-9], `_` and `.` characters.
- a proper origin has at most four parts, `<type>.<category>.<integration_name>.<integration_part>`, and must not skip a part. `type` is `auto` or `manual`.
- `category` must be a span op category (e.g. `http`, `db`, `queue`, `function`, `ai`, `ui`, `rpc`), matching the span's op. Flag origins that put a library or vendor in the category slot (e.g. `auto.kafkajs.producer` instead of `auto.queue.kafkajs.producer`).
- the origin identifies the integration, not the tooling behind it. Flag leftover implementation markers like `otel` or `orchestrion` used as a part.
- flag any non-conforming origin values as invalid and link to the trace origin specification (https://develop.sentry.dev/sdk/telemetry/traces/trace-origin/)
- `SEMANTIC_ATTRIBUTE_SENTRY_OP` (`'sentry.op'`) with a proper span op
- Span ops should be lower case only, and use snake_case. The `.` character is used to delimit op parts.
Expand Down Expand Up @@ -78,6 +81,7 @@ Keep reviews high-signal. Prefer actionable, high-confidence findings over specu
- What to do instead: Use an existing reference to the scope or client. For example, this is possible in most `Integration` hooks.
- Flag hard-coded attribute names and span ops (e.g. `'sentry.origin'`, `'sentry.op'`, `'http.request.method'`, `'db.system.name'`) when `@sentry/conventions` exports a constant for them. Use the constant from `@sentry/conventions/attributes` (e.g. `SENTRY_ORIGIN`, `SENTRY_OP`) or `@sentry/conventions/op` instead. Do not flag values that have no constant in `@sentry/conventions`.
- Flag unnecessary `span.setAttribute(s)` calls: If data is already available at span start, it must be set via the `attributes` option of `startSpan`, `startSpanManual`, `startInactiveSpan` or `startIdleSpan` calls. This ensures that as much context as possible is available when `tracesSampler` or `ignoreSpans` SDK options are applied. If a `span.setAttribute(s)` call happens at a later time than right after span start and the attribute value can only be computed at that time, do not flag it.
- Flag a new option on an integration for incoming HTTP requests that is not in `ServerRequestOptions` (`packages/core/src/integrations/http/server-request-options.ts`), when it applies to more than one runtime. These integrations are Node `httpIntegration`, Deno `denoHttpIntegration` and `denoServeIntegration`, Bun `bunHttpServerIntegration` and `bunServerIntegration`, and Cloudflare `httpServerIntegration`. Add the option to `ServerRequestOptions`, then support it in each runtime or list it as unsupported in that runtime's `CheckServerRequestOptions` check. Also flag a runtime option that matches a shared option in purpose but has a different name or meaning.

### Code quality

Expand Down
8 changes: 4 additions & 4 deletions .cursor/environment.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "Sentry JavaScript SDK Development",
"install": "curl https://get.volta.sh | bash && export VOLTA_HOME=\"$HOME/.volta\" && export PATH=\"$VOLTA_HOME/bin:$PATH\" && export VOLTA_FEATURE_PNPM=1 && pnpm install",
"start": "export VOLTA_HOME=\"$HOME/.volta\" && export PATH=\"$VOLTA_HOME/bin:$PATH\" && export VOLTA_FEATURE_PNPM=1",
"install": "curl -fsSL https://get.pnpm.io/install.sh | sh - && export PNPM_HOME=\"$HOME/.local/share/pnpm\" && export PATH=\"$PNPM_HOME/bin:$PATH\" && pnpm runtime set node 24 -g -y && pnpm install",
"start": "export PNPM_HOME=\"$HOME/.local/share/pnpm\" && export PATH=\"$PNPM_HOME/bin:$PATH\"",
"terminals": [
{
"name": "Development",
"command": "export VOLTA_HOME=\"$HOME/.volta\" && export PATH=\"$VOLTA_HOME/bin:$PATH\" && export VOLTA_FEATURE_PNPM=1 && echo 'Volta setup complete. Node version:' && node --version && echo 'pnpm version:' && pnpm --version",
"description": "Main development terminal with Volta environment configured"
"command": "export PNPM_HOME=\"$HOME/.local/share/pnpm\" && export PATH=\"$PNPM_HOME/bin:$PATH\" && echo 'pnpm setup complete. Node version:' && node --version && echo 'pnpm version:' && pnpm --version",
"description": "Main development terminal with pnpm-managed node"
}
]
}
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Catch-all rule for shared packages
* @getsentry/team-javascript-sdks-browser @getsentry/team-javascript-sdks-server @getsentry/team-javascript-sdks-framework

# Browser, replay, feedback, and related packages
/packages/browser/ @getsentry/team-javascript-sdks-browser
/packages/browser-utils/ @getsentry/team-javascript-sdks-browser
Expand Down
27 changes: 21 additions & 6 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
Before submitting a pull request, please take a look at our
[Contributing](https://github.com/getsentry/sentry-javascript/blob/master/CONTRIBUTING.md) guidelines and verify:
<!--
Read the Contributing guidelines first: https://github.com/getsentry/sentry-javascript/blob/develop/CONTRIBUTING.md

- [ ] If you've added code that should be tested, please add tests.
- [ ] Ensure your code lints and the test suite passes (`pnpm run lint`) & (`pnpm run test`).
- [ ] Link an issue if there is one related to your pull request. If no issue is linked, one will be auto-generated and linked.
Before you request a review:

Closes #issue_link_here
- Add tests for new or changed behavior. `pnpm run lint` and `pnpm run test` pass.
- Fix or dismiss AI review findings.
- Read your own diff first, add inline comments with explanation or where to look closely.
- Large PR? Split or stack it, or describe why you cannot.

- Remove fields that do not apply (e.g. on small PRs).
- External contributors: link an issue where you got a maintainer's go-ahead.
-->

**Why:** <!-- reason behind change, why this approach (no implementation walkthrough), non-obvious decisions/tradeoffs -->

**How to review:** <!-- where to start, what to skim -->

**Unsure about:** <!-- where you want a second opinion -->

Closes #

<!-- Long, AI-written descriptions at the end, inside `<details><summary>AI walkthrough</summary>...</details>` -->
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
12 changes: 11 additions & 1 deletion .github/actions/prepare-e2e-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ inputs:
runs:
using: 'composite'
steps:
# Uses the repo's root node pin for the steps before the app is copied (installing pnpm, `test:prepare`,
# `test:validate`, `ci:copy-to-temp`). The app's own node version is set up after the copy below.
- name: Set up Node
uses: actions/setup-node@v7
with:
node-version-file: 'dev-packages/e2e-tests/test-applications/${{ inputs.test-application }}/package.json'
node-version-file: 'package.json'
- name: Set up Bun
if:
inputs.test-application == 'node-exports-test-app' || contains(inputs.test-application, 'bun') || inputs.runtime
Expand Down Expand Up @@ -102,6 +104,14 @@ runs:
shell: bash
working-directory: dev-packages/e2e-tests

# Reads the node version that `ci:copy-to-temp` wrote into the copied app's `devEngines.runtime`: the app's own pin
# if it has one, otherwise the one inherited from the repo root. setup-node can't look up parent directories, so the
# temp copy has to carry the resolved version.
- name: Set up Node for the E2E app
uses: actions/setup-node@v7
with:
node-version-file: '${{ runner.temp }}/test-application/package.json'

- name: Add pnpm overrides
run:
pnpm run ci:pnpm-overrides ${{ runner.temp }}/test-application ${{ github.workspace
Expand Down
114 changes: 37 additions & 77 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- release/**
pull_request:
merge_group:
types: [checks_requested]
branches: [develop]
workflow_dispatch:
inputs:
commit:
Expand Down 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 @@ -774,35 +762,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 @@ -814,19 +775,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 @@ -852,11 +800,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 @@ -1085,9 +1028,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 @@ -1117,9 +1061,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 @@ -1128,6 +1073,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 @@ -1155,7 +1117,7 @@ jobs:

# - We skip optional tests on release branches
# - The tests run in optional-e2e.yml, so their failures do not mark the PR as failed. This job only waits for
# them and reports failures in a PR comment.
# them. optional-e2e.yml reports the results in a PR comment.
job_optional_e2e_tests:
name: E2E Tests (optional)
# We only run E2E tests for non-fork PRs because the E2E tests require secrets to work and they can't be accessed from forks
Expand All @@ -1173,7 +1135,6 @@ jobs:
permissions:
contents: read
actions: write
pull-requests: write
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v7
Expand Down Expand Up @@ -1219,7 +1180,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
Loading
Loading