Skip to content

Commit cc7ad7d

Browse files
author
Luca Forstner
authored
ref(core): Extract debug ID sourcemap upload into a separate plugin (#231)
1 parent 66f7971 commit cc7ad7d

File tree

3 files changed

+90
-96
lines changed

3 files changed

+90
-96
lines changed

packages/bundler-plugin-core/src/index.ts

Lines changed: 14 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@ import SentryCli from "@sentry/cli";
22
import { makeMain } from "@sentry/node";
33
import { Span, Transaction } from "@sentry/types";
44
import fs from "fs";
5-
import { glob } from "glob";
65
import MagicString from "magic-string";
7-
import os from "os";
8-
import path from "path";
96
import { createUnplugin, UnpluginOptions } from "unplugin";
10-
import { promisify } from "util";
11-
import { prepareBundleForDebugIdUpload } from "./debug-id";
127
import { NormalizedOptions, normalizeUserOptions, validateOptions } from "./options-mapping";
8+
import { debugIdUploadPlugin } from "./plugins/debug-id-upload";
139
import { getSentryCli } from "./sentry/cli";
1410
import { createLogger, Logger } from "./sentry/logger";
1511
import {
@@ -18,7 +14,6 @@ import {
1814
createNewRelease,
1915
finalizeRelease,
2016
setCommits,
21-
uploadDebugIdSourcemaps,
2217
uploadSourceMaps,
2318
} from "./sentry/releasePipeline";
2419
import {
@@ -183,58 +178,6 @@ export function sentryUnpluginFactory({
183178

184179
try {
185180
if (!unpluginMetaContext.watchMode) {
186-
if (options.sourcemaps?.assets) {
187-
const debugIdChunkFilePaths = (
188-
await glob(options.sourcemaps.assets, {
189-
absolute: true,
190-
nodir: true,
191-
ignore: options.sourcemaps.ignore,
192-
})
193-
).filter((p) => p.endsWith(".js") || p.endsWith(".mjs") || p.endsWith(".cjs"));
194-
195-
if (unpluginMetaContext.framework === "esbuild") {
196-
await Promise.all(
197-
debugIdChunkFilePaths.map(async (debugIdChunkFilePath) => {
198-
const chunkFileContents = await promisify(fs.readFile)(
199-
debugIdChunkFilePath,
200-
"utf-8"
201-
);
202-
203-
const debugId = stringToUUID(chunkFileContents);
204-
205-
const newChunkFileContents = chunkFileContents.replace(
206-
/__SENTRY_DEBUG_ID__/g,
207-
debugId
208-
);
209-
210-
await promisify(fs.writeFile)(
211-
debugIdChunkFilePath,
212-
newChunkFileContents,
213-
"utf-8"
214-
);
215-
})
216-
);
217-
}
218-
219-
const sourceFileUploadFolderPromise = promisify(fs.mkdtemp)(
220-
path.join(os.tmpdir(), "sentry-bundler-plugin-upload-")
221-
);
222-
223-
await Promise.all(
224-
debugIdChunkFilePaths.map(async (chunkFilePath, chunkIndex): Promise<void> => {
225-
await prepareBundleForDebugIdUpload(
226-
chunkFilePath,
227-
await sourceFileUploadFolderPromise,
228-
String(chunkIndex),
229-
logger
230-
);
231-
})
232-
);
233-
234-
tmpUploadFolder = await sourceFileUploadFolderPromise;
235-
await uploadDebugIdSourcemaps(options, ctx, tmpUploadFolder, releaseName ?? "");
236-
}
237-
238181
if (releaseName) {
239182
await createNewRelease(options, ctx, releaseName);
240183
await cleanArtifacts(options, ctx, releaseName);
@@ -286,6 +229,19 @@ export function sentryUnpluginFactory({
286229
plugins.push(releaseInjectionPlugin(injectionCode));
287230
}
288231

232+
if (!unpluginMetaContext.watchMode && options.sourcemaps?.assets !== undefined) {
233+
plugins.push(
234+
debugIdUploadPlugin({
235+
assets: options.sourcemaps.assets,
236+
ignore: options.sourcemaps.ignore,
237+
dist: options.dist,
238+
releaseName: releaseName,
239+
logger: logger,
240+
cliInstance: cli,
241+
})
242+
);
243+
}
244+
289245
if (options.sourcemaps?.assets) {
290246
plugins.push(debugIdInjectionPlugin());
291247
}

packages/bundler-plugin-core/src/debug-id.ts renamed to packages/bundler-plugin-core/src/plugins/debug-id-upload.ts

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,78 @@
1-
import * as fs from "fs";
2-
import * as path from "path";
1+
import fs from "fs";
2+
import { glob } from "glob";
3+
import os from "os";
4+
import path from "path";
35
import * as util from "util";
4-
import { Logger } from "./sentry/logger";
6+
import { UnpluginOptions } from "unplugin";
7+
import { Logger } from "../sentry/logger";
8+
import { promisify } from "util";
9+
import { SentryCLILike } from "../sentry/cli";
10+
11+
interface DebugIdUploadPluginOptions {
12+
logger: Logger;
13+
cliInstance: SentryCLILike;
14+
assets: string | string[];
15+
ignore?: string | string[];
16+
releaseName?: string;
17+
dist?: string;
18+
}
19+
20+
export function debugIdUploadPlugin({
21+
assets,
22+
ignore,
23+
logger,
24+
cliInstance,
25+
releaseName,
26+
dist,
27+
}: DebugIdUploadPluginOptions): UnpluginOptions {
28+
return {
29+
name: "sentry-debug-id-upload-plugin",
30+
async writeBundle() {
31+
const tmpUploadFolder = await fs.promises.mkdtemp(
32+
path.join(os.tmpdir(), "sentry-bundler-plugin-upload-")
33+
);
34+
35+
try {
36+
const debugIdChunkFilePaths = (
37+
await glob(assets, {
38+
absolute: true,
39+
nodir: true,
40+
ignore: ignore,
41+
})
42+
).filter(
43+
(debugIdChunkFilePath) =>
44+
debugIdChunkFilePath.endsWith(".js") ||
45+
debugIdChunkFilePath.endsWith(".mjs") ||
46+
debugIdChunkFilePath.endsWith(".cjs")
47+
);
48+
49+
await Promise.all(
50+
debugIdChunkFilePaths.map(async (chunkFilePath, chunkIndex): Promise<void> => {
51+
await prepareBundleForDebugIdUpload(
52+
chunkFilePath,
53+
tmpUploadFolder,
54+
String(chunkIndex),
55+
logger
56+
);
57+
})
58+
);
59+
60+
await cliInstance.releases.uploadSourceMaps(releaseName ?? "", {
61+
include: [
62+
{
63+
paths: [tmpUploadFolder],
64+
rewrite: false,
65+
dist: dist,
66+
},
67+
],
68+
useArtifactBundle: true,
69+
});
70+
} finally {
71+
void fs.promises.rm(tmpUploadFolder, { recursive: true, force: true });
72+
}
73+
},
74+
};
75+
}
576

677
export async function prepareBundleForDebugIdUpload(
778
bundleFilePath: string,
@@ -11,7 +82,7 @@ export async function prepareBundleForDebugIdUpload(
1182
) {
1283
let bundleContent;
1384
try {
14-
bundleContent = await util.promisify(fs.readFile)(bundleFilePath, "utf8");
85+
bundleContent = await promisify(fs.readFile)(bundleFilePath, "utf8");
1586
} catch (e) {
1687
logger.warn(`Could not read bundle to determine debug ID and source map: ${bundleFilePath}`);
1788
return;
@@ -24,7 +95,7 @@ export async function prepareBundleForDebugIdUpload(
2495
}
2596

2697
bundleContent += `\n//# debugId=${debugId}`;
27-
const writeSourceFilePromise = util.promisify(fs.writeFile)(
98+
const writeSourceFilePromise = fs.promises.writeFile(
2899
path.join(uploadFolder, `${uniqueUploadName}.js`),
29100
bundleContent,
30101
"utf-8"

packages/bundler-plugin-core/src/sentry/releasePipeline.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -86,39 +86,6 @@ export async function uploadSourceMaps(
8686
ctx.logger.info("Successfully uploaded source maps.");
8787
}
8888

89-
export async function uploadDebugIdSourcemaps(
90-
options: NormalizedOptions,
91-
ctx: BuildContext,
92-
folderPathToUpload: string,
93-
releaseName: string
94-
): Promise<void> {
95-
const span = addSpanToTransaction(ctx, "function.plugin.upload_debug_id_sourcemaps");
96-
ctx.logger.info("Uploading debug ID Sourcemaps.");
97-
98-
// Since our internal include entries contain all top-level sourcemaps options,
99-
// we only need to pass the include option here.
100-
try {
101-
await ctx.cli.releases.uploadSourceMaps(releaseName, {
102-
include: [
103-
{
104-
paths: [folderPathToUpload],
105-
rewrite: false,
106-
dist: options.dist,
107-
},
108-
],
109-
useArtifactBundle: true,
110-
});
111-
} catch (e) {
112-
ctx.hub.captureException(new Error("CLI Error: Uploading debug ID source maps failed"));
113-
throw e;
114-
} finally {
115-
span?.finish();
116-
}
117-
118-
ctx.hub.addBreadcrumb({ level: "info", message: "Successfully uploaded debug ID source maps." });
119-
ctx.logger.info("Successfully uploaded debug ID source maps.");
120-
}
121-
12289
export async function setCommits(
12390
options: NormalizedOptions,
12491
ctx: BuildContext,

0 commit comments

Comments
 (0)