From 67bead42280d8c8f09a47d998a2f169b5d23a132 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 20:09:25 +0000 Subject: [PATCH 1/2] fix(node,vercel-edge,bundler-plugins): Ignore commit env vars set to their own name Some builds have `VERCEL_GIT_COMMIT_SHA` set to the literal string `VERCEL_GIT_COMMIT_SHA` instead of a SHA. Release auto-detection took that value as the release name, so every build of the app uploaded its source maps into, and reported events against, one release that never changes. Release detection in the bundler plugins and the Node and Vercel Edge SDKs now skips a commit env var whose value is its own name, warns, and moves on to the next candidate. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WgDm3ijhQZQUHGAFFqQzKQ --- packages/bundler-plugins/src/core/utils.ts | 97 ++++++++++------- .../bundler-plugins/test/core/utils.test.ts | 13 +++ packages/node/src/sdk/api.ts | 103 +++++++++++------- .../node/test/sdk/getSentryRelease.test.ts | 17 +++ packages/vercel-edge/src/sdk.ts | 102 ++++++++++------- .../vercel-edge/test/getSentryRelease.test.ts | 30 +++++ 6 files changed, 239 insertions(+), 123 deletions(-) create mode 100644 packages/vercel-edge/test/getSentryRelease.test.ts diff --git a/packages/bundler-plugins/src/core/utils.ts b/packages/bundler-plugins/src/core/utils.ts index f0d8952dc131..01b5b807c1de 100644 --- a/packages/bundler-plugins/src/core/utils.ts +++ b/packages/bundler-plugins/src/core/utils.ts @@ -224,81 +224,81 @@ export function determineReleaseName(): string | undefined { const possibleReleaseNameOfGitProvider = // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables - process.env['GITHUB_SHA'] || + readCommitEnvVar('GITHUB_SHA') || // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html - process.env['CI_MERGE_REQUEST_SOURCE_BRANCH_SHA'] || - process.env['CI_BUILD_REF'] || - process.env['CI_COMMIT_SHA'] || + readCommitEnvVar('CI_MERGE_REQUEST_SOURCE_BRANCH_SHA') || + readCommitEnvVar('CI_BUILD_REF') || + readCommitEnvVar('CI_COMMIT_SHA') || // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ - process.env['BITBUCKET_COMMIT']; + readCommitEnvVar('BITBUCKET_COMMIT'); const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = // AppVeyor - https://www.appveyor.com/docs/environment-variables/ - process.env['APPVEYOR_PULL_REQUEST_HEAD_COMMIT'] || - process.env['APPVEYOR_REPO_COMMIT'] || + readCommitEnvVar('APPVEYOR_PULL_REQUEST_HEAD_COMMIT') || + readCommitEnvVar('APPVEYOR_REPO_COMMIT') || // AWS CodeBuild - https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html - process.env['CODEBUILD_RESOLVED_SOURCE_VERSION'] || + readCommitEnvVar('CODEBUILD_RESOLVED_SOURCE_VERSION') || // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html - process.env['AWS_COMMIT_ID'] || + readCommitEnvVar('AWS_COMMIT_ID') || // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - process.env['BUILD_SOURCEVERSION'] || + readCommitEnvVar('BUILD_SOURCEVERSION') || // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/ - process.env['GIT_CLONE_COMMIT_HASH'] || + readCommitEnvVar('GIT_CLONE_COMMIT_HASH') || // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables - process.env['BUDDY_EXECUTION_REVISION'] || + readCommitEnvVar('BUDDY_EXECUTION_REVISION') || // Builtkite - https://buildkite.com/docs/pipelines/environment-variables - process.env['BUILDKITE_COMMIT'] || + readCommitEnvVar('BUILDKITE_COMMIT') || // CircleCI - https://circleci.com/docs/variables/ - process.env['CIRCLE_SHA1'] || + readCommitEnvVar('CIRCLE_SHA1') || // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables - process.env['CIRRUS_CHANGE_IN_REPO'] || + readCommitEnvVar('CIRRUS_CHANGE_IN_REPO') || // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/ - process.env['CF_REVISION'] || + readCommitEnvVar('CF_REVISION') || // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/ - process.env['CM_COMMIT'] || + readCommitEnvVar('CM_COMMIT') || // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables - process.env['CF_PAGES_COMMIT_SHA'] || + readCommitEnvVar('CF_PAGES_COMMIT_SHA') || // Drone - https://docs.drone.io/pipeline/environment/reference/ - process.env['DRONE_COMMIT_SHA'] || + readCommitEnvVar('DRONE_COMMIT_SHA') || // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables - process.env['FC_GIT_COMMIT_SHA'] || + readCommitEnvVar('FC_GIT_COMMIT_SHA') || // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci - process.env['HEROKU_TEST_RUN_COMMIT_VERSION'] || + readCommitEnvVar('HEROKU_TEST_RUN_COMMIT_VERSION') || // Heroku #2 https://docs.sentry.io/product/integrations/deployment/heroku/#configure-releases - process.env['HEROKU_SLUG_COMMIT'] || + readCommitEnvVar('HEROKU_SLUG_COMMIT') || // Railway - https://docs.railway.app/reference/variables#git-variables - process.env['RAILWAY_GIT_COMMIT_SHA'] || + readCommitEnvVar('RAILWAY_GIT_COMMIT_SHA') || // Render - https://render.com/docs/environment-variables - process.env['RENDER_GIT_COMMIT'] || + readCommitEnvVar('RENDER_GIT_COMMIT') || // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables - process.env['SEMAPHORE_GIT_SHA'] || + readCommitEnvVar('SEMAPHORE_GIT_SHA') || // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - process.env['TRAVIS_PULL_REQUEST_SHA'] || + readCommitEnvVar('TRAVIS_PULL_REQUEST_SHA') || // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - process.env['VERCEL_GIT_COMMIT_SHA'] || - process.env['VERCEL_GITHUB_COMMIT_SHA'] || - process.env['VERCEL_GITLAB_COMMIT_SHA'] || - process.env['VERCEL_BITBUCKET_COMMIT_SHA'] || + readCommitEnvVar('VERCEL_GIT_COMMIT_SHA') || + readCommitEnvVar('VERCEL_GITHUB_COMMIT_SHA') || + readCommitEnvVar('VERCEL_GITLAB_COMMIT_SHA') || + readCommitEnvVar('VERCEL_BITBUCKET_COMMIT_SHA') || // Zeit (now known as Vercel) - process.env['ZEIT_GITHUB_COMMIT_SHA'] || - process.env['ZEIT_GITLAB_COMMIT_SHA'] || - process.env['ZEIT_BITBUCKET_COMMIT_SHA']; + readCommitEnvVar('ZEIT_GITHUB_COMMIT_SHA') || + readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || + readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); const possibleReleaseNameOfCiProvidersWithGenericEnvVar = // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables - process.env['CI_COMMIT_ID'] || + readCommitEnvVar('CI_COMMIT_ID') || // Coolify - https://coolify.io/docs/knowledge-base/environment-variables - process.env['SOURCE_COMMIT'] || + readCommitEnvVar('SOURCE_COMMIT') || // Heroku #3 https://devcenter.heroku.com/changelog-items/630 - process.env['SOURCE_VERSION'] || + readCommitEnvVar('SOURCE_VERSION') || // Jenkins - https://plugins.jenkins.io/git/#environment-variables - process.env['GIT_COMMIT'] || + readCommitEnvVar('GIT_COMMIT') || // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata - process.env['COMMIT_REF'] || + readCommitEnvVar('COMMIT_REF') || // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html - process.env['BUILD_VCS_NUMBER'] || + readCommitEnvVar('BUILD_VCS_NUMBER') || // Woodpecker CI - https://woodpecker-ci.org/docs/usage/environment - process.env['CI_COMMIT_SHA']; + readCommitEnvVar('CI_COMMIT_SHA'); return ( possibleReleaseNameOfGitProvider || @@ -308,6 +308,23 @@ export function determineReleaseName(): string | undefined { ); } +/** + * Reads an environment variable that should hold a commit SHA. A value that is the variable's own + * name, such as `VERCEL_GIT_COMMIT_SHA=VERCEL_GIT_COMMIT_SHA`, is ignored: it never changes, so as + * a release name it would put every build into one release. + */ +function readCommitEnvVar(name: string): string | undefined { + const value = process.env[name]; + if (value?.trim() === name) { + // eslint-disable-next-line no-console + console.warn( + `[@sentry/bundler-plugins] Ignoring the ${name} environment variable as a release name, because its value is its own name. Set the release explicitly, or fix the variable in your build environment.`, + ); + return undefined; + } + return value; +} + /** * Generates code for the global injector which is responsible for setting the global * `SENTRY_RELEASE` & `SENTRY_BUILD_INFO` variables. diff --git a/packages/bundler-plugins/test/core/utils.test.ts b/packages/bundler-plugins/test/core/utils.test.ts index 73c28e6e646f..e3c7ca9ceb63 100644 --- a/packages/bundler-plugins/test/core/utils.test.ts +++ b/packages/bundler-plugins/test/core/utils.test.ts @@ -300,4 +300,17 @@ describe('determineReleaseName', () => { execSyncSpy.mockRestore(); } }); + it('ignores a commit env var whose value is its own name', () => { + const originalEnv = process.env; + process.env = { VERCEL_GIT_COMMIT_SHA: 'VERCEL_GIT_COMMIT_SHA', COMMIT_REF: 'abc123' }; + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined); + + try { + expect(determineReleaseName()).toBe('abc123'); + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('VERCEL_GIT_COMMIT_SHA')); + } finally { + process.env = originalEnv; + warnSpy.mockRestore(); + } + }); }); diff --git a/packages/node/src/sdk/api.ts b/packages/node/src/sdk/api.ts index f3d02265ea4d..11bf30f25285 100644 --- a/packages/node/src/sdk/api.ts +++ b/packages/node/src/sdk/api.ts @@ -1,7 +1,7 @@ // PUBLIC APIS import type { StackParser } from '@sentry/core'; -import { createStackParser, GLOBAL_OBJ } from '@sentry/core'; +import { consoleSandbox, createStackParser, GLOBAL_OBJ } from '@sentry/core'; import { nodeStackLineParser } from '@sentry/core/server'; import { createGetModuleFromFilename } from '../utils/module'; @@ -27,83 +27,83 @@ export function getSentryRelease(fallback?: string): string | undefined { const possibleReleaseNameOfGitProvider = // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables - process.env['GITHUB_SHA'] || + readCommitEnvVar('GITHUB_SHA') || // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html - process.env['CI_MERGE_REQUEST_SOURCE_BRANCH_SHA'] || - process.env['CI_BUILD_REF'] || - process.env['CI_COMMIT_SHA'] || + readCommitEnvVar('CI_MERGE_REQUEST_SOURCE_BRANCH_SHA') || + readCommitEnvVar('CI_BUILD_REF') || + readCommitEnvVar('CI_COMMIT_SHA') || // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ - process.env['BITBUCKET_COMMIT']; + readCommitEnvVar('BITBUCKET_COMMIT'); const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = // AppVeyor - https://www.appveyor.com/docs/environment-variables/ - process.env['APPVEYOR_PULL_REQUEST_HEAD_COMMIT'] || - process.env['APPVEYOR_REPO_COMMIT'] || + readCommitEnvVar('APPVEYOR_PULL_REQUEST_HEAD_COMMIT') || + readCommitEnvVar('APPVEYOR_REPO_COMMIT') || // AWS CodeBuild - https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html - process.env['CODEBUILD_RESOLVED_SOURCE_VERSION'] || + readCommitEnvVar('CODEBUILD_RESOLVED_SOURCE_VERSION') || // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html - process.env['AWS_COMMIT_ID'] || + readCommitEnvVar('AWS_COMMIT_ID') || // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - process.env['BUILD_SOURCEVERSION'] || + readCommitEnvVar('BUILD_SOURCEVERSION') || // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/ - process.env['GIT_CLONE_COMMIT_HASH'] || + readCommitEnvVar('GIT_CLONE_COMMIT_HASH') || // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables - process.env['BUDDY_EXECUTION_REVISION'] || + readCommitEnvVar('BUDDY_EXECUTION_REVISION') || // Builtkite - https://buildkite.com/docs/pipelines/environment-variables - process.env['BUILDKITE_COMMIT'] || + readCommitEnvVar('BUILDKITE_COMMIT') || // CircleCI - https://circleci.com/docs/variables/ - process.env['CIRCLE_SHA1'] || + readCommitEnvVar('CIRCLE_SHA1') || // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables - process.env['CIRRUS_CHANGE_IN_REPO'] || + readCommitEnvVar('CIRRUS_CHANGE_IN_REPO') || // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/ - process.env['CF_REVISION'] || + readCommitEnvVar('CF_REVISION') || // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/ - process.env['CM_COMMIT'] || + readCommitEnvVar('CM_COMMIT') || // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables - process.env['CF_PAGES_COMMIT_SHA'] || + readCommitEnvVar('CF_PAGES_COMMIT_SHA') || // Drone - https://docs.drone.io/pipeline/environment/reference/ - process.env['DRONE_COMMIT_SHA'] || + readCommitEnvVar('DRONE_COMMIT_SHA') || // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables - process.env['FC_GIT_COMMIT_SHA'] || + readCommitEnvVar('FC_GIT_COMMIT_SHA') || // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci - process.env['HEROKU_TEST_RUN_COMMIT_VERSION'] || + readCommitEnvVar('HEROKU_TEST_RUN_COMMIT_VERSION') || // Heroku #2 https://devcenter.heroku.com/articles/dyno-metadata#dyno-metadata - process.env['HEROKU_BUILD_COMMIT'] || + readCommitEnvVar('HEROKU_BUILD_COMMIT') || // Heroku #3 (deprecated by Heroku, kept for backward compatibility) - process.env['HEROKU_SLUG_COMMIT'] || + readCommitEnvVar('HEROKU_SLUG_COMMIT') || // Railway - https://docs.railway.app/reference/variables#git-variables - process.env['RAILWAY_GIT_COMMIT_SHA'] || + readCommitEnvVar('RAILWAY_GIT_COMMIT_SHA') || // Render - https://render.com/docs/environment-variables - process.env['RENDER_GIT_COMMIT'] || + readCommitEnvVar('RENDER_GIT_COMMIT') || // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables - process.env['SEMAPHORE_GIT_SHA'] || + readCommitEnvVar('SEMAPHORE_GIT_SHA') || // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - process.env['TRAVIS_PULL_REQUEST_SHA'] || + readCommitEnvVar('TRAVIS_PULL_REQUEST_SHA') || // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - process.env['VERCEL_GIT_COMMIT_SHA'] || - process.env['VERCEL_GITHUB_COMMIT_SHA'] || - process.env['VERCEL_GITLAB_COMMIT_SHA'] || - process.env['VERCEL_BITBUCKET_COMMIT_SHA'] || + readCommitEnvVar('VERCEL_GIT_COMMIT_SHA') || + readCommitEnvVar('VERCEL_GITHUB_COMMIT_SHA') || + readCommitEnvVar('VERCEL_GITLAB_COMMIT_SHA') || + readCommitEnvVar('VERCEL_BITBUCKET_COMMIT_SHA') || // Zeit (now known as Vercel) - process.env['ZEIT_GITHUB_COMMIT_SHA'] || - process.env['ZEIT_GITLAB_COMMIT_SHA'] || - process.env['ZEIT_BITBUCKET_COMMIT_SHA']; + readCommitEnvVar('ZEIT_GITHUB_COMMIT_SHA') || + readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || + readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); const possibleReleaseNameOfCiProvidersWithGenericEnvVar = // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables - process.env['CI_COMMIT_ID'] || + readCommitEnvVar('CI_COMMIT_ID') || // Coolify - https://coolify.io/docs/knowledge-base/environment-variables - process.env['SOURCE_COMMIT'] || + readCommitEnvVar('SOURCE_COMMIT') || // Heroku #3 https://devcenter.heroku.com/changelog-items/630 - process.env['SOURCE_VERSION'] || + readCommitEnvVar('SOURCE_VERSION') || // Jenkins - https://plugins.jenkins.io/git/#environment-variables - process.env['GIT_COMMIT'] || + readCommitEnvVar('GIT_COMMIT') || // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata - process.env['COMMIT_REF'] || + readCommitEnvVar('COMMIT_REF') || // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html - process.env['BUILD_VCS_NUMBER'] || + readCommitEnvVar('BUILD_VCS_NUMBER') || // Woodpecker CI - https://woodpecker-ci.org/docs/usage/environment - process.env['CI_COMMIT_SHA']; + readCommitEnvVar('CI_COMMIT_SHA'); return ( possibleReleaseNameOfGitProvider || @@ -113,5 +113,24 @@ export function getSentryRelease(fallback?: string): string | undefined { ); } +/** + * Reads an environment variable that should hold a commit SHA. A value that is the variable's own + * name, such as `VERCEL_GIT_COMMIT_SHA=VERCEL_GIT_COMMIT_SHA`, is ignored: it never changes, so as + * a release name it would put every build into one release. + */ +function readCommitEnvVar(name: string): string | undefined { + const value = process.env[name]; + if (value?.trim() === name) { + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + `[Sentry] Ignoring the ${name} environment variable as a release name, because its value is its own name. Set the release explicitly, or fix the variable in your build environment.`, + ); + }); + return undefined; + } + return value; +} + /** Node.js stack parser */ export const defaultStackParser: StackParser = createStackParser(nodeStackLineParser(createGetModuleFromFilename())); diff --git a/packages/node/test/sdk/getSentryRelease.test.ts b/packages/node/test/sdk/getSentryRelease.test.ts index 3e29b94e4e9e..a8148853f088 100644 --- a/packages/node/test/sdk/getSentryRelease.test.ts +++ b/packages/node/test/sdk/getSentryRelease.test.ts @@ -41,4 +41,21 @@ describe('getSentryRelease', () => { expect(getSentryRelease()).toBe('heroku-build-commit-sha'); }); + + it('ignores a commit env var whose value is its own name', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + vi.stubEnv('VERCEL_GIT_COMMIT_SHA', 'VERCEL_GIT_COMMIT_SHA'); + vi.stubEnv('COMMIT_REF', 'netlify-commit-ref'); + + expect(getSentryRelease()).toBe('netlify-commit-ref'); + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('VERCEL_GIT_COMMIT_SHA')); + warnSpy.mockRestore(); + }); + + it('falls back when the only commit env var is its own name', () => { + vi.spyOn(console, 'warn').mockImplementation(() => {}); + vi.stubEnv('VERCEL_GIT_COMMIT_SHA', 'VERCEL_GIT_COMMIT_SHA'); + + expect(getSentryRelease('fallback')).toBe('fallback'); + }); }); diff --git a/packages/vercel-edge/src/sdk.ts b/packages/vercel-edge/src/sdk.ts index ba3c4ce71830..4cb27efcc524 100644 --- a/packages/vercel-edge/src/sdk.ts +++ b/packages/vercel-edge/src/sdk.ts @@ -3,6 +3,7 @@ import type { Client, Integration } from '@sentry/core'; import { _INTERNAL_warnIfClientIsActive, consoleIntegration, + consoleSandbox, conversationIdIntegration, createStackParser, debug, @@ -158,83 +159,83 @@ export function getSentryRelease(fallback?: string): string | undefined { const possibleReleaseNameOfGitProvider = // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables - process.env['GITHUB_SHA'] || + readCommitEnvVar('GITHUB_SHA') || // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html - process.env['CI_MERGE_REQUEST_SOURCE_BRANCH_SHA'] || - process.env['CI_BUILD_REF'] || - process.env['CI_COMMIT_SHA'] || + readCommitEnvVar('CI_MERGE_REQUEST_SOURCE_BRANCH_SHA') || + readCommitEnvVar('CI_BUILD_REF') || + readCommitEnvVar('CI_COMMIT_SHA') || // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ - process.env['BITBUCKET_COMMIT']; + readCommitEnvVar('BITBUCKET_COMMIT'); const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = // AppVeyor - https://www.appveyor.com/docs/environment-variables/ - process.env['APPVEYOR_PULL_REQUEST_HEAD_COMMIT'] || - process.env['APPVEYOR_REPO_COMMIT'] || + readCommitEnvVar('APPVEYOR_PULL_REQUEST_HEAD_COMMIT') || + readCommitEnvVar('APPVEYOR_REPO_COMMIT') || // AWS CodeBuild - https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html - process.env['CODEBUILD_RESOLVED_SOURCE_VERSION'] || + readCommitEnvVar('CODEBUILD_RESOLVED_SOURCE_VERSION') || // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html - process.env['AWS_COMMIT_ID'] || + readCommitEnvVar('AWS_COMMIT_ID') || // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - process.env['BUILD_SOURCEVERSION'] || + readCommitEnvVar('BUILD_SOURCEVERSION') || // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/ - process.env['GIT_CLONE_COMMIT_HASH'] || + readCommitEnvVar('GIT_CLONE_COMMIT_HASH') || // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables - process.env['BUDDY_EXECUTION_REVISION'] || + readCommitEnvVar('BUDDY_EXECUTION_REVISION') || // Builtkite - https://buildkite.com/docs/pipelines/environment-variables - process.env['BUILDKITE_COMMIT'] || + readCommitEnvVar('BUILDKITE_COMMIT') || // CircleCI - https://circleci.com/docs/variables/ - process.env['CIRCLE_SHA1'] || + readCommitEnvVar('CIRCLE_SHA1') || // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables - process.env['CIRRUS_CHANGE_IN_REPO'] || + readCommitEnvVar('CIRRUS_CHANGE_IN_REPO') || // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/ - process.env['CF_REVISION'] || + readCommitEnvVar('CF_REVISION') || // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/ - process.env['CM_COMMIT'] || + readCommitEnvVar('CM_COMMIT') || // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables - process.env['CF_PAGES_COMMIT_SHA'] || + readCommitEnvVar('CF_PAGES_COMMIT_SHA') || // Drone - https://docs.drone.io/pipeline/environment/reference/ - process.env['DRONE_COMMIT_SHA'] || + readCommitEnvVar('DRONE_COMMIT_SHA') || // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables - process.env['FC_GIT_COMMIT_SHA'] || + readCommitEnvVar('FC_GIT_COMMIT_SHA') || // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci - process.env['HEROKU_TEST_RUN_COMMIT_VERSION'] || + readCommitEnvVar('HEROKU_TEST_RUN_COMMIT_VERSION') || // Heroku #2 https://devcenter.heroku.com/articles/dyno-metadata#dyno-metadata - process.env['HEROKU_BUILD_COMMIT'] || + readCommitEnvVar('HEROKU_BUILD_COMMIT') || // Heroku #3 (deprecated by Heroku, kept for backward compatibility) - process.env['HEROKU_SLUG_COMMIT'] || + readCommitEnvVar('HEROKU_SLUG_COMMIT') || // Railway - https://docs.railway.app/reference/variables#git-variables - process.env['RAILWAY_GIT_COMMIT_SHA'] || + readCommitEnvVar('RAILWAY_GIT_COMMIT_SHA') || // Render - https://render.com/docs/environment-variables - process.env['RENDER_GIT_COMMIT'] || + readCommitEnvVar('RENDER_GIT_COMMIT') || // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables - process.env['SEMAPHORE_GIT_SHA'] || + readCommitEnvVar('SEMAPHORE_GIT_SHA') || // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - process.env['TRAVIS_PULL_REQUEST_SHA'] || + readCommitEnvVar('TRAVIS_PULL_REQUEST_SHA') || // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - process.env['VERCEL_GIT_COMMIT_SHA'] || - process.env['VERCEL_GITHUB_COMMIT_SHA'] || - process.env['VERCEL_GITLAB_COMMIT_SHA'] || - process.env['VERCEL_BITBUCKET_COMMIT_SHA'] || + readCommitEnvVar('VERCEL_GIT_COMMIT_SHA') || + readCommitEnvVar('VERCEL_GITHUB_COMMIT_SHA') || + readCommitEnvVar('VERCEL_GITLAB_COMMIT_SHA') || + readCommitEnvVar('VERCEL_BITBUCKET_COMMIT_SHA') || // Zeit (now known as Vercel) - process.env['ZEIT_GITHUB_COMMIT_SHA'] || - process.env['ZEIT_GITLAB_COMMIT_SHA'] || - process.env['ZEIT_BITBUCKET_COMMIT_SHA']; + readCommitEnvVar('ZEIT_GITHUB_COMMIT_SHA') || + readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || + readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); const possibleReleaseNameOfCiProvidersWithGenericEnvVar = // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables - process.env['CI_COMMIT_ID'] || + readCommitEnvVar('CI_COMMIT_ID') || // Coolify - https://coolify.io/docs/knowledge-base/environment-variables - process.env['SOURCE_COMMIT'] || + readCommitEnvVar('SOURCE_COMMIT') || // Heroku #3 https://devcenter.heroku.com/changelog-items/630 - process.env['SOURCE_VERSION'] || + readCommitEnvVar('SOURCE_VERSION') || // Jenkins - https://plugins.jenkins.io/git/#environment-variables - process.env['GIT_COMMIT'] || + readCommitEnvVar('GIT_COMMIT') || // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata - process.env['COMMIT_REF'] || + readCommitEnvVar('COMMIT_REF') || // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html - process.env['BUILD_VCS_NUMBER'] || + readCommitEnvVar('BUILD_VCS_NUMBER') || // Woodpecker CI - https://woodpecker-ci.org/docs/usage/environment - process.env['CI_COMMIT_SHA']; + readCommitEnvVar('CI_COMMIT_SHA'); return ( possibleReleaseNameOfGitProvider || @@ -244,6 +245,25 @@ export function getSentryRelease(fallback?: string): string | undefined { ); } +/** + * Reads an environment variable that should hold a commit SHA. A value that is the variable's own + * name, such as `VERCEL_GIT_COMMIT_SHA=VERCEL_GIT_COMMIT_SHA`, is ignored: it never changes, so as + * a release name it would put every build into one release. + */ +function readCommitEnvVar(name: string): string | undefined { + const value = process.env[name]; + if (value?.trim() === name) { + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + `[Sentry] Ignoring the ${name} environment variable as a release name, because its value is its own name. Set the release explicitly, or fix the variable in your build environment.`, + ); + }); + return undefined; + } + return value; +} + function getTraceLifecycleFromEnv(envVar: string | undefined): 'static' | 'stream' | undefined { return envVar === 'stream' || envVar === 'static' ? envVar : undefined; } diff --git a/packages/vercel-edge/test/getSentryRelease.test.ts b/packages/vercel-edge/test/getSentryRelease.test.ts new file mode 100644 index 000000000000..78f6926edf78 --- /dev/null +++ b/packages/vercel-edge/test/getSentryRelease.test.ts @@ -0,0 +1,30 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { getSentryRelease } from '../src/sdk'; + +// Commit env vars set on CI (e.g. GITHUB_SHA on GitHub Actions) take precedence over the ones tested here. +const HIGHER_PRIORITY_ENV_VARS = [ + 'SENTRY_RELEASE', + 'GITHUB_SHA', + 'CI_MERGE_REQUEST_SOURCE_BRANCH_SHA', + 'CI_BUILD_REF', + 'CI_COMMIT_SHA', + 'BITBUCKET_COMMIT', +]; + +afterEach(() => { + vi.unstubAllEnvs(); + vi.restoreAllMocks(); +}); + +describe('getSentryRelease', () => { + it('ignores a commit env var whose value is its own name', () => { + for (const key of HIGHER_PRIORITY_ENV_VARS) { + vi.stubEnv(key, ''); + } + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + vi.stubEnv('VERCEL_GIT_COMMIT_SHA', 'VERCEL_GIT_COMMIT_SHA'); + + expect(getSentryRelease('fallback')).toBe('fallback'); + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('VERCEL_GIT_COMMIT_SHA')); + }); +}); From 449117985463c8bae71420a0ddc9f8f78ec47b03 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 18:09:27 +0000 Subject: [PATCH 2/2] fix(node,vercel-edge,bundler-plugins): Only warn about placeholder commit vars that would be the release Read the release candidate groups lazily, so a self-named commit variable is warned about only when no earlier variable already supplied the release. Drop the second CI_COMMIT_SHA read for Woodpecker CI: the GitLab check already reads that variable, so the second read could only repeat the warning. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WgDm3ijhQZQUHGAFFqQzKQ --- packages/bundler-plugins/src/core/utils.ts | 20 +++++++------ .../bundler-plugins/test/core/utils.test.ts | 28 ++++++++++++++++++ packages/node/src/sdk/api.ts | 20 +++++++------ .../node/test/sdk/getSentryRelease.test.ts | 20 +++++++++++++ packages/vercel-edge/src/sdk.ts | 20 +++++++------ .../vercel-edge/test/getSentryRelease.test.ts | 29 +++++++++++++++++-- 6 files changed, 107 insertions(+), 30 deletions(-) diff --git a/packages/bundler-plugins/src/core/utils.ts b/packages/bundler-plugins/src/core/utils.ts index 01b5b807c1de..d25cfa36acf3 100644 --- a/packages/bundler-plugins/src/core/utils.ts +++ b/packages/bundler-plugins/src/core/utils.ts @@ -221,8 +221,10 @@ export function determineReleaseName(): string | undefined { // 1. Git providers // 2. CI providers with specific environment variables (has the provider name in the variable name) // 3. CI providers with generic environment variables (checked for last to prevent possible false positives) + // Each group is only read if the earlier ones found nothing, so a placeholder value is only + // warned about when it would otherwise have become the release. - const possibleReleaseNameOfGitProvider = + const possibleReleaseNameOfGitProvider = (): string | undefined => // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables readCommitEnvVar('GITHUB_SHA') || // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html @@ -232,7 +234,7 @@ export function determineReleaseName(): string | undefined { // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ readCommitEnvVar('BITBUCKET_COMMIT'); - const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = + const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = (): string | undefined => // AppVeyor - https://www.appveyor.com/docs/environment-variables/ readCommitEnvVar('APPVEYOR_PULL_REQUEST_HEAD_COMMIT') || readCommitEnvVar('APPVEYOR_REPO_COMMIT') || @@ -284,7 +286,7 @@ export function determineReleaseName(): string | undefined { readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); - const possibleReleaseNameOfCiProvidersWithGenericEnvVar = + const possibleReleaseNameOfCiProvidersWithGenericEnvVar = (): string | undefined => // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables readCommitEnvVar('CI_COMMIT_ID') || // Coolify - https://coolify.io/docs/knowledge-base/environment-variables @@ -296,14 +298,14 @@ export function determineReleaseName(): string | undefined { // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata readCommitEnvVar('COMMIT_REF') || // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html - readCommitEnvVar('BUILD_VCS_NUMBER') || - // Woodpecker CI - https://woodpecker-ci.org/docs/usage/environment - readCommitEnvVar('CI_COMMIT_SHA'); + readCommitEnvVar('BUILD_VCS_NUMBER'); + // Woodpecker CI (https://woodpecker-ci.org/docs/usage/environment) sets CI_COMMIT_SHA, which the + // GitLab check above already reads. return ( - possibleReleaseNameOfGitProvider || - possibleReleaseNameOfCiProvidersWithSpecificEnvVar || - possibleReleaseNameOfCiProvidersWithGenericEnvVar || + possibleReleaseNameOfGitProvider() || + possibleReleaseNameOfCiProvidersWithSpecificEnvVar() || + possibleReleaseNameOfCiProvidersWithGenericEnvVar() || gitRevision() ); } diff --git a/packages/bundler-plugins/test/core/utils.test.ts b/packages/bundler-plugins/test/core/utils.test.ts index e3c7ca9ceb63..da4f3b29e224 100644 --- a/packages/bundler-plugins/test/core/utils.test.ts +++ b/packages/bundler-plugins/test/core/utils.test.ts @@ -313,4 +313,32 @@ describe('determineReleaseName', () => { warnSpy.mockRestore(); } }); + it('does not warn about a placeholder checked after the variable that supplies the release', () => { + const originalEnv = process.env; + process.env = { VERCEL_GIT_COMMIT_SHA: 'abc123', COMMIT_REF: 'COMMIT_REF' }; + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined); + + try { + expect(determineReleaseName()).toBe('abc123'); + expect(warnSpy).not.toHaveBeenCalled(); + } finally { + process.env = originalEnv; + warnSpy.mockRestore(); + } + }); + it('warns once about a CI_COMMIT_SHA placeholder', () => { + const originalEnv = process.env; + process.env = { CI_COMMIT_SHA: 'CI_COMMIT_SHA' }; + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined); + const execSyncSpy = vi.spyOn(childProcess, 'execSync').mockReturnValue(Buffer.from('0'.repeat(40))); + + try { + expect(determineReleaseName()).toBe('0'.repeat(40)); + expect(warnSpy).toHaveBeenCalledTimes(1); + } finally { + process.env = originalEnv; + warnSpy.mockRestore(); + execSyncSpy.mockRestore(); + } + }); }); diff --git a/packages/node/src/sdk/api.ts b/packages/node/src/sdk/api.ts index 11bf30f25285..572b96fafd48 100644 --- a/packages/node/src/sdk/api.ts +++ b/packages/node/src/sdk/api.ts @@ -24,8 +24,10 @@ export function getSentryRelease(fallback?: string): string | undefined { // 1. Git providers // 2. CI providers with specific environment variables (has the provider name in the variable name) // 3. CI providers with generic environment variables (checked for last to prevent possible false positives) + // Each group is only read if the earlier ones found nothing, so a placeholder value is only + // warned about when it would otherwise have become the release. - const possibleReleaseNameOfGitProvider = + const possibleReleaseNameOfGitProvider = (): string | undefined => // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables readCommitEnvVar('GITHUB_SHA') || // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html @@ -35,7 +37,7 @@ export function getSentryRelease(fallback?: string): string | undefined { // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ readCommitEnvVar('BITBUCKET_COMMIT'); - const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = + const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = (): string | undefined => // AppVeyor - https://www.appveyor.com/docs/environment-variables/ readCommitEnvVar('APPVEYOR_PULL_REQUEST_HEAD_COMMIT') || readCommitEnvVar('APPVEYOR_REPO_COMMIT') || @@ -89,7 +91,7 @@ export function getSentryRelease(fallback?: string): string | undefined { readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); - const possibleReleaseNameOfCiProvidersWithGenericEnvVar = + const possibleReleaseNameOfCiProvidersWithGenericEnvVar = (): string | undefined => // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables readCommitEnvVar('CI_COMMIT_ID') || // Coolify - https://coolify.io/docs/knowledge-base/environment-variables @@ -101,14 +103,14 @@ export function getSentryRelease(fallback?: string): string | undefined { // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata readCommitEnvVar('COMMIT_REF') || // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html - readCommitEnvVar('BUILD_VCS_NUMBER') || - // Woodpecker CI - https://woodpecker-ci.org/docs/usage/environment - readCommitEnvVar('CI_COMMIT_SHA'); + readCommitEnvVar('BUILD_VCS_NUMBER'); + // Woodpecker CI (https://woodpecker-ci.org/docs/usage/environment) sets CI_COMMIT_SHA, which the + // GitLab check above already reads. return ( - possibleReleaseNameOfGitProvider || - possibleReleaseNameOfCiProvidersWithSpecificEnvVar || - possibleReleaseNameOfCiProvidersWithGenericEnvVar || + possibleReleaseNameOfGitProvider() || + possibleReleaseNameOfCiProvidersWithSpecificEnvVar() || + possibleReleaseNameOfCiProvidersWithGenericEnvVar() || fallback ); } diff --git a/packages/node/test/sdk/getSentryRelease.test.ts b/packages/node/test/sdk/getSentryRelease.test.ts index a8148853f088..ea190cf98a7d 100644 --- a/packages/node/test/sdk/getSentryRelease.test.ts +++ b/packages/node/test/sdk/getSentryRelease.test.ts @@ -20,6 +20,7 @@ beforeEach(() => { afterEach(() => { vi.unstubAllEnvs(); + vi.restoreAllMocks(); }); describe('getSentryRelease', () => { @@ -58,4 +59,23 @@ describe('getSentryRelease', () => { expect(getSentryRelease('fallback')).toBe('fallback'); }); + + it('does not warn about a placeholder checked after the variable that supplies the release', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + vi.stubEnv('HEROKU_BUILD_COMMIT', 'heroku-build-commit-sha'); + vi.stubEnv('COMMIT_REF', 'COMMIT_REF'); + + expect(getSentryRelease()).toBe('heroku-build-commit-sha'); + expect(warnSpy).not.toHaveBeenCalled(); + warnSpy.mockRestore(); + }); + + it('warns once about a CI_COMMIT_SHA placeholder', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + vi.stubEnv('CI_COMMIT_SHA', 'CI_COMMIT_SHA'); + + expect(getSentryRelease('fallback')).toBe('fallback'); + expect(warnSpy).toHaveBeenCalledTimes(1); + warnSpy.mockRestore(); + }); }); diff --git a/packages/vercel-edge/src/sdk.ts b/packages/vercel-edge/src/sdk.ts index 4cb27efcc524..bc2d74822d65 100644 --- a/packages/vercel-edge/src/sdk.ts +++ b/packages/vercel-edge/src/sdk.ts @@ -156,8 +156,10 @@ export function getSentryRelease(fallback?: string): string | undefined { // 1. Git providers // 2. CI providers with specific environment variables (has the provider name in the variable name) // 3. CI providers with generic environment variables (checked for last to prevent possible false positives) + // Each group is only read if the earlier ones found nothing, so a placeholder value is only + // warned about when it would otherwise have become the release. - const possibleReleaseNameOfGitProvider = + const possibleReleaseNameOfGitProvider = (): string | undefined => // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables readCommitEnvVar('GITHUB_SHA') || // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html @@ -167,7 +169,7 @@ export function getSentryRelease(fallback?: string): string | undefined { // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ readCommitEnvVar('BITBUCKET_COMMIT'); - const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = + const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = (): string | undefined => // AppVeyor - https://www.appveyor.com/docs/environment-variables/ readCommitEnvVar('APPVEYOR_PULL_REQUEST_HEAD_COMMIT') || readCommitEnvVar('APPVEYOR_REPO_COMMIT') || @@ -221,7 +223,7 @@ export function getSentryRelease(fallback?: string): string | undefined { readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); - const possibleReleaseNameOfCiProvidersWithGenericEnvVar = + const possibleReleaseNameOfCiProvidersWithGenericEnvVar = (): string | undefined => // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables readCommitEnvVar('CI_COMMIT_ID') || // Coolify - https://coolify.io/docs/knowledge-base/environment-variables @@ -233,14 +235,14 @@ export function getSentryRelease(fallback?: string): string | undefined { // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata readCommitEnvVar('COMMIT_REF') || // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html - readCommitEnvVar('BUILD_VCS_NUMBER') || - // Woodpecker CI - https://woodpecker-ci.org/docs/usage/environment - readCommitEnvVar('CI_COMMIT_SHA'); + readCommitEnvVar('BUILD_VCS_NUMBER'); + // Woodpecker CI (https://woodpecker-ci.org/docs/usage/environment) sets CI_COMMIT_SHA, which the + // GitLab check above already reads. return ( - possibleReleaseNameOfGitProvider || - possibleReleaseNameOfCiProvidersWithSpecificEnvVar || - possibleReleaseNameOfCiProvidersWithGenericEnvVar || + possibleReleaseNameOfGitProvider() || + possibleReleaseNameOfCiProvidersWithSpecificEnvVar() || + possibleReleaseNameOfCiProvidersWithGenericEnvVar() || fallback ); } diff --git a/packages/vercel-edge/test/getSentryRelease.test.ts b/packages/vercel-edge/test/getSentryRelease.test.ts index 78f6926edf78..785a8a63617d 100644 --- a/packages/vercel-edge/test/getSentryRelease.test.ts +++ b/packages/vercel-edge/test/getSentryRelease.test.ts @@ -11,6 +11,12 @@ const HIGHER_PRIORITY_ENV_VARS = [ 'BITBUCKET_COMMIT', ]; +function clearHigherPriorityEnvVars(): void { + for (const key of HIGHER_PRIORITY_ENV_VARS) { + vi.stubEnv(key, ''); + } +} + afterEach(() => { vi.unstubAllEnvs(); vi.restoreAllMocks(); @@ -18,13 +24,30 @@ afterEach(() => { describe('getSentryRelease', () => { it('ignores a commit env var whose value is its own name', () => { - for (const key of HIGHER_PRIORITY_ENV_VARS) { - vi.stubEnv(key, ''); - } + clearHigherPriorityEnvVars(); const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); vi.stubEnv('VERCEL_GIT_COMMIT_SHA', 'VERCEL_GIT_COMMIT_SHA'); expect(getSentryRelease('fallback')).toBe('fallback'); expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('VERCEL_GIT_COMMIT_SHA')); }); + + it('does not warn about a placeholder checked after the variable that supplies the release', () => { + clearHigherPriorityEnvVars(); + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + vi.stubEnv('VERCEL_GIT_COMMIT_SHA', 'vercel-commit-sha'); + vi.stubEnv('COMMIT_REF', 'COMMIT_REF'); + + expect(getSentryRelease('fallback')).toBe('vercel-commit-sha'); + expect(warnSpy).not.toHaveBeenCalled(); + }); + + it('warns once about a CI_COMMIT_SHA placeholder', () => { + clearHigherPriorityEnvVars(); + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + vi.stubEnv('CI_COMMIT_SHA', 'CI_COMMIT_SHA'); + + expect(getSentryRelease('fallback')).toBe('fallback'); + expect(warnSpy).toHaveBeenCalledTimes(1); + }); });