Skip to content

Commit 4621e22

Browse files
committed
fix: Always delete files when sourcemaps.filesToDeleteAfterUpload is set
1 parent 929451e commit 4621e22

File tree

4 files changed

+77
-35
lines changed

4 files changed

+77
-35
lines changed

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

+3-32
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ interface DebugIdUploadPluginOptions {
2424
handleRecoverableError: (error: unknown) => void;
2525
sentryHub: Hub;
2626
sentryClient: NodeClient;
27-
filesToDeleteAfterUpload?: string | string[];
27+
deleteFilesUpForDeletion: () => Promise<void>;
2828
sentryCliOptions: {
2929
url: string;
3030
authToken: string;
@@ -47,7 +47,7 @@ export function createDebugIdUploadFunction({
4747
sentryClient,
4848
sentryCliOptions,
4949
rewriteSourcesHook,
50-
filesToDeleteAfterUpload,
50+
deleteFilesUpForDeletion,
5151
}: DebugIdUploadPluginOptions) {
5252
return async (buildArtifactPaths: string[]) => {
5353
const artifactBundleUploadTransaction = sentryHub.startTransaction({
@@ -180,36 +180,7 @@ export function createDebugIdUploadFunction({
180180
logger.info("Successfully uploaded source maps to Sentry");
181181
}
182182

183-
if (filesToDeleteAfterUpload) {
184-
const deleteGlobSpan = artifactBundleUploadTransaction.startChild({
185-
description: "delete-glob",
186-
});
187-
const filePathsToDelete = await glob(filesToDeleteAfterUpload, {
188-
absolute: true,
189-
nodir: true,
190-
});
191-
deleteGlobSpan.finish();
192-
193-
filePathsToDelete.forEach((filePathToDelete) => {
194-
logger.debug(`Deleting asset after upload: ${filePathToDelete}`);
195-
});
196-
197-
const deleteSpan = artifactBundleUploadTransaction.startChild({
198-
description: "delete-files-after-upload",
199-
});
200-
await Promise.all(
201-
filePathsToDelete.map((filePathToDelete) =>
202-
fs.promises.rm(filePathToDelete, { force: true }).catch((e) => {
203-
// This is allowed to fail - we just don't do anything
204-
logger.debug(
205-
`An error occured while attempting to delete asset: ${filePathToDelete}`,
206-
e
207-
);
208-
})
209-
)
210-
);
211-
deleteSpan.finish();
212-
}
183+
await deleteFilesUpForDeletion();
213184
} catch (e) {
214185
sentryHub.withScope((scope) => {
215186
scope.setSpan(artifactBundleUploadTransaction);

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

+40-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
import * as dotenv from "dotenv";
2626
import { glob } from "glob";
2727
import { logger } from "@sentry/utils";
28+
import { fileDeletionPlugin } from "./plugins/sourcemap-deletion";
2829

2930
interface SentryUnpluginFactoryOptions {
3031
releaseInjectionPlugin: (injectionCode: string) => UnpluginOptions;
@@ -180,6 +181,34 @@ export function sentryUnpluginFactory({
180181
})
181182
);
182183

184+
async function deleteFilesUpForDeletion() {
185+
const filesToDeleteAfterUpload =
186+
options.sourcemaps?.filesToDeleteAfterUpload ?? options.sourcemaps?.deleteFilesAfterUpload;
187+
188+
if (filesToDeleteAfterUpload) {
189+
const filePathsToDelete = await glob(filesToDeleteAfterUpload, {
190+
absolute: true,
191+
nodir: true,
192+
});
193+
194+
filePathsToDelete.forEach((filePathToDelete) => {
195+
logger.debug(`Deleting asset after upload: ${filePathToDelete}`);
196+
});
197+
198+
await Promise.all(
199+
filePathsToDelete.map((filePathToDelete) =>
200+
fs.promises.rm(filePathToDelete, { force: true }).catch((e) => {
201+
// This is allowed to fail - we just don't do anything
202+
logger.debug(
203+
`An error occurred while attempting to delete asset: ${filePathToDelete}`,
204+
e
205+
);
206+
})
207+
)
208+
);
209+
}
210+
}
211+
183212
if (options.bundleSizeOptimizations) {
184213
const { bundleSizeOptimizations } = options;
185214
const replacementValues: SentrySDKBuildFlags = {};
@@ -293,12 +322,22 @@ export function sentryUnpluginFactory({
293322
vcsRemote: options.release.vcsRemote,
294323
headers: options.headers,
295324
},
325+
deleteFilesUpForDeletion,
296326
})
297327
);
298328
}
299329

300330
plugins.push(debugIdInjectionPlugin(logger));
301331

332+
plugins.push(
333+
fileDeletionPlugin({
334+
deleteFilesUpForDeletion,
335+
handleRecoverableError: handleRecoverableError,
336+
sentryHub,
337+
sentryClient,
338+
})
339+
);
340+
302341
if (!options.authToken) {
303342
logger.warn(
304343
"No auth token provided. Will not upload source maps. Please set the `authToken` option. You can find information on how to generate a Sentry auth token here: https://docs.sentry.io/api/auth/"
@@ -317,9 +356,7 @@ export function sentryUnpluginFactory({
317356
createDebugIdUploadFunction({
318357
assets: options.sourcemaps?.assets,
319358
ignore: options.sourcemaps?.ignore,
320-
filesToDeleteAfterUpload:
321-
options.sourcemaps?.filesToDeleteAfterUpload ??
322-
options.sourcemaps?.deleteFilesAfterUpload,
359+
deleteFilesUpForDeletion,
323360
dist: options.release.dist,
324361
releaseName: options.release.name,
325362
logger: logger,

packages/bundler-plugin-core/src/plugins/release-management.ts

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface ReleaseManagementPluginOptions {
2727
silent: boolean;
2828
headers?: Record<string, string>;
2929
};
30+
deleteFilesUpForDeletion: () => Promise<void>;
3031
}
3132

3233
export function releaseManagementPlugin({
@@ -41,6 +42,7 @@ export function releaseManagementPlugin({
4142
sentryHub,
4243
sentryClient,
4344
sentryCliOptions,
45+
deleteFilesUpForDeletion,
4446
}: ReleaseManagementPluginOptions): UnpluginOptions {
4547
return {
4648
name: "sentry-debug-id-upload-plugin",
@@ -83,6 +85,8 @@ export function releaseManagementPlugin({
8385
if (deployOptions) {
8486
await cliInstance.releases.newDeploy(releaseName, deployOptions);
8587
}
88+
89+
await deleteFilesUpForDeletion();
8690
} catch (e) {
8791
sentryHub.captureException('Error in "releaseManagementPlugin" writeBundle hook');
8892
await safeFlushTelemetry(sentryClient);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Hub, NodeClient } from "@sentry/node";
2+
import { UnpluginOptions } from "unplugin";
3+
import { safeFlushTelemetry } from "../sentry/telemetry";
4+
5+
interface FileDeletionPlugin {
6+
handleRecoverableError: (error: unknown) => void;
7+
deleteFilesUpForDeletion: () => Promise<void>;
8+
sentryHub: Hub;
9+
sentryClient: NodeClient;
10+
}
11+
12+
export function fileDeletionPlugin({
13+
handleRecoverableError,
14+
sentryHub,
15+
sentryClient,
16+
deleteFilesUpForDeletion,
17+
}: FileDeletionPlugin): UnpluginOptions {
18+
return {
19+
name: "sentry-file-deletion-plugin",
20+
async buildEnd() {
21+
try {
22+
await deleteFilesUpForDeletion();
23+
} catch (e) {
24+
sentryHub.captureException('Error in "sentry-file-deletion-plugin" buildEnd hook');
25+
await safeFlushTelemetry(sentryClient);
26+
handleRecoverableError(e);
27+
}
28+
},
29+
};
30+
}

0 commit comments

Comments
 (0)