From d5f04eacffdedc40f73a99966fde0c30cc2a2e2a Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Tue, 2 Sep 2025 17:02:11 +0200 Subject: [PATCH 1/2] feat: Extend deploy option to allow opting out of automatic deploy creation --- .../src/options-mapping.ts | 4 +- packages/bundler-plugin-core/src/types.ts | 4 +- .../test/option-mappings.test.ts | 89 ++++++++++++++++++- .../src/generate-documentation-table.ts | 3 +- 4 files changed, 95 insertions(+), 5 deletions(-) diff --git a/packages/bundler-plugin-core/src/options-mapping.ts b/packages/bundler-plugin-core/src/options-mapping.ts index 3057c8af..62035292 100644 --- a/packages/bundler-plugin-core/src/options-mapping.ts +++ b/packages/bundler-plugin-core/src/options-mapping.ts @@ -51,7 +51,7 @@ export type NormalizedOptions = { time?: number; name?: string; url?: string; - }; + } | false; uploadLegacySourcemaps?: string | IncludeEntry | Array; }; bundleSizeOptimizations: @@ -195,7 +195,7 @@ export function validateOptions(options: NormalizedOptions, logger: Logger): boo } } - if (options.release?.deploy && !options.release?.deploy.env) { + if (options.release?.deploy && typeof options.release.deploy === "object" && !options.release.deploy.env) { logger.error( "The `deploy` option was specified but is missing the required `env` property.", "Please set the `env` property." diff --git a/packages/bundler-plugin-core/src/types.ts b/packages/bundler-plugin-core/src/types.ts index 81862a52..3d92e380 100644 --- a/packages/bundler-plugin-core/src/types.ts +++ b/packages/bundler-plugin-core/src/types.ts @@ -239,8 +239,10 @@ export interface Options { /** * Configuration for adding deployment information to the release in Sentry. + * + * Set to `false` to disable automatic deployment detection and creation. */ - deploy?: DeployOptions; + deploy?: DeployOptions | false; /** * Legacy method of uploading source maps. (not recommended unless necessary) diff --git a/packages/bundler-plugin-core/test/option-mappings.test.ts b/packages/bundler-plugin-core/test/option-mappings.test.ts index f233e1e7..ae0fc661 100644 --- a/packages/bundler-plugin-core/test/option-mappings.test.ts +++ b/packages/bundler-plugin-core/test/option-mappings.test.ts @@ -110,6 +110,86 @@ describe("normalizeUserOptions()", () => { expect(normalizeUserOptions(options).telemetry).toBe(true); } ); + + describe("Vercel deploy detection", () => { + const originalEnv = process.env; + + beforeEach(() => { + process.env = { ...originalEnv }; + }); + + afterEach(() => { + process.env = originalEnv; + }); + + test("should automatically create deploy config when Vercel env vars are present", () => { + process.env["VERCEL"] = "1"; + process.env["VERCEL_TARGET_ENV"] = "production"; + process.env["VERCEL_URL"] = "my-app.vercel.app"; + + const userOptions: Options = { + org: "my-org", + project: "my-project", + authToken: "my-auth-token", + release: { name: "my-release" }, + }; + + const normalizedOptions = normalizeUserOptions(userOptions); + + expect(normalizedOptions.release.deploy).toEqual({ + env: "vercel-production", + url: "https://my-app.vercel.app", + }); + }); + + test("should not create deploy config when deploy is explicitly set to false", () => { + process.env["VERCEL"] = "1"; + process.env["VERCEL_TARGET_ENV"] = "production"; + process.env["VERCEL_URL"] = "my-app.vercel.app"; + + const userOptions: Options = { + org: "my-org", + project: "my-project", + authToken: "my-auth-token", + release: { name: "my-release", deploy: false }, + }; + + const normalizedOptions = normalizeUserOptions(userOptions); + + expect(normalizedOptions.release.deploy).toBe(false); + }); + + test("should not override manually provided deploy config", () => { + process.env["VERCEL"] = "1"; + process.env["VERCEL_TARGET_ENV"] = "production"; + process.env["VERCEL_URL"] = "my-app.vercel.app"; + + const manualDeployConfig = { env: "custom-env", name: "custom-deploy" }; + const userOptions: Options = { + org: "my-org", + project: "my-project", + authToken: "my-auth-token", + release: { name: "my-release", deploy: manualDeployConfig }, + }; + + const normalizedOptions = normalizeUserOptions(userOptions); + + expect(normalizedOptions.release.deploy).toEqual(manualDeployConfig); + }); + + test("should not create deploy config when Vercel env vars are missing", () => { + const userOptions: Options = { + org: "my-org", + project: "my-project", + authToken: "my-auth-token", + release: { name: "my-release" }, + }; + + const normalizedOptions = normalizeUserOptions(userOptions); + + expect(normalizedOptions.release.deploy).toBeUndefined(); + }); + }); }); describe("validateOptions", () => { @@ -164,7 +244,14 @@ describe("validateOptions", () => { }); it("should return `true` if `deploy`is set and `env` is provided", () => { - const options = { deploy: { env: "my-env" } } as Partial; + const options = { release: { deploy: { env: "my-env" } } } as Partial; + + expect(validateOptions(options as unknown as NormalizedOptions, mockedLogger)).toBe(true); + expect(mockedLogger.error).not.toHaveBeenCalled(); + }); + + it("should return `true` if `deploy` is set to `false`", () => { + const options = { release: { deploy: false } } as Partial; expect(validateOptions(options as unknown as NormalizedOptions, mockedLogger)).toBe(true); expect(mockedLogger.error).not.toHaveBeenCalled(); diff --git a/packages/dev-utils/src/generate-documentation-table.ts b/packages/dev-utils/src/generate-documentation-table.ts index 3a4529c4..1757ffe9 100644 --- a/packages/dev-utils/src/generate-documentation-table.ts +++ b/packages/dev-utils/src/generate-documentation-table.ts @@ -221,8 +221,9 @@ Use the \`debug\` option to print information about source map resolution. }, { name: "deploy", + type: "DeployOptions | false", fullDescription: - "Configuration for adding deployment information to the release in Sentry.", + "Configuration for adding deployment information to the release in Sentry.\n\nSet to `false` to disable automatic deployment detection and creation (e.g., when deploying on Vercel).", children: [ { name: "env", From 54b06e160fed4e37728d38977af1756714409d9a Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Tue, 2 Sep 2025 17:11:25 +0200 Subject: [PATCH 2/2] formatting --- .../src/options-mapping.ts | 24 ++++++++++++------- packages/bundler-plugin-core/src/types.ts | 2 +- .../test/option-mappings.test.ts | 8 +++---- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/packages/bundler-plugin-core/src/options-mapping.ts b/packages/bundler-plugin-core/src/options-mapping.ts index 62035292..0c79a5ae 100644 --- a/packages/bundler-plugin-core/src/options-mapping.ts +++ b/packages/bundler-plugin-core/src/options-mapping.ts @@ -44,14 +44,16 @@ export type NormalizedOptions = { | false | undefined; dist?: string; - deploy?: { - env: string; - started?: number | string; - finished?: number | string; - time?: number; - name?: string; - url?: string; - } | false; + deploy?: + | { + env: string; + started?: number | string; + finished?: number | string; + time?: number; + name?: string; + url?: string; + } + | false; uploadLegacySourcemaps?: string | IncludeEntry | Array; }; bundleSizeOptimizations: @@ -195,7 +197,11 @@ export function validateOptions(options: NormalizedOptions, logger: Logger): boo } } - if (options.release?.deploy && typeof options.release.deploy === "object" && !options.release.deploy.env) { + if ( + options.release?.deploy && + typeof options.release.deploy === "object" && + !options.release.deploy.env + ) { logger.error( "The `deploy` option was specified but is missing the required `env` property.", "Please set the `env` property." diff --git a/packages/bundler-plugin-core/src/types.ts b/packages/bundler-plugin-core/src/types.ts index 3d92e380..accceee5 100644 --- a/packages/bundler-plugin-core/src/types.ts +++ b/packages/bundler-plugin-core/src/types.ts @@ -239,7 +239,7 @@ export interface Options { /** * Configuration for adding deployment information to the release in Sentry. - * + * * Set to `false` to disable automatic deployment detection and creation. */ deploy?: DeployOptions | false; diff --git a/packages/bundler-plugin-core/test/option-mappings.test.ts b/packages/bundler-plugin-core/test/option-mappings.test.ts index ae0fc661..76bceb3d 100644 --- a/packages/bundler-plugin-core/test/option-mappings.test.ts +++ b/packages/bundler-plugin-core/test/option-mappings.test.ts @@ -135,7 +135,7 @@ describe("normalizeUserOptions()", () => { }; const normalizedOptions = normalizeUserOptions(userOptions); - + expect(normalizedOptions.release.deploy).toEqual({ env: "vercel-production", url: "https://my-app.vercel.app", @@ -155,7 +155,7 @@ describe("normalizeUserOptions()", () => { }; const normalizedOptions = normalizeUserOptions(userOptions); - + expect(normalizedOptions.release.deploy).toBe(false); }); @@ -173,7 +173,7 @@ describe("normalizeUserOptions()", () => { }; const normalizedOptions = normalizeUserOptions(userOptions); - + expect(normalizedOptions.release.deploy).toEqual(manualDeployConfig); }); @@ -186,7 +186,7 @@ describe("normalizeUserOptions()", () => { }; const normalizedOptions = normalizeUserOptions(userOptions); - + expect(normalizedOptions.release.deploy).toBeUndefined(); }); });