diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic-cjs.test.ts index cc4449e10efe..b6497403fc72 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic-cjs.test.ts @@ -35,7 +35,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic.test.ts index cc4449e10efe..b6497403fc72 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/basic.test.ts @@ -35,7 +35,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/release-disabled.test.ts index 214529d8fe34..71eaf7b92ce9 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/esbuild/release-disabled.test.ts @@ -34,7 +34,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { ", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic-cjs.test.ts index ef26f379ba3b..c59af2abe5e4 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic-cjs.test.ts @@ -20,7 +20,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic.test.ts index ef26f379ba3b..c59af2abe5e4 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/basic.test.ts @@ -20,7 +20,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/release-disabled.test.ts index 18e4c8f80f47..3bf5b9b5f855 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rolldown/release-disabled.test.ts @@ -19,7 +19,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles }) => { ", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic-cjs.test.ts index 1d68d3104370..5667c2ea0b02 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic-cjs.test.ts @@ -11,7 +11,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic.test.ts index 1d68d3104370..5667c2ea0b02 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/basic.test.ts @@ -11,7 +11,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/release-disabled.test.ts index b8e6f6b9d32f..051038a480e3 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup3/release-disabled.test.ts @@ -10,7 +10,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles }) => { ", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic-cjs.test.ts index 1d68d3104370..5667c2ea0b02 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic-cjs.test.ts @@ -11,7 +11,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic.test.ts index 1d68d3104370..5667c2ea0b02 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/basic.test.ts @@ -11,7 +11,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/release-disabled.test.ts index b8e6f6b9d32f..051038a480e3 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/rollup4/release-disabled.test.ts @@ -10,7 +10,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles }) => { ", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic-cjs.test.ts index 10e0aad0e5e9..9e086c0dc020 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic-cjs.test.ts @@ -19,7 +19,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic.test.ts index 10e0aad0e5e9..9e086c0dc020 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/basic.test.ts @@ -19,7 +19,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/release-disabled.test.ts index b8a755e78265..a71c289a22b8 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite4/release-disabled.test.ts @@ -18,7 +18,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles }) => { ", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic-cjs.test.ts index 4b334c167dbb..e6d000c44c49 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic-cjs.test.ts @@ -19,7 +19,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic.test.ts index 4b334c167dbb..e6d000c44c49 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/basic.test.ts @@ -19,7 +19,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/release-disabled.test.ts index be2e8688f19a..453c03f9a040 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite7/release-disabled.test.ts @@ -18,7 +18,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles }) => { ", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic-cjs.test.ts index ef26f379ba3b..c59af2abe5e4 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic-cjs.test.ts @@ -20,7 +20,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic.test.ts index ef26f379ba3b..c59af2abe5e4 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/basic.test.ts @@ -20,7 +20,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/release-disabled.test.ts index 18e4c8f80f47..3bf5b9b5f855 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/vite8/release-disabled.test.ts @@ -19,7 +19,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles }) => { ", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic-cjs.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic-cjs.test.ts index baa396d20e70..0bc8f4f2b4e5 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic-cjs.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic-cjs.test.ts @@ -16,7 +16,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic.test.ts index baa396d20e70..0bc8f4f2b4e5 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/basic.test.ts @@ -16,7 +16,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles, runFileInNode }) => { "sentry-cli-mock.json": "["releases","new","CURRENT_SHA"], ["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/release-disabled.test.ts b/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/release-disabled.test.ts index 5f0e210be09d..9d180fc54288 100644 --- a/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/release-disabled.test.ts +++ b/dev-packages/bundler-plugin-integration-tests/fixtures/webpack5/release-disabled.test.ts @@ -15,7 +15,6 @@ test(import.meta.url, ({ runBundler, readOutputFiles }) => { ;", "sentry-cli-mock.json": "["releases","set-commits","CURRENT_SHA","--auto","--ignore-missing"], ["releases","finalize","CURRENT_SHA"], - ["sourcemaps","upload","-p","fake-project","--release","CURRENT_SHA","sentry-bundler-plugin-upload-path","--ignore","node_modules","--no-rewrite"], ", } `); diff --git a/packages/bundler-plugins/src/core/build-plugin-manager.ts b/packages/bundler-plugins/src/core/build-plugin-manager.ts index 0df5d5ddd4ce..e0cb62bd7b61 100644 --- a/packages/bundler-plugins/src/core/build-plugin-manager.ts +++ b/packages/bundler-plugins/src/core/build-plugin-manager.ts @@ -703,6 +703,19 @@ export function createSentryBuildPluginManager( setMeasurement('files', files.length, 'none', prepBundlesSpan); setMeasurement('upload_size', uploadSize, 'byte', prepBundlesSpan); + // Preparation produced no artifacts, meaning none of the + // matched bundles had an associated source map. This almost + // always means source map generation is turned off in the + // bundler, so warn instead of silently reporting success. + if (files.length === 0) { + logger.warn( + `No source maps found for any of the ${debugIdChunkFilePaths.length} matched build ` + + 'artifacts, so no source maps were uploaded to Sentry. This usually means source map ' + + 'generation is not enabled in your bundler. Enable it so Sentry can un-minify your stack traces.', + ); + return; + } + await startSpan({ name: 'upload', scope: sentryScope }, async () => { const cliInstance = createCliInstance(options); await cliInstance.releases.uploadSourceMaps(options.release.name ?? 'undefined', { @@ -717,9 +730,11 @@ export function createSentryBuildPluginManager( live: 'rejectOnError', }); }); - }); - logger.info('Successfully uploaded source maps to Sentry'); + // this must be in the method so that the "no sourcemaps" + // early return doesn't also log success. + logger.info('Successfully uploaded source maps to Sentry'); + }); } } } catch (e) { diff --git a/packages/bundler-plugins/src/core/debug-id-upload.ts b/packages/bundler-plugins/src/core/debug-id-upload.ts index 932f326e1e98..1a09be2df2fd 100644 --- a/packages/bundler-plugins/src/core/debug-id-upload.ts +++ b/packages/bundler-plugins/src/core/debug-id-upload.ts @@ -48,28 +48,40 @@ export async function prepareBundleForDebugIdUpload( const uniqueUploadName = `${debugId}-${chunkIndex}`; bundleContent = addDebugIdToBundleSource(bundleContent, debugId); + + const sourceMapPath = await determineSourceMapPathFromBundle( + bundleFilePath, + bundleContent, + logger, + resolveSourceMapHook, + ); + + // A chunk with a debug ID but no resolvable source map + // (e.g. framework-generated stub chunks that never emit one) can't be + // symbolicated, so uploading its minified source alone accomplishes + // nothing and only makes the uploader warn about a missing source map ref. + // Skip it, unless the source map is inlined into the bundle, in which case + // the source file carries the map itself and must still be uploaded. + if (!sourceMapPath && !bundleHasInlineSourceMap(bundleContent)) { + logger.debug(`Not uploading bundle without a source map: ${bundleFilePath}`); + return; + } + const writeSourceFilePromise = fs.promises.writeFile( path.join(uploadFolder, `${uniqueUploadName}.js`), bundleContent, 'utf-8', ); - const writeSourceMapFilePromise = determineSourceMapPathFromBundle( - bundleFilePath, - bundleContent, - logger, - resolveSourceMapHook, - ).then(async sourceMapPath => { - if (sourceMapPath) { - await prepareSourceMapForDebugIdUpload( + const writeSourceMapFilePromise = sourceMapPath + ? prepareSourceMapForDebugIdUpload( sourceMapPath, path.join(uploadFolder, `${uniqueUploadName}.js.map`), debugId, rewriteSourcesHook, logger, - ); - } - }); + ) + : Promise.resolve(); await writeSourceFilePromise; await writeSourceMapFilePromise; @@ -107,6 +119,16 @@ function addDebugIdToBundleSource(bundleSource: string, debugId: string): string } } +/** + * Whether the bundle carries its source map inlined as `sourceMappingURL=data:` + * URI, rather than referencing a separate `.map` file. Such bundles must still + * be uploaded even when no `.map` file is found, because the source file itself + * contains the map. + */ +function bundleHasInlineSourceMap(bundleSource: string): boolean { + return /^\s*\/\/# sourceMappingURL=data:/m.test(bundleSource); +} + /** * Applies a set of heuristics to find the source map for a particular bundle. * diff --git a/packages/bundler-plugins/test/core/build-plugin-manager.test.ts b/packages/bundler-plugins/test/core/build-plugin-manager.test.ts index 283030370d68..ea88ab067079 100644 --- a/packages/bundler-plugins/test/core/build-plugin-manager.test.ts +++ b/packages/bundler-plugins/test/core/build-plugin-manager.test.ts @@ -417,6 +417,44 @@ describe('createSentryBuildPluginManager', () => { live: 'rejectOnError', }); }); + + // Skipping mapless chunks (so the CLI stops warning per stub chunk) must + // not swallow the signal that source map generation is disabled. + it('warns and skips upload when none of the matched bundles have a source map', async () => { + mockCliUploadSourceMaps.mockResolvedValue(undefined); + + // Bundles were found, but preparation produced no artifacts + mockGlobFiles.mockResolvedValue(['/app/dist/a.js', '/app/dist/b.js']); + + vi.spyOn(fs.promises, 'mkdtemp').mockResolvedValue('/tmp/sentry-upload-empty'); + vi.spyOn(fs.promises, 'readdir').mockResolvedValue([] as never); + vi.spyOn(fs.promises, 'stat').mockResolvedValue({ size: 0 } as fs.Stats); + vi.spyOn(fs.promises, 'rm').mockResolvedValue(undefined as never); + + mockPrepareBundleForDebugIdUpload.mockResolvedValue(undefined); + + const manager = createSentryBuildPluginManager( + { + authToken: 't', + org: 'o', + project: 'p', + release: { name: 'some-release-name', dist: '1' }, + sourcemaps: { assets: ['/app/dist/**/*'] }, + }, + { buildTool: 'webpack', loggerPrefix: '[sentry-webpack-plugin]' }, + ); + + const warnSpy = vi.spyOn(manager.logger, 'warn'); + + await manager.uploadSourcemaps(['/unused']); + + expect(warnSpy).toHaveBeenCalledTimes(1); + expect(warnSpy.mock.calls[0]?.[0]).toMatch(/source map generation is not enabled/); + // Nothing to upload, so the CLI upload must be skipped entirely. + expect(mockCliUploadSourceMaps).not.toHaveBeenCalled(); + + vi.restoreAllMocks(); + }); }); describe('injectDebugIds', () => { @@ -477,9 +515,10 @@ describe('createSentryBuildPluginManager', () => { mockPrepareBundleForDebugIdUpload.mockResolvedValue(undefined); mockCliUploadSourceMaps.mockResolvedValue(undefined); - // Mock fs operations needed for temp folder upload path + // Mock fs operations needed for temp folder upload path. `readdir` returns a prepared artifact + // so the upload path runs (an empty temp folder warns and skips the upload instead). vi.spyOn(fs.promises, 'mkdtemp').mockResolvedValue('/tmp/sentry-test'); - vi.spyOn(fs.promises, 'readdir').mockResolvedValue([]); + vi.spyOn(fs.promises, 'readdir').mockResolvedValue(['bundle.js', 'bundle.js.map'] as never); vi.spyOn(fs.promises, 'stat').mockResolvedValue({ size: 1000 } as fs.Stats); vi.spyOn(fs.promises, 'rm').mockResolvedValue(undefined); }); diff --git a/packages/bundler-plugins/test/core/debug-id-upload.test.ts b/packages/bundler-plugins/test/core/debug-id-upload.test.ts index c14dfe7e3651..6e1ac6940f29 100644 --- a/packages/bundler-plugins/test/core/debug-id-upload.test.ts +++ b/packages/bundler-plugins/test/core/debug-id-upload.test.ts @@ -61,4 +61,48 @@ describe('prepareBundleForDebugIdUpload', () => { expect(capturedContexts).toHaveLength(1); expect(capturedContexts[0]!.mapDir).toBe(bundleDir); }); + + const debugIdSnippet = (debugId: string): string => + `;!function(){try{var e="undefined"!=typeof window?window:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="${debugId}",e._sentryDebugIdIdentifier="sentry-dbid-${debugId}")}catch(e){}}();`; + + const noopRewriteHook: RewriteSourcesHook = source => source; + const makeLogger = (): Logger => + ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }) as unknown as Logger; + + it('does not write an upload artifact for a chunk that has no source map', async () => { + const bundleDir = path.join(tmpDir, 'src'); + const uploadDir = path.join(tmpDir, 'upload'); + fs.mkdirSync(bundleDir, { recursive: true }); + fs.mkdirSync(uploadDir, { recursive: true }); + + const debugId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; + const bundlePath = path.join(bundleDir, 'stub.js'); + // A stub chunk: debug ID snippet but no code and no sourceMappingURL / adjacent `.map`. + fs.writeFileSync(bundlePath, `"use strict";\n${debugIdSnippet(debugId)}`); + + await prepareBundleForDebugIdUpload(bundlePath, uploadDir, 0, makeLogger(), noopRewriteHook, undefined); + + expect(fs.readdirSync(uploadDir)).toEqual([]); + }); + + it('writes an upload artifact for a chunk whose source map is inlined', async () => { + const bundleDir = path.join(tmpDir, 'src'); + const uploadDir = path.join(tmpDir, 'upload'); + fs.mkdirSync(bundleDir, { recursive: true }); + fs.mkdirSync(uploadDir, { recursive: true }); + + const debugId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; + const bundlePath = path.join(bundleDir, 'inline.js'); + const inlineMap = Buffer.from(JSON.stringify({ version: 3, sources: ['a.ts'], mappings: 'AAAA' })).toString( + 'base64', + ); + fs.writeFileSync( + bundlePath, + `"use strict";\n// code\n${debugIdSnippet(debugId)}\n//# sourceMappingURL=data:application/json;base64,${inlineMap}`, + ); + + await prepareBundleForDebugIdUpload(bundlePath, uploadDir, 0, makeLogger(), noopRewriteHook, undefined); + + expect(fs.readdirSync(uploadDir)).toEqual([`${debugId}-0.js`]); + }); });