diff --git a/packages/bundler-plugins/src/core/utils.ts b/packages/bundler-plugins/src/core/utils.ts index 6cf8c6af8e81..1e949c1b4785 100644 --- a/packages/bundler-plugins/src/core/utils.ts +++ b/packages/bundler-plugins/src/core/utils.ts @@ -6,6 +6,10 @@ import crypto from 'crypto'; import childProcess from 'child_process'; import type { SourceMap } from 'magic-string'; import MagicString from 'magic-string'; +import { + _INTERNAL_getReleaseFromCommitEnv as getReleaseFromCommitEnv, + _INTERNAL_readCommitEnvVar as readCoreCommitEnvVar, +} from '@sentry/core/server'; /** * Checks whether the given input is already an array, and if it isn't, wraps it in one. @@ -215,124 +219,32 @@ function gitRevision(): string | undefined { /** * Tries to guess a release name based on environmental data. */ -// oxlint-disable-next-line complexity export function determineReleaseName(): string | undefined { - // This list is in approximate alpha order, separated into 3 categories: - // 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 = (): 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 - 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/ - readCommitEnvVar('BITBUCKET_COMMIT'); - - const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = (): string | undefined => - // AppVeyor - https://www.appveyor.com/docs/environment-variables/ - 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 - readCommitEnvVar('CODEBUILD_RESOLVED_SOURCE_VERSION') || - // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html - readCommitEnvVar('AWS_COMMIT_ID') || - // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - readCommitEnvVar('BUILD_SOURCEVERSION') || - // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/ - readCommitEnvVar('GIT_CLONE_COMMIT_HASH') || - // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables - readCommitEnvVar('BUDDY_EXECUTION_REVISION') || - // Builtkite - https://buildkite.com/docs/pipelines/environment-variables - readCommitEnvVar('BUILDKITE_COMMIT') || - // CircleCI - https://circleci.com/docs/variables/ - readCommitEnvVar('CIRCLE_SHA1') || - // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables - readCommitEnvVar('CIRRUS_CHANGE_IN_REPO') || - // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/ - readCommitEnvVar('CF_REVISION') || - // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/ - readCommitEnvVar('CM_COMMIT') || - // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables - readCommitEnvVar('CF_PAGES_COMMIT_SHA') || - // Drone - https://docs.drone.io/pipeline/environment/reference/ - readCommitEnvVar('DRONE_COMMIT_SHA') || - // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables - readCommitEnvVar('FC_GIT_COMMIT_SHA') || - // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci - readCommitEnvVar('HEROKU_TEST_RUN_COMMIT_VERSION') || - // Heroku #2 https://docs.sentry.io/product/integrations/deployment/heroku/#configure-releases - readCommitEnvVar('HEROKU_SLUG_COMMIT') || - // Railway - https://docs.railway.app/reference/variables#git-variables - readCommitEnvVar('RAILWAY_GIT_COMMIT_SHA') || - // Render - https://render.com/docs/environment-variables - readCommitEnvVar('RENDER_GIT_COMMIT') || - // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables - readCommitEnvVar('SEMAPHORE_GIT_SHA') || - // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - readCommitEnvVar('TRAVIS_PULL_REQUEST_SHA') || - // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - 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) - readCommitEnvVar('ZEIT_GITHUB_COMMIT_SHA') || - readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || - readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); - - 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 - readCommitEnvVar('SOURCE_COMMIT') || - // Heroku #3 https://devcenter.heroku.com/changelog-items/630 - readCommitEnvVar('SOURCE_VERSION') || - // Jenkins - https://plugins.jenkins.io/git/#environment-variables - readCommitEnvVar('GIT_COMMIT') || - // 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) sets CI_COMMIT_SHA, which the - // GitLab check above already reads. - - return ( - possibleReleaseNameOfGitProvider() || - possibleReleaseNameOfCiProvidersWithSpecificEnvVar() || - possibleReleaseNameOfCiProvidersWithGenericEnvVar() || - gitRevision() - ); + return getReleaseFromCommitEnv(warnAboutPlaceholderCommitEnvVar) || gitRevision(); } // Release detection and commit association can read the same variable in one build. const warnedPlaceholderEnvVars = new Set(); +function warnAboutPlaceholderCommitEnvVar(name: string): void { + if (warnedPlaceholderEnvVars.has(name)) { + return; + } + warnedPlaceholderEnvVars.add(name); + // This runs before the plugin logger exists, so `silent: true` does not suppress it. That is + // deliberate: a warning that is easy to miss is how this misconfiguration went unnoticed. + // 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.`, + ); +} + /** - * 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. + * Reads an environment variable that should hold a commit SHA, ignoring a value that is the + * variable's own name. See `_INTERNAL_readCommitEnvVar` in `@sentry/core/server`. */ export function readCommitEnvVar(name: string): string | undefined { - const value = process.env[name]; - if (value?.trim() === name) { - if (!warnedPlaceholderEnvVars.has(name)) { - warnedPlaceholderEnvVars.add(name); - // This runs before the plugin logger exists, so `silent: true` does not suppress it. That is - // deliberate: a warning that is easy to miss is how this misconfiguration went unnoticed. - // 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; + return readCoreCommitEnvVar(name, warnAboutPlaceholderCommitEnvVar); } function stringifyForCodeInjection(value: unknown): string | undefined { diff --git a/packages/bundler-plugins/test/core/utils.test.ts b/packages/bundler-plugins/test/core/utils.test.ts index e387230a4ada..68e62701f0fa 100644 --- a/packages/bundler-plugins/test/core/utils.test.ts +++ b/packages/bundler-plugins/test/core/utils.test.ts @@ -345,6 +345,16 @@ describe('determineReleaseName', () => { execSyncSpy.mockRestore(); } }); + it('detects HEROKU_BUILD_COMMIT', () => { + const originalEnv = process.env; + process.env = { HEROKU_BUILD_COMMIT: 'heroku-build-commit' }; + + try { + expect(determineReleaseName()).toBe('heroku-build-commit'); + } finally { + process.env = originalEnv; + } + }); 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' }; diff --git a/packages/core/src/server.ts b/packages/core/src/server.ts index e44bb9c2df8b..f328253a9208 100644 --- a/packages/core/src/server.ts +++ b/packages/core/src/server.ts @@ -12,6 +12,10 @@ export { wrapMcpServerWithSentry } from './integrations/mcp-server'; export { isNodeEnv, loadModule } from './utils/node'; export { filenameIsInApp, node, nodeStackLineParser } from './utils/node-stack-trace'; export { vercelWaitUntil } from './utils/vercelWaitUntil'; +export { + getReleaseFromCommitEnv as _INTERNAL_getReleaseFromCommitEnv, + readCommitEnvVar as _INTERNAL_readCommitEnvVar, +} from './utils/commitEnv'; export { flushIfServerless } from './utils/flushIfServerless'; export { callFrameToStackFrame, watchdogTimer } from './utils/anr'; export { safeUnref as _INTERNAL_safeUnref } from './utils/timer'; diff --git a/packages/core/src/utils/commitEnv.ts b/packages/core/src/utils/commitEnv.ts new file mode 100644 index 000000000000..ca5d6fe75de1 --- /dev/null +++ b/packages/core/src/utils/commitEnv.ts @@ -0,0 +1,139 @@ +import { consoleSandbox } from './debug-logger'; + +/** + * Environment variables that CI and hosting providers set to the commit being built, in the order + * release detection checks them. The list is in approximate alpha order, separated into 3 categories: + * 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) + */ +const COMMIT_ENV_VARS = [ + // 1. Git providers + // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables + 'GITHUB_SHA', + // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html + // Woodpecker CI also sets CI_COMMIT_SHA - https://woodpecker-ci.org/docs/usage/environment + 'CI_MERGE_REQUEST_SOURCE_BRANCH_SHA', + 'CI_BUILD_REF', + 'CI_COMMIT_SHA', + // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ + 'BITBUCKET_COMMIT', + + // 2. CI providers with specific environment variables + // AppVeyor - https://www.appveyor.com/docs/environment-variables/ + 'APPVEYOR_PULL_REQUEST_HEAD_COMMIT', + 'APPVEYOR_REPO_COMMIT', + // AWS CodeBuild - https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html + 'CODEBUILD_RESOLVED_SOURCE_VERSION', + // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html + 'AWS_COMMIT_ID', + // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml + 'BUILD_SOURCEVERSION', + // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/ + 'GIT_CLONE_COMMIT_HASH', + // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables + 'BUDDY_EXECUTION_REVISION', + // Builtkite - https://buildkite.com/docs/pipelines/environment-variables + 'BUILDKITE_COMMIT', + // CircleCI - https://circleci.com/docs/variables/ + 'CIRCLE_SHA1', + // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables + 'CIRRUS_CHANGE_IN_REPO', + // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/ + 'CF_REVISION', + // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/ + 'CM_COMMIT', + // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables + 'CF_PAGES_COMMIT_SHA', + // Drone - https://docs.drone.io/pipeline/environment/reference/ + 'DRONE_COMMIT_SHA', + // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables + 'FC_GIT_COMMIT_SHA', + // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci + 'HEROKU_TEST_RUN_COMMIT_VERSION', + // Heroku #2 https://devcenter.heroku.com/articles/dyno-metadata#dyno-metadata + 'HEROKU_BUILD_COMMIT', + // Heroku #3 (deprecated by Heroku, kept for backward compatibility) + 'HEROKU_SLUG_COMMIT', + // Railway - https://docs.railway.app/reference/variables#git-variables + 'RAILWAY_GIT_COMMIT_SHA', + // Render - https://render.com/docs/environment-variables + 'RENDER_GIT_COMMIT', + // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables + 'SEMAPHORE_GIT_SHA', + // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables + 'TRAVIS_PULL_REQUEST_SHA', + // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables + 'VERCEL_GIT_COMMIT_SHA', + 'VERCEL_GITHUB_COMMIT_SHA', + 'VERCEL_GITLAB_COMMIT_SHA', + 'VERCEL_BITBUCKET_COMMIT_SHA', + // Zeit (now known as Vercel) + 'ZEIT_GITHUB_COMMIT_SHA', + 'ZEIT_GITLAB_COMMIT_SHA', + 'ZEIT_BITBUCKET_COMMIT_SHA', + + // 3. CI providers with generic environment variables + // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables + 'CI_COMMIT_ID', + // Coolify - https://coolify.io/docs/knowledge-base/environment-variables + 'SOURCE_COMMIT', + // Heroku #4 https://devcenter.heroku.com/changelog-items/630 + 'SOURCE_VERSION', + // Jenkins - https://plugins.jenkins.io/git/#environment-variables + 'GIT_COMMIT', + // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata + 'COMMIT_REF', + // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html + 'BUILD_VCS_NUMBER', +] as const; + +/** Called with the name of a commit environment variable whose value is its own name. */ +export type PlaceholderCommitEnvVarHandler = (name: string) => void; + +function warnAboutPlaceholderCommitEnvVar(name: string): void { + 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.`, + ); + }); +} + +/** + * 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. `onPlaceholder` is called for such a + * value and warns on the console by default. + */ +export function readCommitEnvVar( + name: string, + onPlaceholder: PlaceholderCommitEnvVarHandler = warnAboutPlaceholderCommitEnvVar, +): string | undefined { + if (typeof process === 'undefined') { + return undefined; + } + const value = process.env[name]; + if (value?.trim() === name) { + onPlaceholder(name); + return undefined; + } + return value || undefined; +} + +/** + * Returns the commit that CI or the hosting provider is building, read from the first of the known + * commit environment variables that is set. Variables are read in order and only until one is + * found, so a placeholder value is only reported when it would otherwise have become the release. + */ +export function getReleaseFromCommitEnv( + onPlaceholder: PlaceholderCommitEnvVarHandler = warnAboutPlaceholderCommitEnvVar, +): string | undefined { + for (const name of COMMIT_ENV_VARS) { + const value = readCommitEnvVar(name, onPlaceholder); + if (value) { + return value; + } + } + return undefined; +} diff --git a/packages/core/test/lib/utils/commitEnv.test.ts b/packages/core/test/lib/utils/commitEnv.test.ts new file mode 100644 index 000000000000..5954785256fb --- /dev/null +++ b/packages/core/test/lib/utils/commitEnv.test.ts @@ -0,0 +1,95 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { getReleaseFromCommitEnv, readCommitEnvVar } from '../../../src/utils/commitEnv'; + +describe('commitEnv', () => { + const originalEnv = process.env; + + beforeEach(() => { + // CI sets some of these variables (e.g. GITHUB_SHA on GitHub Actions), so start from an empty env. + process.env = {}; + }); + + afterEach(() => { + process.env = originalEnv; + vi.restoreAllMocks(); + }); + + describe('readCommitEnvVar', () => { + it('returns the value of the variable', () => { + process.env.VERCEL_GIT_COMMIT_SHA = 'abc123'; + + expect(readCommitEnvVar('VERCEL_GIT_COMMIT_SHA')).toBe('abc123'); + }); + + it('returns undefined for an unset or empty variable', () => { + process.env.VERCEL_GIT_COMMIT_SHA = ''; + + expect(readCommitEnvVar('VERCEL_GIT_COMMIT_SHA')).toBeUndefined(); + expect(readCommitEnvVar('GITHUB_SHA')).toBeUndefined(); + }); + + it('ignores a value that is its own name and warns by default', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + process.env.VERCEL_GIT_COMMIT_SHA = ' VERCEL_GIT_COMMIT_SHA '; + + expect(readCommitEnvVar('VERCEL_GIT_COMMIT_SHA')).toBeUndefined(); + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('VERCEL_GIT_COMMIT_SHA')); + }); + + it('passes a placeholder to a custom handler instead of warning', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + const onPlaceholder = vi.fn(); + process.env.VERCEL_GIT_COMMIT_SHA = 'VERCEL_GIT_COMMIT_SHA'; + + expect(readCommitEnvVar('VERCEL_GIT_COMMIT_SHA', onPlaceholder)).toBeUndefined(); + expect(onPlaceholder).toHaveBeenCalledWith('VERCEL_GIT_COMMIT_SHA'); + expect(warnSpy).not.toHaveBeenCalled(); + }); + }); + + describe('getReleaseFromCommitEnv', () => { + it('returns undefined when no commit variable is set', () => { + expect(getReleaseFromCommitEnv()).toBeUndefined(); + }); + + it('prefers git provider variables over generic CI variables', () => { + process.env.COMMIT_REF = 'netlify-commit'; + process.env.GITHUB_SHA = 'github-commit'; + + expect(getReleaseFromCommitEnv()).toBe('github-commit'); + }); + + it('reads HEROKU_BUILD_COMMIT before HEROKU_SLUG_COMMIT', () => { + process.env.HEROKU_BUILD_COMMIT = 'heroku-build-commit'; + process.env.HEROKU_SLUG_COMMIT = 'heroku-slug-commit'; + + expect(getReleaseFromCommitEnv()).toBe('heroku-build-commit'); + }); + + it('skips a placeholder and uses the next variable that is set', () => { + const onPlaceholder = vi.fn(); + process.env.VERCEL_GIT_COMMIT_SHA = 'VERCEL_GIT_COMMIT_SHA'; + process.env.COMMIT_REF = 'netlify-commit'; + + expect(getReleaseFromCommitEnv(onPlaceholder)).toBe('netlify-commit'); + expect(onPlaceholder).toHaveBeenCalledWith('VERCEL_GIT_COMMIT_SHA'); + }); + + it('does not report a placeholder checked after the variable that supplies the release', () => { + const onPlaceholder = vi.fn(); + process.env.VERCEL_GIT_COMMIT_SHA = 'vercel-commit'; + process.env.COMMIT_REF = 'COMMIT_REF'; + + expect(getReleaseFromCommitEnv(onPlaceholder)).toBe('vercel-commit'); + expect(onPlaceholder).not.toHaveBeenCalled(); + }); + + it('reports each placeholder once', () => { + const onPlaceholder = vi.fn(); + process.env.CI_COMMIT_SHA = 'CI_COMMIT_SHA'; + + expect(getReleaseFromCommitEnv(onPlaceholder)).toBeUndefined(); + expect(onPlaceholder).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/packages/node/src/sdk/api.ts b/packages/node/src/sdk/api.ts index 572b96fafd48..2e07f45297d8 100644 --- a/packages/node/src/sdk/api.ts +++ b/packages/node/src/sdk/api.ts @@ -1,14 +1,13 @@ // PUBLIC APIS import type { StackParser } from '@sentry/core'; -import { consoleSandbox, createStackParser, GLOBAL_OBJ } from '@sentry/core'; -import { nodeStackLineParser } from '@sentry/core/server'; +import { createStackParser, GLOBAL_OBJ } from '@sentry/core'; +import { _INTERNAL_getReleaseFromCommitEnv as getReleaseFromCommitEnv, nodeStackLineParser } from '@sentry/core/server'; import { createGetModuleFromFilename } from '../utils/module'; /** * Returns a release dynamically from environment variables. */ -// eslint-disable-next-line complexity export function getSentryRelease(fallback?: string): string | undefined { // Always read first as Sentry takes this as precedence if (process.env.SENTRY_RELEASE) { @@ -20,118 +19,7 @@ export function getSentryRelease(fallback?: string): string | undefined { return GLOBAL_OBJ.SENTRY_RELEASE.id; } - // This list is in approximate alpha order, separated into 3 categories: - // 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 = (): 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 - 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/ - readCommitEnvVar('BITBUCKET_COMMIT'); - - const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = (): string | undefined => - // AppVeyor - https://www.appveyor.com/docs/environment-variables/ - 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 - readCommitEnvVar('CODEBUILD_RESOLVED_SOURCE_VERSION') || - // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html - readCommitEnvVar('AWS_COMMIT_ID') || - // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - readCommitEnvVar('BUILD_SOURCEVERSION') || - // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/ - readCommitEnvVar('GIT_CLONE_COMMIT_HASH') || - // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables - readCommitEnvVar('BUDDY_EXECUTION_REVISION') || - // Builtkite - https://buildkite.com/docs/pipelines/environment-variables - readCommitEnvVar('BUILDKITE_COMMIT') || - // CircleCI - https://circleci.com/docs/variables/ - readCommitEnvVar('CIRCLE_SHA1') || - // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables - readCommitEnvVar('CIRRUS_CHANGE_IN_REPO') || - // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/ - readCommitEnvVar('CF_REVISION') || - // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/ - readCommitEnvVar('CM_COMMIT') || - // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables - readCommitEnvVar('CF_PAGES_COMMIT_SHA') || - // Drone - https://docs.drone.io/pipeline/environment/reference/ - readCommitEnvVar('DRONE_COMMIT_SHA') || - // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables - readCommitEnvVar('FC_GIT_COMMIT_SHA') || - // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci - readCommitEnvVar('HEROKU_TEST_RUN_COMMIT_VERSION') || - // Heroku #2 https://devcenter.heroku.com/articles/dyno-metadata#dyno-metadata - readCommitEnvVar('HEROKU_BUILD_COMMIT') || - // Heroku #3 (deprecated by Heroku, kept for backward compatibility) - readCommitEnvVar('HEROKU_SLUG_COMMIT') || - // Railway - https://docs.railway.app/reference/variables#git-variables - readCommitEnvVar('RAILWAY_GIT_COMMIT_SHA') || - // Render - https://render.com/docs/environment-variables - readCommitEnvVar('RENDER_GIT_COMMIT') || - // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables - readCommitEnvVar('SEMAPHORE_GIT_SHA') || - // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - readCommitEnvVar('TRAVIS_PULL_REQUEST_SHA') || - // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - 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) - readCommitEnvVar('ZEIT_GITHUB_COMMIT_SHA') || - readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || - readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); - - 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 - readCommitEnvVar('SOURCE_COMMIT') || - // Heroku #3 https://devcenter.heroku.com/changelog-items/630 - readCommitEnvVar('SOURCE_VERSION') || - // Jenkins - https://plugins.jenkins.io/git/#environment-variables - readCommitEnvVar('GIT_COMMIT') || - // 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) sets CI_COMMIT_SHA, which the - // GitLab check above already reads. - - return ( - possibleReleaseNameOfGitProvider() || - possibleReleaseNameOfCiProvidersWithSpecificEnvVar() || - possibleReleaseNameOfCiProvidersWithGenericEnvVar() || - fallback - ); -} - -/** - * 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; + return getReleaseFromCommitEnv() || fallback; } /** Node.js stack parser */ diff --git a/packages/vercel-edge/src/sdk.ts b/packages/vercel-edge/src/sdk.ts index bc2d74822d65..47522657a510 100644 --- a/packages/vercel-edge/src/sdk.ts +++ b/packages/vercel-edge/src/sdk.ts @@ -3,7 +3,6 @@ import type { Client, Integration } from '@sentry/core'; import { _INTERNAL_warnIfClientIsActive, consoleIntegration, - consoleSandbox, conversationIdIntegration, createStackParser, debug, @@ -18,7 +17,7 @@ import { requestDataIntegration, stackParserFromStackParserOptions, } from '@sentry/core'; -import { nodeStackLineParser } from '@sentry/core/server'; +import { _INTERNAL_getReleaseFromCommitEnv as getReleaseFromCommitEnv, nodeStackLineParser } from '@sentry/core/server'; import { SentryPropagator, SentryTracerProvider, @@ -140,7 +139,6 @@ function setupOpenTelemetryLogger(): void { /** * Returns a release dynamically from environment variables. */ -// eslint-disable-next-line complexity export function getSentryRelease(fallback?: string): string | undefined { // Always read first as Sentry takes this as precedence if (process.env.SENTRY_RELEASE) { @@ -152,118 +150,7 @@ export function getSentryRelease(fallback?: string): string | undefined { return GLOBAL_OBJ.SENTRY_RELEASE.id; } - // This list is in approximate alpha order, separated into 3 categories: - // 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 = (): 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 - 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/ - readCommitEnvVar('BITBUCKET_COMMIT'); - - const possibleReleaseNameOfCiProvidersWithSpecificEnvVar = (): string | undefined => - // AppVeyor - https://www.appveyor.com/docs/environment-variables/ - 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 - readCommitEnvVar('CODEBUILD_RESOLVED_SOURCE_VERSION') || - // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html - readCommitEnvVar('AWS_COMMIT_ID') || - // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - readCommitEnvVar('BUILD_SOURCEVERSION') || - // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/ - readCommitEnvVar('GIT_CLONE_COMMIT_HASH') || - // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables - readCommitEnvVar('BUDDY_EXECUTION_REVISION') || - // Builtkite - https://buildkite.com/docs/pipelines/environment-variables - readCommitEnvVar('BUILDKITE_COMMIT') || - // CircleCI - https://circleci.com/docs/variables/ - readCommitEnvVar('CIRCLE_SHA1') || - // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables - readCommitEnvVar('CIRRUS_CHANGE_IN_REPO') || - // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/ - readCommitEnvVar('CF_REVISION') || - // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/ - readCommitEnvVar('CM_COMMIT') || - // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables - readCommitEnvVar('CF_PAGES_COMMIT_SHA') || - // Drone - https://docs.drone.io/pipeline/environment/reference/ - readCommitEnvVar('DRONE_COMMIT_SHA') || - // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables - readCommitEnvVar('FC_GIT_COMMIT_SHA') || - // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci - readCommitEnvVar('HEROKU_TEST_RUN_COMMIT_VERSION') || - // Heroku #2 https://devcenter.heroku.com/articles/dyno-metadata#dyno-metadata - readCommitEnvVar('HEROKU_BUILD_COMMIT') || - // Heroku #3 (deprecated by Heroku, kept for backward compatibility) - readCommitEnvVar('HEROKU_SLUG_COMMIT') || - // Railway - https://docs.railway.app/reference/variables#git-variables - readCommitEnvVar('RAILWAY_GIT_COMMIT_SHA') || - // Render - https://render.com/docs/environment-variables - readCommitEnvVar('RENDER_GIT_COMMIT') || - // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables - readCommitEnvVar('SEMAPHORE_GIT_SHA') || - // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - readCommitEnvVar('TRAVIS_PULL_REQUEST_SHA') || - // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - 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) - readCommitEnvVar('ZEIT_GITHUB_COMMIT_SHA') || - readCommitEnvVar('ZEIT_GITLAB_COMMIT_SHA') || - readCommitEnvVar('ZEIT_BITBUCKET_COMMIT_SHA'); - - 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 - readCommitEnvVar('SOURCE_COMMIT') || - // Heroku #3 https://devcenter.heroku.com/changelog-items/630 - readCommitEnvVar('SOURCE_VERSION') || - // Jenkins - https://plugins.jenkins.io/git/#environment-variables - readCommitEnvVar('GIT_COMMIT') || - // 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) sets CI_COMMIT_SHA, which the - // GitLab check above already reads. - - return ( - possibleReleaseNameOfGitProvider() || - possibleReleaseNameOfCiProvidersWithSpecificEnvVar() || - possibleReleaseNameOfCiProvidersWithGenericEnvVar() || - fallback - ); -} - -/** - * 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; + return getReleaseFromCommitEnv() || fallback; } function getTraceLifecycleFromEnv(envVar: string | undefined): 'static' | 'stream' | undefined {