Skip to content

Add Sentry source map upload for browser builds - #4611

Merged
liamdebeasi merged 7 commits into
mainfrom
ai_main_de7ba29bd49e404da98c
Sep 9, 2026
Merged

Add Sentry source map upload for browser builds#4611
liamdebeasi merged 7 commits into
mainfrom
ai_main_de7ba29bd49e404da98c

Conversation

@liamdebeasi

@liamdebeasi liamdebeasi commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for uploading sourcemaps to sentry during the build step.


Edit in Builder  Preview


To clone this PR locally use the Github CLI with command gh pr checkout 4611

You can tag me at @BuilderIO for anything you want me to fix or change

@builder-io-integration builder-io-integration Bot changed the title Update from the Builder.io agent Add Sentry source map upload for browser builds Sep 9, 2026
builder-io-integration[bot]

This comment was marked as outdated.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Here's a visual recap of what changed:

Visual recap

Open the full interactive recap

@liamdebeasi

Copy link
Copy Markdown
Contributor Author

@builderio-bot look at latest PR feedback and fix anything you agree with. Be skeptical. Reply to every comment (directly on the comment thread of each comment) if you fixed it or not and why

@builder-io-integration

Copy link
Copy Markdown
Contributor

All 169 pass, typecheck clean, oxlint clean. Summary of what I did with the 5 review comments:

# Severity Verdict Action
Return type / TypeError 🔴 Rejected Ran the actual installed @sentry/vite-plugin@5.4.0 — it genuinely returns an array. Premise was false; replied with evidence, no code change.
Env not threaded through loadEnv 🟡 (3/3 agents) Fixed Added resolveAgentNativeRuntimeEnv() helper; both the sourcemap flag and plugin creation now read the merged .env-file + process.env value instead of raw process.env.
Wrong cleanup outDir 🟡 (2/3) Resolved as side effect Moot once the cleanup mechanism itself was removed (see next row).
Numeric SENTRY_PROJECT_ID as slug 🟡 (1/3) Fixed Removed it from the project-slug fallback chain; falls back to no-op instead of targeting the wrong project.
Fail-open swallows upload error but still deletes local maps 🟡 (1/3) Fixed Traced the actual bundler-plugin-core source and confirmed the cleanup runs unconditionally regardless of upload success. Removed filesToDeleteAfterUpload — maps now stay in dist/ (still hidden from sourceMappingURL) rather than risking losing both copies.

Replied to all 5 comment threads on PR #4611 explaining the verdict and reasoning for each, pushed the fixes, and confirmed 169 tests + typecheck + lint all pass.



🟢 Addressed all 5 PR review comments — 4 fixed (env threading, project slug, unsafe map deletion, moot outDir issue) and 1 rejected with verified evidence (array-return claim was empirically false); replied on every thread, 169 tests passing.

@builder-io-integration builder-io-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder reviewed your changes and found 2 potential issues 🟡

Review Details

Incremental Code Review Summary

This update correctly addresses four previously reported configuration issues: it now loads Sentry settings from Vite env files, no longer treats the numeric project ID as a slug, removes unconditional post-upload map deletion, and removes the incorrect fixed cleanup directory. Those previously open comments were resolved where the fixes were verified. The original plugin-shape issue remains open and was intentionally not reposted.

New Findings

  • 🟡 MEDIUM — Plugin creation still chooses development or production from process.env.NODE_ENV before Vite supplies the actual ConfigEnv.mode. Custom modes, and even normal builds where NODE_ENV is unset, can make source-map generation and plugin activation disagree.
  • 🟡 MEDIUM — The upload release uses AGENT_NATIVE_BUILD_ID from Vite-loaded env files, while the browser bundle's injected build ID still comes from process.env. File-only build IDs therefore produce different Sentry releases and prevent symbolication.

The implementation has good fail-open behavior and improved env/config coverage, but these two mode/build-ID consistency issues should be fixed before approval.

🧪 Browser testing: Skipped — PR only modifies build tooling, source-map upload configuration, and analytics initialization; there is no user-facing UI flow to verify.

