UNPKG

dd-trace

Version:

Datadog APM tracing client for JavaScript

844 lines (767 loc) 27.9 kB
'use strict' const { readFileSync, readdirSync, existsSync } = require('fs') const path = require('path') const { getEnvironmentVariable, getEnvironmentVariables, getValueFromEnvSources } = require('../../config/helper') const { GIT_BRANCH, GIT_COMMIT_SHA, GIT_TAG, GIT_COMMIT_AUTHOR_EMAIL, GIT_COMMIT_AUTHOR_NAME, GIT_COMMIT_MESSAGE, GIT_COMMIT_AUTHOR_DATE, GIT_COMMIT_HEAD_SHA, GIT_PULL_REQUEST_BASE_BRANCH_SHA, GIT_PULL_REQUEST_BASE_BRANCH, GIT_REPOSITORY_URL, CI_PIPELINE_ID, CI_PIPELINE_NAME, CI_PIPELINE_NUMBER, CI_PIPELINE_URL, CI_PROVIDER_NAME, CI_WORKSPACE_PATH, CI_JOB_URL, CI_JOB_NAME, CI_STAGE_NAME, CI_ENV_VARS, GIT_COMMIT_COMMITTER_NAME, GIT_COMMIT_COMMITTER_EMAIL, CI_NODE_LABELS, CI_NODE_NAME, PR_NUMBER, CI_JOB_ID, GIT_PULL_REQUEST_BASE_BRANCH_HEAD_SHA, } = require('./tags') const { filterSensitiveInfoFromRepository } = require('./url') // Receives a string with the form 'John Doe <john.doe@gmail.com>' // and returns { name: 'John Doe', email: 'john.doe@gmail.com' } function parseEmailAndName (emailAndName) { if (!emailAndName) { return { name: '', email: '' } } let name = '' let email = '' const matchNameAndEmail = emailAndName.match(/(?:"?([^"]*)"?\s)?(?:<?(.+@[^>]+)>?)/) if (matchNameAndEmail) { name = matchNameAndEmail[1] email = matchNameAndEmail[2] } return { name, email } } function removeEmptyValues (tags) { return Object.keys(tags).reduce((filteredTags, tag) => { if (!tags[tag]) { return filteredTags } return { ...filteredTags, [tag]: tags[tag], } }, {}) } function normalizeTag (targetTags, tagKey, normalize) { if (targetTags[tagKey]) { targetTags[tagKey] = normalize(targetTags[tagKey]) } } function normalizeRef (ref) { if (!ref) { return ref } return ref.replaceAll(/origin\/|refs\/heads\/|tags\//gm, '') } function resolveTilde (filePath) { if (!filePath || typeof filePath !== 'string') { return '' } // '~/folder/path' or '~' if (filePath[0] === '~' && (filePath[1] === '/' || filePath.length === 1)) { return filePath.replace('~', getEnvironmentVariable('HOME')) } return filePath } function normalizeNumber (number) { if (typeof number !== 'number') { return number } return number.toString() } function getGitHubEventPayload () { const path = getEnvironmentVariable('GITHUB_EVENT_PATH') if (!path) { return } return JSON.parse(readFileSync(path, 'utf8')) } function getJobIDFromDiagFile (runnerTemp) { if (!runnerTemp || !existsSync(runnerTemp)) { return null } // RUNNER_TEMP usually looks like: // Linux/mac hosted: /home/runner/work/_temp // Windows hosted: C:\actions-runner\_work\_temp // Self-hosted (unix): /opt/actions-runner/_work/_temp const workDir = path.dirname(runnerTemp) // .../work or .../_work const runnerRoot = path.dirname(workDir) // /home/runner/ (runner root) const dirs = [ path.join(runnerRoot, 'cached', '_diag'), path.join(runnerRoot, '_diag'), path.join(runnerRoot, 'actions-runner', 'cached', '_diag'), path.join(runnerRoot, 'actions-runner', '_diag'), ] const isWin = process.platform === 'win32' // Hardcoded fallbacks if (isWin) { dirs.push( 'C:/actions-runner/cached/_diag', 'C:/actions-runner/_diag', ) } else { dirs.push( '/home/runner/actions-runner/cached/_diag', '/home/runner/actions-runner/_diag', '/opt/actions-runner/_diag', ) } // Remove duplicates const possibleDiagsPaths = [...new Set(dirs)] // This will hold the names of the worker log files that (potentially) contain the Job ID let workerLogFiles = [] // This will hold the chosen diagnostics path (between the ones that are contemplated in possibleDiagsPath) let chosenDiagPath = '' for (const diagPath of possibleDiagsPaths) { try { // Obtain a list of fs.Dirent objects of the files in diagPath const files = readdirSync(diagPath, { withFileTypes: true }) // Check if there are valid potential log files const potentialLogs = files .filter((file) => file.isFile() && file.name.startsWith('Worker_')) .map((file) => file.name) if (potentialLogs.length > 0) { chosenDiagPath = diagPath workerLogFiles = potentialLogs break // No need to keep looking for more log files } } catch (error) { // If the directory was not found, just look in the next one if (error instanceof Error && 'code' in error && error.code === 'ENOENT') { continue } // Any other kind of error must force a return return null } } // Get the job ID via regex for (const logFile of workerLogFiles) { const filePath = path.posix.join(chosenDiagPath, logFile) const content = readFileSync(filePath, 'utf8') const match = content.match(/"job":\s*{[\s\S]*?"v"\s*:\s*(\d+)(?:\.0)?/) // match[1] is the captured group with the display name if (match && match[1]) { return match[1] } } return null } module.exports = { normalizeRef, getJobIDFromDiagFile, getCIMetadata () { const env = getEnvironmentVariables() let tags = {} if (env.JENKINS_URL) { const { WORKSPACE, BUILD_TAG, JOB_NAME, BUILD_NUMBER, BUILD_URL, GIT_BRANCH: JENKINS_GIT_BRANCH, GIT_COMMIT: JENKINS_GIT_COMMIT, GIT_URL: JENKINS_GIT_REPOSITORY_URL, GIT_URL_1: JENKINS_GIT_REPOSITORY_URL_1, NODE_NAME, NODE_LABELS, CHANGE_ID, CHANGE_TARGET, } = env const DD_CUSTOM_TRACE_ID = getValueFromEnvSources('DD_CUSTOM_TRACE_ID') tags = { [CI_PIPELINE_ID]: BUILD_TAG, [CI_PIPELINE_NUMBER]: BUILD_NUMBER, [CI_PIPELINE_URL]: BUILD_URL, [CI_PROVIDER_NAME]: 'jenkins', [GIT_COMMIT_SHA]: JENKINS_GIT_COMMIT, [GIT_REPOSITORY_URL]: JENKINS_GIT_REPOSITORY_URL || JENKINS_GIT_REPOSITORY_URL_1, [CI_WORKSPACE_PATH]: WORKSPACE, [CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID }), [CI_NODE_NAME]: NODE_NAME, [PR_NUMBER]: CHANGE_ID, [GIT_PULL_REQUEST_BASE_BRANCH]: CHANGE_TARGET, } if (NODE_LABELS) { let nodeLabels try { nodeLabels = JSON.stringify(NODE_LABELS.split(' ')) tags[CI_NODE_LABELS] = nodeLabels } catch { // ignore errors } } const isTag = JENKINS_GIT_BRANCH && JENKINS_GIT_BRANCH.includes('tags/') const refKey = isTag ? GIT_TAG : GIT_BRANCH const ref = normalizeRef(JENKINS_GIT_BRANCH) tags[refKey] = ref if (JOB_NAME) { // Job names can contain parameters, e.g. jobName/KEY1=VALUE1,KEY2=VALUE2/branchName const jobNameAndParams = JOB_NAME.split('/') const finalPipelineName = jobNameAndParams.length > 1 && jobNameAndParams[1].includes('=') ? jobNameAndParams[0] : JOB_NAME.replace(`/${ref}`, '') tags[CI_PIPELINE_NAME] = finalPipelineName } } if (env.GITLAB_CI) { const { CI_PIPELINE_ID: GITLAB_PIPELINE_ID, CI_PROJECT_PATH, CI_PIPELINE_IID, CI_PIPELINE_URL: GITLAB_PIPELINE_URL, CI_PROJECT_DIR, CI_COMMIT_REF_NAME, CI_COMMIT_TAG, CI_COMMIT_SHA, CI_REPOSITORY_URL, CI_JOB_URL: GITLAB_CI_JOB_URL, CI_JOB_STAGE, CI_JOB_NAME: GITLAB_CI_JOB_NAME, CI_COMMIT_MESSAGE, CI_COMMIT_TIMESTAMP, CI_COMMIT_AUTHOR, CI_PROJECT_URL: GITLAB_PROJECT_URL, CI_JOB_ID: GITLAB_CI_JOB_ID, CI_RUNNER_ID, CI_RUNNER_TAGS, CI_MERGE_REQUEST_TARGET_BRANCH_NAME, CI_MERGE_REQUEST_IID, CI_MERGE_REQUEST_TARGET_BRANCH_SHA, CI_MERGE_REQUEST_DIFF_BASE_SHA, } = env const { name, email } = parseEmailAndName(CI_COMMIT_AUTHOR) tags = { [CI_PIPELINE_ID]: GITLAB_PIPELINE_ID, [CI_PIPELINE_NAME]: CI_PROJECT_PATH, [CI_PIPELINE_NUMBER]: CI_PIPELINE_IID, [CI_PROVIDER_NAME]: 'gitlab', [GIT_COMMIT_SHA]: CI_COMMIT_SHA, [GIT_REPOSITORY_URL]: CI_REPOSITORY_URL, [CI_JOB_URL]: GITLAB_CI_JOB_URL, [GIT_TAG]: CI_COMMIT_TAG, [GIT_BRANCH]: CI_COMMIT_REF_NAME, [CI_WORKSPACE_PATH]: CI_PROJECT_DIR, [CI_PIPELINE_URL]: GITLAB_PIPELINE_URL, [CI_STAGE_NAME]: CI_JOB_STAGE, [CI_JOB_NAME]: GITLAB_CI_JOB_NAME, [GIT_COMMIT_MESSAGE]: CI_COMMIT_MESSAGE, [GIT_COMMIT_AUTHOR_NAME]: name, [GIT_COMMIT_AUTHOR_EMAIL]: email, [GIT_COMMIT_AUTHOR_DATE]: CI_COMMIT_TIMESTAMP, [CI_ENV_VARS]: JSON.stringify({ CI_PROJECT_URL: GITLAB_PROJECT_URL, CI_PIPELINE_ID: GITLAB_PIPELINE_ID, CI_JOB_ID: GITLAB_CI_JOB_ID, }), [CI_NODE_LABELS]: CI_RUNNER_TAGS, [CI_NODE_NAME]: CI_RUNNER_ID, [GIT_PULL_REQUEST_BASE_BRANCH]: CI_MERGE_REQUEST_TARGET_BRANCH_NAME, [PR_NUMBER]: CI_MERGE_REQUEST_IID, [CI_JOB_ID]: GITLAB_CI_JOB_ID, [GIT_PULL_REQUEST_BASE_BRANCH_SHA]: CI_MERGE_REQUEST_DIFF_BASE_SHA, [GIT_PULL_REQUEST_BASE_BRANCH_HEAD_SHA]: CI_MERGE_REQUEST_TARGET_BRANCH_SHA, } } if (env.CIRCLECI) { const { CIRCLE_WORKFLOW_ID, CIRCLE_PROJECT_REPONAME, CIRCLE_BUILD_URL, CIRCLE_WORKING_DIRECTORY, CIRCLE_BRANCH, CIRCLE_TAG, CIRCLE_SHA1, CIRCLE_REPOSITORY_URL, CIRCLE_JOB, CIRCLE_BUILD_NUM, CIRCLE_PR_NUMBER, } = env const pipelineUrl = `https://app.circleci.com/pipelines/workflows/${CIRCLE_WORKFLOW_ID}` tags = { [CI_PIPELINE_ID]: CIRCLE_WORKFLOW_ID, [CI_PIPELINE_NAME]: CIRCLE_PROJECT_REPONAME, [CI_PIPELINE_URL]: pipelineUrl, [CI_JOB_NAME]: CIRCLE_JOB, [CI_PROVIDER_NAME]: 'circleci', [GIT_COMMIT_SHA]: CIRCLE_SHA1, [GIT_REPOSITORY_URL]: CIRCLE_REPOSITORY_URL, [CI_JOB_URL]: CIRCLE_BUILD_URL, [CI_WORKSPACE_PATH]: CIRCLE_WORKING_DIRECTORY, [GIT_TAG]: CIRCLE_TAG, [GIT_BRANCH]: CIRCLE_BRANCH, [CI_ENV_VARS]: JSON.stringify({ CIRCLE_WORKFLOW_ID, CIRCLE_BUILD_NUM, }), [PR_NUMBER]: CIRCLE_PR_NUMBER, [CI_JOB_ID]: CIRCLE_BUILD_NUM, } } if (env.GITHUB_ACTIONS || env.GITHUB_ACTION) { const { GITHUB_RUN_ID, GITHUB_WORKFLOW, GITHUB_RUN_NUMBER, GITHUB_WORKSPACE, GITHUB_HEAD_REF, GITHUB_REF, GITHUB_SHA, GITHUB_REPOSITORY, GITHUB_SERVER_URL, GITHUB_RUN_ATTEMPT, GITHUB_JOB, GITHUB_BASE_REF, RUNNER_TEMP, JOB_CHECK_RUN_ID, } = env const repositoryURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git` let pipelineURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}` if (GITHUB_RUN_ATTEMPT) { pipelineURL = `${pipelineURL}/attempts/${GITHUB_RUN_ATTEMPT}` } // Build the job url extracting the job ID. If extraction fails, job url is constructed as a generalized url const GITHUB_JOB_ID = JOB_CHECK_RUN_ID ?? getJobIDFromDiagFile(RUNNER_TEMP) const jobUrl = GITHUB_JOB_ID === null ? `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks` : `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/job/${GITHUB_JOB_ID}` const ref = GITHUB_HEAD_REF || GITHUB_REF || '' const refKey = ref.includes('tags/') ? GIT_TAG : GIT_BRANCH // Both pipeline URL and job URL include GITHUB_SERVER_URL, which can include user credentials, // so we pass them through `filterSensitiveInfoFromRepository`. tags = { [CI_PIPELINE_ID]: GITHUB_RUN_ID, [CI_PIPELINE_NAME]: GITHUB_WORKFLOW, [CI_PIPELINE_NUMBER]: GITHUB_RUN_NUMBER, [CI_PIPELINE_URL]: filterSensitiveInfoFromRepository(pipelineURL), [CI_PROVIDER_NAME]: 'github', [GIT_COMMIT_SHA]: GITHUB_SHA, [GIT_REPOSITORY_URL]: repositoryURL, [CI_JOB_URL]: filterSensitiveInfoFromRepository(jobUrl), [CI_JOB_NAME]: GITHUB_JOB, [CI_WORKSPACE_PATH]: GITHUB_WORKSPACE, [refKey]: ref, [CI_ENV_VARS]: JSON.stringify({ GITHUB_SERVER_URL: filterSensitiveInfoFromRepository(GITHUB_SERVER_URL), GITHUB_REPOSITORY, GITHUB_RUN_ID, GITHUB_RUN_ATTEMPT, }), [CI_JOB_ID]: GITHUB_JOB_ID ?? GITHUB_JOB, } if (GITHUB_BASE_REF) { // `pull_request` or `pull_request_target` event tags[GIT_PULL_REQUEST_BASE_BRANCH] = GITHUB_BASE_REF try { const eventContent = getGitHubEventPayload() tags[GIT_PULL_REQUEST_BASE_BRANCH_HEAD_SHA] = eventContent.pull_request.base.sha tags[GIT_COMMIT_HEAD_SHA] = eventContent.pull_request.head.sha } catch { // ignore malformed event content } } } if (env.APPVEYOR) { const { APPVEYOR_REPO_NAME, APPVEYOR_REPO_PROVIDER, APPVEYOR_BUILD_FOLDER, APPVEYOR_BUILD_ID, APPVEYOR_BUILD_NUMBER, APPVEYOR_REPO_COMMIT, APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH, APPVEYOR_REPO_BRANCH, APPVEYOR_REPO_TAG_NAME, APPVEYOR_REPO_COMMIT_AUTHOR, APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL, APPVEYOR_REPO_COMMIT_MESSAGE, APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED, APPVEYOR_PULL_REQUEST_HEAD_COMMIT, APPVEYOR_PULL_REQUEST_NUMBER, } = env const pipelineUrl = `https://ci.appveyor.com/project/${APPVEYOR_REPO_NAME}/builds/${APPVEYOR_BUILD_ID}` tags = { [CI_PROVIDER_NAME]: 'appveyor', [CI_PIPELINE_URL]: pipelineUrl, [CI_PIPELINE_ID]: APPVEYOR_BUILD_ID, [CI_PIPELINE_NAME]: APPVEYOR_REPO_NAME, [CI_PIPELINE_NUMBER]: APPVEYOR_BUILD_NUMBER, [CI_JOB_URL]: pipelineUrl, [CI_WORKSPACE_PATH]: APPVEYOR_BUILD_FOLDER, [GIT_COMMIT_AUTHOR_NAME]: APPVEYOR_REPO_COMMIT_AUTHOR, [GIT_COMMIT_AUTHOR_EMAIL]: APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL, [GIT_COMMIT_MESSAGE]: APPVEYOR_REPO_COMMIT_MESSAGE + '\n' + APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED, [GIT_COMMIT_HEAD_SHA]: APPVEYOR_PULL_REQUEST_HEAD_COMMIT, [PR_NUMBER]: APPVEYOR_PULL_REQUEST_NUMBER, } if (APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH) { tags[GIT_PULL_REQUEST_BASE_BRANCH] = APPVEYOR_REPO_BRANCH } if (APPVEYOR_REPO_PROVIDER === 'github') { tags = { ...tags, [GIT_REPOSITORY_URL]: `https://github.com/${APPVEYOR_REPO_NAME}.git`, [GIT_COMMIT_SHA]: APPVEYOR_REPO_COMMIT, [GIT_TAG]: APPVEYOR_REPO_TAG_NAME, [GIT_BRANCH]: APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH || APPVEYOR_REPO_BRANCH, } } } if (env.TF_BUILD) { const { BUILD_SOURCESDIRECTORY, BUILD_BUILDID, BUILD_DEFINITIONNAME, SYSTEM_TEAMFOUNDATIONSERVERURI, SYSTEM_TEAMPROJECTID, SYSTEM_JOBID, SYSTEM_TASKINSTANCEID, SYSTEM_PULLREQUEST_SOURCEBRANCH, BUILD_SOURCEBRANCH, BUILD_SOURCEBRANCHNAME, SYSTEM_PULLREQUEST_SOURCECOMMITID, SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI, BUILD_REPOSITORY_URI, BUILD_SOURCEVERSION, BUILD_REQUESTEDFORID, BUILD_REQUESTEDFOREMAIL, BUILD_SOURCEVERSIONMESSAGE, SYSTEM_STAGEDISPLAYNAME, SYSTEM_JOBDISPLAYNAME, SYSTEM_PULLREQUEST_PULLREQUESTNUMBER, SYSTEM_PULLREQUEST_TARGETBRANCH, } = env const ref = SYSTEM_PULLREQUEST_SOURCEBRANCH || BUILD_SOURCEBRANCH || BUILD_SOURCEBRANCHNAME const refKey = (ref || '').includes('tags/') ? GIT_TAG : GIT_BRANCH tags = { [CI_PROVIDER_NAME]: 'azurepipelines', [CI_PIPELINE_ID]: BUILD_BUILDID, [CI_PIPELINE_NAME]: BUILD_DEFINITIONNAME, [CI_PIPELINE_NUMBER]: BUILD_BUILDID, [GIT_COMMIT_SHA]: SYSTEM_PULLREQUEST_SOURCECOMMITID || BUILD_SOURCEVERSION, [CI_WORKSPACE_PATH]: BUILD_SOURCESDIRECTORY, [GIT_REPOSITORY_URL]: SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI || BUILD_REPOSITORY_URI, [refKey]: ref, [GIT_COMMIT_AUTHOR_NAME]: BUILD_REQUESTEDFORID, [GIT_COMMIT_AUTHOR_EMAIL]: BUILD_REQUESTEDFOREMAIL, [GIT_COMMIT_MESSAGE]: BUILD_SOURCEVERSIONMESSAGE, [CI_STAGE_NAME]: SYSTEM_STAGEDISPLAYNAME, [CI_JOB_NAME]: SYSTEM_JOBDISPLAYNAME, [CI_ENV_VARS]: JSON.stringify({ SYSTEM_TEAMPROJECTID, BUILD_BUILDID, SYSTEM_JOBID }), [PR_NUMBER]: SYSTEM_PULLREQUEST_PULLREQUESTNUMBER, [GIT_PULL_REQUEST_BASE_BRANCH]: SYSTEM_PULLREQUEST_TARGETBRANCH, [CI_JOB_ID]: SYSTEM_JOBID, } if (SYSTEM_TEAMFOUNDATIONSERVERURI && SYSTEM_TEAMPROJECTID && BUILD_BUILDID) { const baseUrl = `${SYSTEM_TEAMFOUNDATIONSERVERURI}${SYSTEM_TEAMPROJECTID}/_build/results?buildId=${BUILD_BUILDID}` const pipelineUrl = baseUrl const jobUrl = `${baseUrl}&view=logs&j=${SYSTEM_JOBID}&t=${SYSTEM_TASKINSTANCEID}` tags = { ...tags, [CI_PIPELINE_URL]: pipelineUrl, [CI_JOB_URL]: jobUrl, } } } if (env.BITBUCKET_COMMIT) { const { BITBUCKET_REPO_FULL_NAME, BITBUCKET_BUILD_NUMBER, BITBUCKET_BRANCH, BITBUCKET_COMMIT, BITBUCKET_GIT_SSH_ORIGIN, BITBUCKET_GIT_HTTP_ORIGIN, BITBUCKET_TAG, BITBUCKET_PIPELINE_UUID, BITBUCKET_CLONE_DIR, BITBUCKET_PR_DESTINATION_BRANCH, BITBUCKET_PR_ID, } = env const url = `https://bitbucket.org/${BITBUCKET_REPO_FULL_NAME}/addon/pipelines/home#!/results/${BITBUCKET_BUILD_NUMBER}` tags = { [CI_PROVIDER_NAME]: 'bitbucket', [GIT_COMMIT_SHA]: BITBUCKET_COMMIT, [CI_PIPELINE_NUMBER]: BITBUCKET_BUILD_NUMBER, [CI_PIPELINE_NAME]: BITBUCKET_REPO_FULL_NAME, [CI_JOB_URL]: url, [CI_PIPELINE_URL]: url, [GIT_BRANCH]: BITBUCKET_BRANCH, [GIT_TAG]: BITBUCKET_TAG, [GIT_REPOSITORY_URL]: BITBUCKET_GIT_SSH_ORIGIN || BITBUCKET_GIT_HTTP_ORIGIN, [CI_WORKSPACE_PATH]: BITBUCKET_CLONE_DIR, [CI_PIPELINE_ID]: BITBUCKET_PIPELINE_UUID && BITBUCKET_PIPELINE_UUID.replaceAll(/{|}/gm, ''), [GIT_PULL_REQUEST_BASE_BRANCH]: BITBUCKET_PR_DESTINATION_BRANCH, [PR_NUMBER]: BITBUCKET_PR_ID, } } if (env.BITRISE_BUILD_SLUG) { const { BITRISE_GIT_COMMIT, GIT_CLONE_COMMIT_HASH, BITRISEIO_GIT_BRANCH_DEST, BITRISE_GIT_BRANCH, BITRISE_BUILD_SLUG, BITRISE_TRIGGERED_WORKFLOW_ID, BITRISE_BUILD_NUMBER, BITRISE_BUILD_URL, BITRISE_SOURCE_DIR, GIT_REPOSITORY_URL: BITRISE_GIT_REPOSITORY_URL, BITRISE_GIT_TAG, BITRISE_GIT_MESSAGE, BITRISE_PULL_REQUEST, } = env tags = { [CI_PROVIDER_NAME]: 'bitrise', [CI_PIPELINE_ID]: BITRISE_BUILD_SLUG, [CI_PIPELINE_NAME]: BITRISE_TRIGGERED_WORKFLOW_ID, [CI_PIPELINE_NUMBER]: BITRISE_BUILD_NUMBER, [CI_PIPELINE_URL]: BITRISE_BUILD_URL, [GIT_COMMIT_SHA]: BITRISE_GIT_COMMIT || GIT_CLONE_COMMIT_HASH, [GIT_REPOSITORY_URL]: BITRISE_GIT_REPOSITORY_URL, [CI_WORKSPACE_PATH]: BITRISE_SOURCE_DIR, [GIT_TAG]: BITRISE_GIT_TAG, [GIT_BRANCH]: BITRISEIO_GIT_BRANCH_DEST || BITRISE_GIT_BRANCH, [GIT_COMMIT_MESSAGE]: BITRISE_GIT_MESSAGE, [GIT_PULL_REQUEST_BASE_BRANCH]: BITRISEIO_GIT_BRANCH_DEST, [PR_NUMBER]: BITRISE_PULL_REQUEST, } } if (env.BUILDKITE) { const { BUILDKITE_BRANCH, BUILDKITE_COMMIT, BUILDKITE_REPO, BUILDKITE_TAG, BUILDKITE_BUILD_ID, BUILDKITE_PIPELINE_SLUG, BUILDKITE_BUILD_NUMBER, BUILDKITE_BUILD_URL, BUILDKITE_JOB_ID, BUILDKITE_BUILD_CHECKOUT_PATH, BUILDKITE_BUILD_AUTHOR, BUILDKITE_BUILD_AUTHOR_EMAIL, BUILDKITE_MESSAGE, BUILDKITE_AGENT_ID, BUILDKITE_PULL_REQUEST, BUILDKITE_PULL_REQUEST_BASE_BRANCH, } = env const extraTags = Object.keys(env).filter(envVar => envVar.startsWith('BUILDKITE_AGENT_META_DATA_') ).map((metadataKey) => { const key = metadataKey.replace('BUILDKITE_AGENT_META_DATA_', '').toLowerCase() return `${key}:${env[metadataKey]}` }) tags = { [CI_PROVIDER_NAME]: 'buildkite', [CI_PIPELINE_ID]: BUILDKITE_BUILD_ID, [CI_PIPELINE_NAME]: BUILDKITE_PIPELINE_SLUG, [CI_PIPELINE_NUMBER]: BUILDKITE_BUILD_NUMBER, [CI_PIPELINE_URL]: BUILDKITE_BUILD_URL, [CI_JOB_URL]: `${BUILDKITE_BUILD_URL}#${BUILDKITE_JOB_ID}`, [GIT_COMMIT_SHA]: BUILDKITE_COMMIT, [CI_WORKSPACE_PATH]: BUILDKITE_BUILD_CHECKOUT_PATH, [GIT_REPOSITORY_URL]: BUILDKITE_REPO, [GIT_TAG]: BUILDKITE_TAG, [GIT_BRANCH]: BUILDKITE_BRANCH, [GIT_COMMIT_AUTHOR_NAME]: BUILDKITE_BUILD_AUTHOR, [GIT_COMMIT_AUTHOR_EMAIL]: BUILDKITE_BUILD_AUTHOR_EMAIL, [GIT_COMMIT_MESSAGE]: BUILDKITE_MESSAGE, [CI_ENV_VARS]: JSON.stringify({ BUILDKITE_BUILD_ID, BUILDKITE_JOB_ID, }), [CI_NODE_NAME]: BUILDKITE_AGENT_ID, [CI_NODE_LABELS]: JSON.stringify(extraTags), [PR_NUMBER]: BUILDKITE_PULL_REQUEST, [CI_JOB_ID]: BUILDKITE_JOB_ID, } if (BUILDKITE_PULL_REQUEST) { tags[GIT_PULL_REQUEST_BASE_BRANCH] = BUILDKITE_PULL_REQUEST_BASE_BRANCH } } if (env.TRAVIS) { const { TRAVIS_PULL_REQUEST_BRANCH, TRAVIS_BRANCH, TRAVIS_COMMIT, TRAVIS_REPO_SLUG, TRAVIS_TAG, TRAVIS_JOB_WEB_URL, TRAVIS_BUILD_ID, TRAVIS_BUILD_NUMBER, TRAVIS_BUILD_WEB_URL, TRAVIS_BUILD_DIR, TRAVIS_COMMIT_MESSAGE, TRAVIS_PULL_REQUEST, TRAVIS_PULL_REQUEST_SHA, } = env tags = { [CI_PROVIDER_NAME]: 'travisci', [CI_JOB_URL]: TRAVIS_JOB_WEB_URL, [CI_PIPELINE_ID]: TRAVIS_BUILD_ID, [CI_PIPELINE_NAME]: TRAVIS_REPO_SLUG, [CI_PIPELINE_NUMBER]: TRAVIS_BUILD_NUMBER, [CI_PIPELINE_URL]: TRAVIS_BUILD_WEB_URL, [GIT_COMMIT_SHA]: TRAVIS_COMMIT, [GIT_REPOSITORY_URL]: `https://github.com/${TRAVIS_REPO_SLUG}.git`, [CI_WORKSPACE_PATH]: TRAVIS_BUILD_DIR, [GIT_TAG]: TRAVIS_TAG, [GIT_BRANCH]: TRAVIS_PULL_REQUEST_BRANCH || TRAVIS_BRANCH, [GIT_COMMIT_MESSAGE]: TRAVIS_COMMIT_MESSAGE, [GIT_COMMIT_HEAD_SHA]: TRAVIS_PULL_REQUEST_SHA, [GIT_PULL_REQUEST_BASE_BRANCH]: TRAVIS_BRANCH, [PR_NUMBER]: TRAVIS_PULL_REQUEST, } } if (env.BUDDY) { const { BUDDY_EXECUTION_BRANCH, BUDDY_EXECUTION_ID, BUDDY_EXECUTION_REVISION, BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL, BUDDY_EXECUTION_REVISION_COMMITTER_NAME, BUDDY_EXECUTION_REVISION_MESSAGE, BUDDY_EXECUTION_TAG, BUDDY_EXECUTION_URL, BUDDY_PIPELINE_ID, BUDDY_PIPELINE_NAME, BUDDY_SCM_URL, BUDDY_RUN_PR_BASE_BRANCH, BUDDY_RUN_PR_NO, } = env tags = { [CI_PROVIDER_NAME]: 'buddy', [CI_PIPELINE_ID]: `${BUDDY_PIPELINE_ID}/${BUDDY_EXECUTION_ID}`, [CI_PIPELINE_NAME]: BUDDY_PIPELINE_NAME, [CI_PIPELINE_NUMBER]: BUDDY_EXECUTION_ID, [CI_PIPELINE_URL]: BUDDY_EXECUTION_URL, [GIT_COMMIT_SHA]: BUDDY_EXECUTION_REVISION, [GIT_REPOSITORY_URL]: BUDDY_SCM_URL, [GIT_BRANCH]: BUDDY_EXECUTION_BRANCH, [GIT_TAG]: BUDDY_EXECUTION_TAG, [GIT_COMMIT_MESSAGE]: BUDDY_EXECUTION_REVISION_MESSAGE, [GIT_COMMIT_COMMITTER_NAME]: BUDDY_EXECUTION_REVISION_COMMITTER_NAME, [GIT_COMMIT_COMMITTER_EMAIL]: BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL, [GIT_PULL_REQUEST_BASE_BRANCH]: BUDDY_RUN_PR_BASE_BRANCH, [PR_NUMBER]: BUDDY_RUN_PR_NO, } } if (env.TEAMCITY_VERSION) { const { BUILD_URL, TEAMCITY_BUILDCONF_NAME, DATADOG_BUILD_ID, TEAMCITY_PULLREQUEST_NUMBER, TEAMCITY_PULLREQUEST_TARGET_BRANCH, } = env tags = { [CI_PROVIDER_NAME]: 'teamcity', [CI_JOB_URL]: BUILD_URL, [CI_JOB_NAME]: TEAMCITY_BUILDCONF_NAME, [CI_ENV_VARS]: JSON.stringify({ DATADOG_BUILD_ID, }), [PR_NUMBER]: TEAMCITY_PULLREQUEST_NUMBER, [GIT_PULL_REQUEST_BASE_BRANCH]: TEAMCITY_PULLREQUEST_TARGET_BRANCH, } } if (env.CF_BUILD_ID) { const { CF_BUILD_ID, CF_PIPELINE_NAME, CF_BUILD_URL, CF_STEP_NAME, CF_BRANCH, CF_PULL_REQUEST_NUMBER, CF_PULL_REQUEST_TARGET, } = env tags = { [CI_PROVIDER_NAME]: 'codefresh', [CI_PIPELINE_ID]: CF_BUILD_ID, [CI_PIPELINE_NAME]: CF_PIPELINE_NAME, [CI_PIPELINE_URL]: CF_BUILD_URL, [CI_JOB_NAME]: CF_STEP_NAME, [CI_ENV_VARS]: JSON.stringify({ CF_BUILD_ID, }), [PR_NUMBER]: CF_PULL_REQUEST_NUMBER, [GIT_PULL_REQUEST_BASE_BRANCH]: CF_PULL_REQUEST_TARGET, } const isTag = CF_BRANCH && CF_BRANCH.includes('tags/') const refKey = isTag ? GIT_TAG : GIT_BRANCH const ref = normalizeRef(CF_BRANCH) tags[refKey] = ref } if (env.CODEBUILD_INITIATOR?.startsWith('codepipeline/')) { const DD_ACTION_EXECUTION_ID = getValueFromEnvSources('DD_ACTION_EXECUTION_ID') const DD_PIPELINE_EXECUTION_ID = getValueFromEnvSources('DD_PIPELINE_EXECUTION_ID') tags = { [CI_PROVIDER_NAME]: 'awscodepipeline', [CI_PIPELINE_ID]: DD_PIPELINE_EXECUTION_ID, [CI_ENV_VARS]: JSON.stringify({ CODEBUILD_BUILD_ARN: env.CODEBUILD_BUILD_ARN, DD_PIPELINE_EXECUTION_ID, DD_ACTION_EXECUTION_ID, }), [CI_JOB_ID]: DD_ACTION_EXECUTION_ID, } } if (env.DRONE && env.CI) { const { DRONE_BUILD_NUMBER, DRONE_BUILD_LINK, DRONE_STEP_NAME, DRONE_STAGE_NAME, DRONE_WORKSPACE, DRONE_GIT_HTTP_URL, DRONE_COMMIT_SHA, DRONE_BRANCH, DRONE_TAG, DRONE_COMMIT_AUTHOR_NAME, DRONE_COMMIT_AUTHOR_EMAIL, DRONE_COMMIT_MESSAGE, DRONE_PULL_REQUEST, DRONE_TARGET_BRANCH, } = env tags = { [CI_PROVIDER_NAME]: 'drone', [CI_PIPELINE_NUMBER]: DRONE_BUILD_NUMBER, [CI_PIPELINE_URL]: DRONE_BUILD_LINK, [CI_JOB_NAME]: DRONE_STEP_NAME, [CI_STAGE_NAME]: DRONE_STAGE_NAME, [CI_WORKSPACE_PATH]: DRONE_WORKSPACE, [GIT_REPOSITORY_URL]: DRONE_GIT_HTTP_URL, [GIT_COMMIT_SHA]: DRONE_COMMIT_SHA, [GIT_BRANCH]: DRONE_BRANCH, [GIT_TAG]: DRONE_TAG, [GIT_COMMIT_AUTHOR_NAME]: DRONE_COMMIT_AUTHOR_NAME, [GIT_COMMIT_AUTHOR_EMAIL]: DRONE_COMMIT_AUTHOR_EMAIL, [GIT_COMMIT_MESSAGE]: DRONE_COMMIT_MESSAGE, [PR_NUMBER]: DRONE_PULL_REQUEST, [GIT_PULL_REQUEST_BASE_BRANCH]: DRONE_TARGET_BRANCH, } } normalizeTag(tags, CI_WORKSPACE_PATH, resolveTilde) normalizeTag(tags, GIT_REPOSITORY_URL, filterSensitiveInfoFromRepository) normalizeTag(tags, GIT_BRANCH, normalizeRef) normalizeTag(tags, GIT_TAG, normalizeRef) normalizeTag(tags, GIT_PULL_REQUEST_BASE_BRANCH, normalizeRef) normalizeTag(tags, PR_NUMBER, normalizeNumber) return removeEmptyValues(tags) }, }