From 67bead42280d8c8f09a47d998a2f169b5d23a132 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 20:09:25 +0000 Subject: [PATCH] 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')); + }); +});