Comment on lines +3636 to +3638
const runtimeEnv = resolveAgentNativeRuntimeEnv(
process.cwd(),
process.env.NODE_ENV === "production" ? "production" : "development",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Resolve Sentry configuration using Vite's selected mode

createAgentNativePlugins is constructed before Vite's config hook receives the actual mode and chooses only production or development from process.env.NODE_ENV. For vite build --mode staging (and normal builds where NODE_ENV is unset), the later config hook can load Sentry settings from one mode while the already-created plugin list was resolved from another, causing hidden maps to be generated without an upload plugin or enabling uploads in the wrong mode. Use the actual Vite mode consistently for both env loading and plugin creation.

Additional Info
Reported independently by all 3 review agents. This is a new issue distinct from the resolved general env-file loading issue.

Fix in Builder

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed. createAgentNativePlugins runs synchronously before Vite's config hook resolves the real mode, so it previously always guessed production/development from NODE_ENV. Added resolveEagerAgentNativeMode(), which checks process.argv for --mode/-m (the same flag Vite's own CLI reads) before falling back to the NODE_ENV guess, and used it both for the eager plugin-list construction and as createAgentNativeConfig's mode default. This repo's own agent-native build never passes a custom --mode (it forces NODE_ENV=production instead), so the guess and Vite's real resolved mode already always agreed on our own build path — but this closes the gap for anyone using the agentNative() preset directly with vite build --mode staging, which is exactly the scenario described.

Comment on lines +50 to +55
return {
authToken,
org,
project,
url: firstNonEmpty(env.SENTRY_URL),
release: resolveSentryClientRelease(env),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Keep the uploaded release aligned with the browser build release

The upload release derives its build ID from the merged Vite env, which can include AGENT_NATIVE_BUILD_ID from .env.<mode>, but createAgentNativeConfig still injects __AGENT_NATIVE_BUILD_ID__ using process.env. With a file-only build ID, source maps upload under one release while browser events report another, so Sentry cannot symbolicate them. Resolve the build ID once from the same mode-aware env and use it for both the injected client value and upload release.

Additional Info
Reported independently by all 3 review agents. This is a new release-consistency issue introduced by using Vite-loaded env for upload configuration.

Fix in Builder

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed — this was a real bug, and it directly contradicted this file's own header comment claiming the two releases can't drift apart. client.ts was computing the browser's embedded __AGENT_NATIVE_BUILD_ID__ from raw process.env, while resolveSentryClientRelease() here resolves from the merged runtimeEnv (workspace + app .env files + process.env). If AGENT_NATIVE_BUILD_ID/DEPLOY_ID/etc. was only set via a dotenv file and not exported to the shell, the browser SDK would report one release while source maps uploaded under another, and neither would resolve. Fixed by making the build-id resolution in client.ts read the same runtimeEnv instead of process.env.

@netlify

This comment has been minimized.

builder-io-integration[bot]

This comment was marked as outdated.

builder-io-integration[bot]

This comment was marked as outdated.

@liamdebeasi

Copy link
Copy Markdown
Contributor Author

@builderio-bot look at latest PR feedback and fix anything you agree with. Be skeptical. Reply to every comment (directly on the comment thread of each comment) if you fixed it or not and why

@liamdebeasi
liamdebeasi requested review from a team and enzoames and removed request for a team September 9, 2026 19:37
@builder-io-integration

Copy link
Copy Markdown
Contributor

That worked. Now the remaining 4 replies.

builder-io-integration[bot]

This comment was marked as outdated.

@liamdebeasi
liamdebeasi force-pushed the ai_main_de7ba29bd49e404da98c branch from e625bb2 to 550b999 Compare September 9, 2026 19:59

@builder-io-integration builder-io-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder reviewed your changes and found 2 potential issues 🔴

Review Details

Incremental Code Review Summary

This revision fixes the prior failed-upload exposure: the upload path now rejects the build and the success path removes generated maps. That stale failure-path comment was resolved. The earlier Vite-mode and release/build-ID consistency comments remain unresolved and were intentionally not reposted.

New Findings

  • 🔴 HIGH — Fleet-wide shell Sentry credentials have regressed: template .env values are again parsed after shell values and overwrite them, so a stale/local token or project can be propagated during a fleet sync.
  • 🟡 MEDIUM — The new cleanup plugin recursively deletes every .map file in the output directory, not only maps uploaded by Sentry. This can remove CSS/other map artifacts and explicit user-requested public maps that Sentry never uploaded.

The build-failure behavior and build-only credential scope are improvements, but these new credential-precedence and over-broad-cleanup issues should be fixed before merge.

🧪 Browser testing: Skipped — PR only modifies build tooling, deployment environment synchronization, and analytics/source-map configuration; there is no user-facing UI flow to verify.

Comment thread scripts/sync-template-netlify-env.ts
Comment thread packages/core/src/vite/sentry-source-maps.ts
@liamdebeasi
liamdebeasi enabled auto-merge (squash) September 9, 2026 20:05
@liamdebeasi
liamdebeasi merged commit b3262c3 into main Sep 9, 2026
48 checks passed
@liamdebeasi
liamdebeasi deleted the ai_main_de7ba29bd49e404da98c branch September 9, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants