From 0f1490fd8d1dbd73befe37e8ef6f7e9a91063cc6 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 13:06:14 +0200 Subject: [PATCH 01/31] move git constants here from dd-trace-rb --- lib/datadog/ci/ext/environment.rb | 204 +++++++++++++++--------------- lib/datadog/ci/ext/git.rb | 37 ++++++ sig/datadog/ci/ext/git.rbs | 53 ++++++++ 3 files changed, 192 insertions(+), 102 deletions(-) create mode 100644 lib/datadog/ci/ext/git.rb create mode 100644 sig/datadog/ci/ext/git.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 98ec37e8..a26c5865 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -require "datadog/core/git/ext" - require "open3" require "json" +require_relative "git" + module Datadog module CI module Ext @@ -50,16 +50,16 @@ def tags(env) # If user defined metadata is defined, overwrite tags.merge!(extract_user_defined_git(env)) - if !tags[Core::Git::Ext::TAG_BRANCH].nil? && tags[Core::Git::Ext::TAG_BRANCH].include?("tags/") - tags[Core::Git::Ext::TAG_TAG] = tags[Core::Git::Ext::TAG_BRANCH] - tags.delete(Core::Git::Ext::TAG_BRANCH) + if !tags[Git::TAG_BRANCH].nil? && tags[Git::TAG_BRANCH].include?("tags/") + tags[Git::TAG_TAG] = tags[Git::TAG_BRANCH] + tags.delete(Git::TAG_BRANCH) end # Normalize Git references - tags[Core::Git::Ext::TAG_TAG] = normalize_ref(tags[Core::Git::Ext::TAG_TAG]) - tags[Core::Git::Ext::TAG_BRANCH] = normalize_ref(tags[Core::Git::Ext::TAG_BRANCH]) - tags[Core::Git::Ext::TAG_REPOSITORY_URL] = filter_sensitive_info( - tags[Core::Git::Ext::TAG_REPOSITORY_URL] + tags[Git::TAG_TAG] = normalize_ref(tags[Git::TAG_TAG]) + tags[Git::TAG_BRANCH] = normalize_ref(tags[Git::TAG_BRANCH]) + tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info( + tags[Git::TAG_REPOSITORY_URL] ) # Expand ~ @@ -107,19 +107,19 @@ def extract_appveyor(env) { TAG_PROVIDER_NAME => "appveyor", - Core::Git::Ext::TAG_REPOSITORY_URL => repository, - Core::Git::Ext::TAG_COMMIT_SHA => commit, + Git::TAG_REPOSITORY_URL => repository, + Git::TAG_COMMIT_SHA => commit, TAG_WORKSPACE_PATH => env["APPVEYOR_BUILD_FOLDER"], TAG_PIPELINE_ID => env["APPVEYOR_BUILD_ID"], TAG_PIPELINE_NAME => env["APPVEYOR_REPO_NAME"], TAG_PIPELINE_NUMBER => env["APPVEYOR_BUILD_NUMBER"], TAG_PIPELINE_URL => url, TAG_JOB_URL => url, - Core::Git::Ext::TAG_BRANCH => branch, - Core::Git::Ext::TAG_TAG => tag, - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env["APPVEYOR_REPO_COMMIT_AUTHOR"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env["APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => commit_message + Git::TAG_BRANCH => branch, + Git::TAG_TAG => tag, + Git::TAG_COMMIT_AUTHOR_NAME => env["APPVEYOR_REPO_COMMIT_AUTHOR"], + Git::TAG_COMMIT_AUTHOR_EMAIL => env["APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL"], + Git::TAG_COMMIT_MESSAGE => commit_message } end @@ -147,15 +147,15 @@ def extract_azure_pipelines(env) TAG_JOB_URL => job_url, TAG_STAGE_NAME => env["SYSTEM_STAGEDISPLAYNAME"], TAG_JOB_NAME => env["SYSTEM_JOBDISPLAYNAME"], - Core::Git::Ext::TAG_REPOSITORY_URL => + Git::TAG_REPOSITORY_URL => env["SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI"] || env["BUILD_REPOSITORY_URI"], - Core::Git::Ext::TAG_COMMIT_SHA => env["SYSTEM_PULLREQUEST_SOURCECOMMITID"] \ + Git::TAG_COMMIT_SHA => env["SYSTEM_PULLREQUEST_SOURCECOMMITID"] \ || env["BUILD_SOURCEVERSION"], - Core::Git::Ext::TAG_BRANCH => branch, - Core::Git::Ext::TAG_TAG => tag, - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env["BUILD_REQUESTEDFORID"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env["BUILD_REQUESTEDFOREMAIL"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env["BUILD_SOURCEVERSIONMESSAGE"], + Git::TAG_BRANCH => branch, + Git::TAG_TAG => tag, + Git::TAG_COMMIT_AUTHOR_NAME => env["BUILD_REQUESTEDFORID"], + Git::TAG_COMMIT_AUTHOR_EMAIL => env["BUILD_REQUESTEDFOREMAIL"], + Git::TAG_COMMIT_MESSAGE => env["BUILD_SOURCEVERSIONMESSAGE"], TAG_CI_ENV_VARS => { "SYSTEM_TEAMPROJECTID" => env["SYSTEM_TEAMPROJECTID"], "BUILD_BUILDID" => env["BUILD_BUILDID"], @@ -173,10 +173,10 @@ def extract_bitbucket(env) ) { - Core::Git::Ext::TAG_BRANCH => env["BITBUCKET_BRANCH"], - Core::Git::Ext::TAG_COMMIT_SHA => env["BITBUCKET_COMMIT"], - Core::Git::Ext::TAG_REPOSITORY_URL => repository_url, - Core::Git::Ext::TAG_TAG => env["BITBUCKET_TAG"], + Git::TAG_BRANCH => env["BITBUCKET_BRANCH"], + Git::TAG_COMMIT_SHA => env["BITBUCKET_COMMIT"], + Git::TAG_REPOSITORY_URL => repository_url, + Git::TAG_TAG => env["BITBUCKET_TAG"], TAG_JOB_URL => pipeline_url, TAG_PIPELINE_ID => env["BITBUCKET_PIPELINE_UUID"] ? env["BITBUCKET_PIPELINE_UUID"].tr("{}", "") : nil, TAG_PIPELINE_NAME => env["BITBUCKET_REPO_FULL_NAME"], @@ -195,22 +195,22 @@ def extract_buddy(env) TAG_PIPELINE_NUMBER => env["BUDDY_EXECUTION_ID"], TAG_PIPELINE_URL => env["BUDDY_EXECUTION_URL"], TAG_WORKSPACE_PATH => env["CI_WORKSPACE_PATH"], - Core::Git::Ext::TAG_REPOSITORY_URL => env["BUDDY_SCM_URL"], - Core::Git::Ext::TAG_COMMIT_SHA => env["BUDDY_EXECUTION_REVISION"], - Core::Git::Ext::TAG_BRANCH => env["BUDDY_EXECUTION_BRANCH"], - Core::Git::Ext::TAG_TAG => env["BUDDY_EXECUTION_TAG"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env["BUDDY_EXECUTION_REVISION_MESSAGE"], - Core::Git::Ext::TAG_COMMIT_COMMITTER_NAME => env["BUDDY_EXECUTION_REVISION_COMMITTER_NAME"], - Core::Git::Ext::TAG_COMMIT_COMMITTER_EMAIL => env["BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL"] + Git::TAG_REPOSITORY_URL => env["BUDDY_SCM_URL"], + Git::TAG_COMMIT_SHA => env["BUDDY_EXECUTION_REVISION"], + Git::TAG_BRANCH => env["BUDDY_EXECUTION_BRANCH"], + Git::TAG_TAG => env["BUDDY_EXECUTION_TAG"], + Git::TAG_COMMIT_MESSAGE => env["BUDDY_EXECUTION_REVISION_MESSAGE"], + Git::TAG_COMMIT_COMMITTER_NAME => env["BUDDY_EXECUTION_REVISION_COMMITTER_NAME"], + Git::TAG_COMMIT_COMMITTER_EMAIL => env["BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL"] } end def extract_buildkite(env) tags = { - Core::Git::Ext::TAG_BRANCH => env["BUILDKITE_BRANCH"], - Core::Git::Ext::TAG_COMMIT_SHA => env["BUILDKITE_COMMIT"], - Core::Git::Ext::TAG_REPOSITORY_URL => env["BUILDKITE_REPO"], - Core::Git::Ext::TAG_TAG => env["BUILDKITE_TAG"], + Git::TAG_BRANCH => env["BUILDKITE_BRANCH"], + Git::TAG_COMMIT_SHA => env["BUILDKITE_COMMIT"], + Git::TAG_REPOSITORY_URL => env["BUILDKITE_REPO"], + Git::TAG_TAG => env["BUILDKITE_TAG"], TAG_PIPELINE_ID => env["BUILDKITE_BUILD_ID"], TAG_PIPELINE_NAME => env["BUILDKITE_PIPELINE_SLUG"], TAG_PIPELINE_NUMBER => env["BUILDKITE_BUILD_NUMBER"], @@ -218,9 +218,9 @@ def extract_buildkite(env) TAG_JOB_URL => "#{env["BUILDKITE_BUILD_URL"]}##{env["BUILDKITE_JOB_ID"]}", TAG_PROVIDER_NAME => "buildkite", TAG_WORKSPACE_PATH => env["BUILDKITE_BUILD_CHECKOUT_PATH"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env["BUILDKITE_BUILD_AUTHOR"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env["BUILDKITE_BUILD_AUTHOR_EMAIL"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env["BUILDKITE_MESSAGE"], + Git::TAG_COMMIT_AUTHOR_NAME => env["BUILDKITE_BUILD_AUTHOR"], + Git::TAG_COMMIT_AUTHOR_EMAIL => env["BUILDKITE_BUILD_AUTHOR_EMAIL"], + Git::TAG_COMMIT_MESSAGE => env["BUILDKITE_MESSAGE"], TAG_NODE_NAME => env["BUILDKITE_AGENT_ID"], TAG_CI_ENV_VARS => { "BUILDKITE_BUILD_ID" => env["BUILDKITE_BUILD_ID"], @@ -240,10 +240,10 @@ def extract_buildkite(env) def extract_circle_ci(env) { - Core::Git::Ext::TAG_BRANCH => env["CIRCLE_BRANCH"], - Core::Git::Ext::TAG_COMMIT_SHA => env["CIRCLE_SHA1"], - Core::Git::Ext::TAG_REPOSITORY_URL => env["CIRCLE_REPOSITORY_URL"], - Core::Git::Ext::TAG_TAG => env["CIRCLE_TAG"], + Git::TAG_BRANCH => env["CIRCLE_BRANCH"], + Git::TAG_COMMIT_SHA => env["CIRCLE_SHA1"], + Git::TAG_REPOSITORY_URL => env["CIRCLE_REPOSITORY_URL"], + Git::TAG_TAG => env["CIRCLE_TAG"], TAG_PIPELINE_ID => env["CIRCLE_WORKFLOW_ID"], TAG_PIPELINE_NAME => env["CIRCLE_PROJECT_REPONAME"], TAG_PIPELINE_URL => "https://app.circleci.com/pipelines/workflows/#{env["CIRCLE_WORKFLOW_ID"]}", @@ -251,9 +251,9 @@ def extract_circle_ci(env) TAG_JOB_URL => env["CIRCLE_BUILD_URL"], TAG_PROVIDER_NAME => "circleci", TAG_WORKSPACE_PATH => env["CIRCLE_WORKING_DIRECTORY"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env["BUILD_REQUESTEDFORID"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env["BUILD_REQUESTEDFOREMAIL"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env["BUILD_SOURCEVERSIONMESSAGE"], + Git::TAG_COMMIT_AUTHOR_NAME => env["BUILD_REQUESTEDFORID"], + Git::TAG_COMMIT_AUTHOR_EMAIL => env["BUILD_REQUESTEDFOREMAIL"], + Git::TAG_COMMIT_MESSAGE => env["BUILD_SOURCEVERSIONMESSAGE"], TAG_CI_ENV_VARS => { "CIRCLE_WORKFLOW_ID" => env["CIRCLE_WORKFLOW_ID"], "CIRCLE_BUILD_NUM" => env["CIRCLE_BUILD_NUM"] @@ -270,10 +270,10 @@ def extract_github_actions(env) pipeline_url = "#{pipeline_url}/attempts/#{env["GITHUB_RUN_ATTEMPT"]}" if env["GITHUB_RUN_ATTEMPT"] { - Core::Git::Ext::TAG_BRANCH => branch, - Core::Git::Ext::TAG_COMMIT_SHA => env["GITHUB_SHA"], - Core::Git::Ext::TAG_REPOSITORY_URL => "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}.git", - Core::Git::Ext::TAG_TAG => tag, + Git::TAG_BRANCH => branch, + Git::TAG_COMMIT_SHA => env["GITHUB_SHA"], + Git::TAG_REPOSITORY_URL => "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}.git", + Git::TAG_TAG => tag, TAG_JOB_URL => "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks", TAG_JOB_NAME => env["GITHUB_JOB"], TAG_PIPELINE_ID => env["GITHUB_RUN_ID"], @@ -295,13 +295,13 @@ def extract_gitlab(env) commit_author_name, commit_author_email = extract_name_email(env["CI_COMMIT_AUTHOR"]) { - Core::Git::Ext::TAG_BRANCH => env["CI_COMMIT_REF_NAME"], - Core::Git::Ext::TAG_COMMIT_SHA => env["CI_COMMIT_SHA"], - Core::Git::Ext::TAG_REPOSITORY_URL => env["CI_REPOSITORY_URL"], - Core::Git::Ext::TAG_TAG => env["CI_COMMIT_TAG"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => commit_author_name, - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => commit_author_email, - Core::Git::Ext::TAG_COMMIT_AUTHOR_DATE => env["CI_COMMIT_TIMESTAMP"], + Git::TAG_BRANCH => env["CI_COMMIT_REF_NAME"], + Git::TAG_COMMIT_SHA => env["CI_COMMIT_SHA"], + Git::TAG_REPOSITORY_URL => env["CI_REPOSITORY_URL"], + Git::TAG_TAG => env["CI_COMMIT_TAG"], + Git::TAG_COMMIT_AUTHOR_NAME => commit_author_name, + Git::TAG_COMMIT_AUTHOR_EMAIL => commit_author_email, + Git::TAG_COMMIT_AUTHOR_DATE => env["CI_COMMIT_TIMESTAMP"], TAG_STAGE_NAME => env["CI_JOB_STAGE"], TAG_JOB_NAME => env["CI_JOB_NAME"], TAG_JOB_URL => env["CI_JOB_URL"], @@ -313,7 +313,7 @@ def extract_gitlab(env) TAG_WORKSPACE_PATH => env["CI_PROJECT_DIR"], TAG_NODE_LABELS => env["CI_RUNNER_TAGS"], TAG_NODE_NAME => env["CI_RUNNER_ID"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env["CI_COMMIT_MESSAGE"], + Git::TAG_COMMIT_MESSAGE => env["CI_COMMIT_MESSAGE"], TAG_CI_ENV_VARS => { "CI_PROJECT_URL" => env["CI_PROJECT_URL"], "CI_PIPELINE_ID" => env["CI_PIPELINE_ID"], @@ -333,10 +333,10 @@ def extract_jenkins(env) node_labels = env["NODE_LABELS"] && env["NODE_LABELS"].split.to_json { - Core::Git::Ext::TAG_BRANCH => branch, - Core::Git::Ext::TAG_COMMIT_SHA => env["GIT_COMMIT"], - Core::Git::Ext::TAG_REPOSITORY_URL => env["GIT_URL"] || env["GIT_URL_1"], - Core::Git::Ext::TAG_TAG => tag, + Git::TAG_BRANCH => branch, + Git::TAG_COMMIT_SHA => env["GIT_COMMIT"], + Git::TAG_REPOSITORY_URL => env["GIT_URL"] || env["GIT_URL_1"], + Git::TAG_TAG => tag, TAG_PIPELINE_ID => env["BUILD_TAG"], TAG_PIPELINE_NAME => name, TAG_PIPELINE_NUMBER => env["BUILD_NUMBER"], @@ -361,10 +361,10 @@ def extract_teamcity(env) def extract_travis(env) { - Core::Git::Ext::TAG_BRANCH => (env["TRAVIS_PULL_REQUEST_BRANCH"] || env["TRAVIS_BRANCH"]), - Core::Git::Ext::TAG_COMMIT_SHA => env["TRAVIS_COMMIT"], - Core::Git::Ext::TAG_REPOSITORY_URL => "https://github.com/#{env["TRAVIS_REPO_SLUG"]}.git", - Core::Git::Ext::TAG_TAG => env["TRAVIS_TAG"], + Git::TAG_BRANCH => (env["TRAVIS_PULL_REQUEST_BRANCH"] || env["TRAVIS_BRANCH"]), + Git::TAG_COMMIT_SHA => env["TRAVIS_COMMIT"], + Git::TAG_REPOSITORY_URL => "https://github.com/#{env["TRAVIS_REPO_SLUG"]}.git", + Git::TAG_TAG => env["TRAVIS_TAG"], TAG_JOB_URL => env["TRAVIS_JOB_WEB_URL"], TAG_PIPELINE_ID => env["TRAVIS_BUILD_ID"], TAG_PIPELINE_NAME => env["TRAVIS_REPO_SLUG"], @@ -372,7 +372,7 @@ def extract_travis(env) TAG_PIPELINE_URL => env["TRAVIS_BUILD_WEB_URL"], TAG_PROVIDER_NAME => "travisci", TAG_WORKSPACE_PATH => env["TRAVIS_BUILD_DIR"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env["TRAVIS_COMMIT_MESSAGE"] + Git::TAG_COMMIT_MESSAGE => env["TRAVIS_COMMIT_MESSAGE"] } end @@ -394,15 +394,15 @@ def extract_bitrise(env) TAG_PIPELINE_NUMBER => env["BITRISE_BUILD_NUMBER"], TAG_PIPELINE_URL => env["BITRISE_BUILD_URL"], TAG_WORKSPACE_PATH => env["BITRISE_SOURCE_DIR"], - Core::Git::Ext::TAG_REPOSITORY_URL => env["GIT_REPOSITORY_URL"], - Core::Git::Ext::TAG_COMMIT_SHA => commit, - Core::Git::Ext::TAG_BRANCH => branch, - Core::Git::Ext::TAG_TAG => env["BITRISE_GIT_TAG"], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env["BITRISE_GIT_MESSAGE"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env["GIT_CLONE_COMMIT_AUTHOR_NAME"], - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env["GIT_CLONE_COMMIT_AUTHOR_EMAIL"], - Core::Git::Ext::TAG_COMMIT_COMMITTER_NAME => env["GIT_CLONE_COMMIT_COMMITER_NAME"], - Core::Git::Ext::TAG_COMMIT_COMMITTER_EMAIL => commiter_email + Git::TAG_REPOSITORY_URL => env["GIT_REPOSITORY_URL"], + Git::TAG_COMMIT_SHA => commit, + Git::TAG_BRANCH => branch, + Git::TAG_TAG => env["BITRISE_GIT_TAG"], + Git::TAG_COMMIT_MESSAGE => env["BITRISE_GIT_MESSAGE"], + Git::TAG_COMMIT_AUTHOR_NAME => env["GIT_CLONE_COMMIT_AUTHOR_NAME"], + Git::TAG_COMMIT_AUTHOR_EMAIL => env["GIT_CLONE_COMMIT_AUTHOR_EMAIL"], + Git::TAG_COMMIT_COMMITTER_NAME => env["GIT_CLONE_COMMIT_COMMITER_NAME"], + Git::TAG_COMMIT_COMMITTER_EMAIL => commiter_email } end @@ -415,8 +415,8 @@ def extract_codefresh(env) TAG_PIPELINE_NAME => env["CF_PIPELINE_NAME"], TAG_PIPELINE_URL => env["CF_BUILD_URL"], TAG_JOB_NAME => env["CF_STEP_NAME"], - Core::Git::Ext::TAG_BRANCH => branch, - Core::Git::Ext::TAG_TAG => tag, + Git::TAG_BRANCH => branch, + Git::TAG_TAG => tag, TAG_CI_ENV_VARS => { "CF_BUILD_ID" => env["CF_BUILD_ID"] }.to_json @@ -425,17 +425,17 @@ def extract_codefresh(env) def extract_user_defined_git(env) { - Core::Git::Ext::TAG_REPOSITORY_URL => env[Core::Git::Ext::ENV_REPOSITORY_URL], - Core::Git::Ext::TAG_COMMIT_SHA => env[Core::Git::Ext::ENV_COMMIT_SHA], - Core::Git::Ext::TAG_BRANCH => env[Core::Git::Ext::ENV_BRANCH], - Core::Git::Ext::TAG_TAG => env[Core::Git::Ext::ENV_TAG], - Core::Git::Ext::TAG_COMMIT_MESSAGE => env[Core::Git::Ext::ENV_COMMIT_MESSAGE], - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env[Core::Git::Ext::ENV_COMMIT_AUTHOR_NAME], - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env[Core::Git::Ext::ENV_COMMIT_AUTHOR_EMAIL], - Core::Git::Ext::TAG_COMMIT_AUTHOR_DATE => env[Core::Git::Ext::ENV_COMMIT_AUTHOR_DATE], - Core::Git::Ext::TAG_COMMIT_COMMITTER_NAME => env[Core::Git::Ext::ENV_COMMIT_COMMITTER_NAME], - Core::Git::Ext::TAG_COMMIT_COMMITTER_EMAIL => env[Core::Git::Ext::ENV_COMMIT_COMMITTER_EMAIL], - Core::Git::Ext::TAG_COMMIT_COMMITTER_DATE => env[Core::Git::Ext::ENV_COMMIT_COMMITTER_DATE] + Git::TAG_REPOSITORY_URL => env[Git::ENV_REPOSITORY_URL], + Git::TAG_COMMIT_SHA => env[Git::ENV_COMMIT_SHA], + Git::TAG_BRANCH => env[Git::ENV_BRANCH], + Git::TAG_TAG => env[Git::ENV_TAG], + Git::TAG_COMMIT_MESSAGE => env[Git::ENV_COMMIT_MESSAGE], + Git::TAG_COMMIT_AUTHOR_NAME => env[Git::ENV_COMMIT_AUTHOR_NAME], + Git::TAG_COMMIT_AUTHOR_EMAIL => env[Git::ENV_COMMIT_AUTHOR_EMAIL], + Git::TAG_COMMIT_AUTHOR_DATE => env[Git::ENV_COMMIT_AUTHOR_DATE], + Git::TAG_COMMIT_COMMITTER_NAME => env[Git::ENV_COMMIT_COMMITTER_NAME], + Git::TAG_COMMIT_COMMITTER_EMAIL => env[Git::ENV_COMMIT_COMMITTER_EMAIL], + Git::TAG_COMMIT_COMMITTER_DATE => env[Git::ENV_COMMIT_COMMITTER_DATE] }.reject { |_, v| v.nil? || v.strip.empty? } end @@ -534,21 +534,21 @@ def exec_git_command(cmd) def extract_local_git env = { TAG_WORKSPACE_PATH => git_base_directory, - Core::Git::Ext::TAG_REPOSITORY_URL => git_repository_url, - Core::Git::Ext::TAG_COMMIT_SHA => git_commit_sha, - Core::Git::Ext::TAG_BRANCH => git_branch, - Core::Git::Ext::TAG_TAG => git_tag, - Core::Git::Ext::TAG_COMMIT_MESSAGE => git_commit_message + Git::TAG_REPOSITORY_URL => git_repository_url, + Git::TAG_COMMIT_SHA => git_commit_sha, + Git::TAG_BRANCH => git_branch, + Git::TAG_TAG => git_tag, + Git::TAG_COMMIT_MESSAGE => git_commit_message } if (commit_users = git_commit_users) env.merge!( - Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => commit_users[:author_name], - Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => commit_users[:author_email], - Core::Git::Ext::TAG_COMMIT_AUTHOR_DATE => commit_users[:author_date], - Core::Git::Ext::TAG_COMMIT_COMMITTER_NAME => commit_users[:committer_name], - Core::Git::Ext::TAG_COMMIT_COMMITTER_EMAIL => commit_users[:committer_email], - Core::Git::Ext::TAG_COMMIT_COMMITTER_DATE => commit_users[:committer_date] + Git::TAG_COMMIT_AUTHOR_NAME => commit_users[:author_name], + Git::TAG_COMMIT_AUTHOR_EMAIL => commit_users[:author_email], + Git::TAG_COMMIT_AUTHOR_DATE => commit_users[:author_date], + Git::TAG_COMMIT_COMMITTER_NAME => commit_users[:committer_name], + Git::TAG_COMMIT_COMMITTER_EMAIL => commit_users[:committer_email], + Git::TAG_COMMIT_COMMITTER_DATE => commit_users[:committer_date] ) end diff --git a/lib/datadog/ci/ext/git.rb b/lib/datadog/ci/ext/git.rb new file mode 100644 index 00000000..5bd87946 --- /dev/null +++ b/lib/datadog/ci/ext/git.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Datadog + module CI + module Ext + # Defines constants for Git tags + module Git + GIT_SHA_LENGTH = 40 + + TAG_BRANCH = "git.branch" + TAG_REPOSITORY_URL = "git.repository_url" + TAG_TAG = "git.tag" + + TAG_COMMIT_AUTHOR_DATE = "git.commit.author.date" + TAG_COMMIT_AUTHOR_EMAIL = "git.commit.author.email" + TAG_COMMIT_AUTHOR_NAME = "git.commit.author.name" + TAG_COMMIT_COMMITTER_DATE = "git.commit.committer.date" + TAG_COMMIT_COMMITTER_EMAIL = "git.commit.committer.email" + TAG_COMMIT_COMMITTER_NAME = "git.commit.committer.name" + TAG_COMMIT_MESSAGE = "git.commit.message" + TAG_COMMIT_SHA = "git.commit.sha" + + ENV_REPOSITORY_URL = "DD_GIT_REPOSITORY_URL" + ENV_COMMIT_SHA = "DD_GIT_COMMIT_SHA" + ENV_BRANCH = "DD_GIT_BRANCH" + ENV_TAG = "DD_GIT_TAG" + ENV_COMMIT_MESSAGE = "DD_GIT_COMMIT_MESSAGE" + ENV_COMMIT_AUTHOR_NAME = "DD_GIT_COMMIT_AUTHOR_NAME" + ENV_COMMIT_AUTHOR_EMAIL = "DD_GIT_COMMIT_AUTHOR_EMAIL" + ENV_COMMIT_AUTHOR_DATE = "DD_GIT_COMMIT_AUTHOR_DATE" + ENV_COMMIT_COMMITTER_NAME = "DD_GIT_COMMIT_COMMITTER_NAME" + ENV_COMMIT_COMMITTER_EMAIL = "DD_GIT_COMMIT_COMMITTER_EMAIL" + ENV_COMMIT_COMMITTER_DATE = "DD_GIT_COMMIT_COMMITTER_DATE" + end + end + end +end diff --git a/sig/datadog/ci/ext/git.rbs b/sig/datadog/ci/ext/git.rbs new file mode 100644 index 00000000..3424c185 --- /dev/null +++ b/sig/datadog/ci/ext/git.rbs @@ -0,0 +1,53 @@ +module Datadog + module CI + module Ext + module Git + GIT_SHA_LENGTH: 40 + + TAG_BRANCH: "git.branch" + + TAG_REPOSITORY_URL: "git.repository_url" + + TAG_TAG: "git.tag" + + TAG_COMMIT_AUTHOR_DATE: "git.commit.author.date" + + TAG_COMMIT_AUTHOR_EMAIL: "git.commit.author.email" + + TAG_COMMIT_AUTHOR_NAME: "git.commit.author.name" + + TAG_COMMIT_COMMITTER_DATE: "git.commit.committer.date" + + TAG_COMMIT_COMMITTER_EMAIL: "git.commit.committer.email" + + TAG_COMMIT_COMMITTER_NAME: "git.commit.committer.name" + + TAG_COMMIT_MESSAGE: "git.commit.message" + + TAG_COMMIT_SHA: "git.commit.sha" + + ENV_REPOSITORY_URL: "DD_GIT_REPOSITORY_URL" + + ENV_COMMIT_SHA: "DD_GIT_COMMIT_SHA" + + ENV_BRANCH: "DD_GIT_BRANCH" + + ENV_TAG: "DD_GIT_TAG" + + ENV_COMMIT_MESSAGE: "DD_GIT_COMMIT_MESSAGE" + + ENV_COMMIT_AUTHOR_NAME: "DD_GIT_COMMIT_AUTHOR_NAME" + + ENV_COMMIT_AUTHOR_EMAIL: "DD_GIT_COMMIT_AUTHOR_EMAIL" + + ENV_COMMIT_AUTHOR_DATE: "DD_GIT_COMMIT_AUTHOR_DATE" + + ENV_COMMIT_COMMITTER_NAME: "DD_GIT_COMMIT_COMMITTER_NAME" + + ENV_COMMIT_COMMITTER_EMAIL: "DD_GIT_COMMIT_COMMITTER_EMAIL" + + ENV_COMMIT_COMMITTER_DATE: "DD_GIT_COMMIT_COMMITTER_DATE" + end + end + end +end From b5c77ba8f05880b71fdf8889ff055743dc165ba9 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 14:13:08 +0200 Subject: [PATCH 02/31] start environment refactoring with appveyor provider --- lib/datadog/ci/ext/environment.rb | 41 +------ lib/datadog/ci/ext/providers.rb | 21 ++++ lib/datadog/ci/ext/providers/appveyor.rb | 95 ++++++++++++++ lib/datadog/ci/ext/providers/default.rb | 18 +++ lib/datadog/ci/ext/providers/extractor.rb | 136 +++++++++++++++++++++ sig/datadog/ci/ext/providers.rbs | 31 +++++ sig/datadog/ci/ext/providers/appveyor.rbs | 45 +++++++ sig/datadog/ci/ext/providers/default.rbs | 11 ++ sig/datadog/ci/ext/providers/extractor.rbs | 67 ++++++++++ 9 files changed, 426 insertions(+), 39 deletions(-) create mode 100644 lib/datadog/ci/ext/providers.rb create mode 100644 lib/datadog/ci/ext/providers/appveyor.rb create mode 100644 lib/datadog/ci/ext/providers/default.rb create mode 100644 lib/datadog/ci/ext/providers/extractor.rb create mode 100644 sig/datadog/ci/ext/providers.rbs create mode 100644 sig/datadog/ci/ext/providers/appveyor.rbs create mode 100644 sig/datadog/ci/ext/providers/default.rbs create mode 100644 sig/datadog/ci/ext/providers/extractor.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index a26c5865..b677c428 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -4,6 +4,7 @@ require "json" require_relative "git" +require_relative "providers/extractor" module Datadog module CI @@ -22,11 +23,8 @@ module Environment TAG_NODE_LABELS = "ci.node.labels" TAG_NODE_NAME = "ci.node.name" TAG_CI_ENV_VARS = "_dd.ci.env_vars" - TAG_NODE_LABELS = "ci.node.labels" - TAG_NODE_NAME = "ci.node.name" PROVIDERS = [ - ["APPVEYOR", :extract_appveyor], ["TF_BUILD", :extract_azure_pipelines], ["BITBUCKET_COMMIT", :extract_bitbucket], ["BUDDY", :extract_buddy], @@ -46,7 +44,7 @@ module Environment def tags(env) # Extract metadata from CI provider environment variables _, extractor = PROVIDERS.find { |provider_env_var, _| env.key?(provider_env_var) } - tags = extractor ? public_send(extractor, env).reject { |_, v| v.nil? || v.strip.empty? } : {} + tags = extractor ? public_send(extractor, env).reject { |_, v| v.nil? || v.strip.empty? } : Providers::Extractor.for_environment(env).tags # If user defined metadata is defined, overwrite tags.merge!(extract_user_defined_git(env)) @@ -88,41 +86,6 @@ def filter_sensitive_info(url) end # CI providers - - def extract_appveyor(env) - url = "https://ci.appveyor.com/project/#{env["APPVEYOR_REPO_NAME"]}/builds/#{env["APPVEYOR_BUILD_ID"]}" - - if env["APPVEYOR_REPO_PROVIDER"] == "github" - repository = "https://github.com/#{env["APPVEYOR_REPO_NAME"]}.git" - commit = env["APPVEYOR_REPO_COMMIT"] - branch = (env["APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH"] || env["APPVEYOR_REPO_BRANCH"]) - tag = env["APPVEYOR_REPO_TAG_NAME"] - end - - commit_message = env["APPVEYOR_REPO_COMMIT_MESSAGE"] - if commit_message - extended = env["APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED"] - commit_message = "#{commit_message}\n#{extended}" if extended - end - - { - TAG_PROVIDER_NAME => "appveyor", - Git::TAG_REPOSITORY_URL => repository, - Git::TAG_COMMIT_SHA => commit, - TAG_WORKSPACE_PATH => env["APPVEYOR_BUILD_FOLDER"], - TAG_PIPELINE_ID => env["APPVEYOR_BUILD_ID"], - TAG_PIPELINE_NAME => env["APPVEYOR_REPO_NAME"], - TAG_PIPELINE_NUMBER => env["APPVEYOR_BUILD_NUMBER"], - TAG_PIPELINE_URL => url, - TAG_JOB_URL => url, - Git::TAG_BRANCH => branch, - Git::TAG_TAG => tag, - Git::TAG_COMMIT_AUTHOR_NAME => env["APPVEYOR_REPO_COMMIT_AUTHOR"], - Git::TAG_COMMIT_AUTHOR_EMAIL => env["APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL"], - Git::TAG_COMMIT_MESSAGE => commit_message - } - end - def extract_azure_pipelines(env) build_id = env["BUILD_BUILDID"] diff --git a/lib/datadog/ci/ext/providers.rb b/lib/datadog/ci/ext/providers.rb new file mode 100644 index 00000000..7522ac76 --- /dev/null +++ b/lib/datadog/ci/ext/providers.rb @@ -0,0 +1,21 @@ +module Datadog + module CI + module Ext + # Provider is a specific CI provider like Azure Pipelines, Github Actions, Gitlab CI, etc + module Providers + TAG_JOB_NAME = "ci.job.name" + TAG_JOB_URL = "ci.job.url" + TAG_PIPELINE_ID = "ci.pipeline.id" + TAG_PIPELINE_NAME = "ci.pipeline.name" + TAG_PIPELINE_NUMBER = "ci.pipeline.number" + TAG_PIPELINE_URL = "ci.pipeline.url" + TAG_PROVIDER_NAME = "ci.provider.name" + TAG_STAGE_NAME = "ci.stage.name" + TAG_WORKSPACE_PATH = "ci.workspace_path" + TAG_NODE_LABELS = "ci.node.labels" + TAG_NODE_NAME = "ci.node.name" + TAG_CI_ENV_VARS = "_dd.ci.env_vars" + end + end + end +end diff --git a/lib/datadog/ci/ext/providers/appveyor.rb b/lib/datadog/ci/ext/providers/appveyor.rb new file mode 100644 index 00000000..54b17499 --- /dev/null +++ b/lib/datadog/ci/ext/providers/appveyor.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require_relative "extractor" + +module Datadog + module CI + module Ext + module Providers + # TODO + class Appveyor < Extractor + private + + def provider_name + "appveyor" + end + + def pipeline_url + url + end + + def job_url + url + end + + def workspace_path + env["APPVEYOR_BUILD_FOLDER"] + end + + def pipeline_id + env["APPVEYOR_BUILD_ID"] + end + + def pipeline_name + env["APPVEYOR_REPO_NAME"] + end + + def pipeline_number + env["APPVEYOR_BUILD_NUMBER"] + end + + def git_repository_url + return nil unless github_repo_provider? + + "https://github.com/#{env["APPVEYOR_REPO_NAME"]}.git" + end + + def git_commit_sha + return nil unless github_repo_provider? + + env["APPVEYOR_REPO_COMMIT"] + end + + def git_branch + return nil unless github_repo_provider? + + env["APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH"] || env["APPVEYOR_REPO_BRANCH"] + end + + def git_tag + return nil unless github_repo_provider? + + env["APPVEYOR_REPO_TAG_NAME"] + end + + def git_commit_author_name + env["APPVEYOR_REPO_COMMIT_AUTHOR"] + end + + def git_commit_author_email + env["APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL"] + end + + def git_commit_message + commit_message = env["APPVEYOR_REPO_COMMIT_MESSAGE"] + if commit_message + extended = env["APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED"] + commit_message = "#{commit_message}\n#{extended}" if extended + end + commit_message + end + + def github_repo_provider? + return @github_repo_provider if defined?(@github_repo_provider) + + @github_repo_provider = env["APPVEYOR_REPO_PROVIDER"] == "github" + end + + def url + "https://ci.appveyor.com/project/#{env["APPVEYOR_REPO_NAME"]}/builds/#{env["APPVEYOR_BUILD_ID"]}" + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/providers/default.rb b/lib/datadog/ci/ext/providers/default.rb new file mode 100644 index 00000000..da9b81aa --- /dev/null +++ b/lib/datadog/ci/ext/providers/default.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require_relative "extractor" + +module Datadog + module CI + module Ext + module Providers + # TODO + class Default < Extractor + def tags + {} + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/providers/extractor.rb b/lib/datadog/ci/ext/providers/extractor.rb new file mode 100644 index 00000000..07fc44b9 --- /dev/null +++ b/lib/datadog/ci/ext/providers/extractor.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +require_relative "../providers" +require_relative "../git" + +module Datadog + module CI + module Ext + module Providers + # Providers::Extractor is responsible for detecting where pipeline is being executed based on environment vars + # and return the specific extractor that is able to return environment- and git-specific tags + class Extractor + require_relative "default" + require_relative "appveyor" + + EXTRACTORS = [ + ["APPVEYOR", Appveyor] + ] + + def self.for_environment(env) + _, extractor_klass = EXTRACTORS.find { |provider_env_var, _| env.key?(provider_env_var) } + extractor_klass = Default if extractor_klass.nil? + + extractor_klass.new(env) + end + + def initialize(env) + @env = env + end + + def tags + { + Providers::TAG_JOB_NAME => job_name, + Providers::TAG_JOB_URL => job_url, + Providers::TAG_PIPELINE_ID => pipeline_id, + Providers::TAG_PIPELINE_NAME => pipeline_name, + Providers::TAG_PIPELINE_NUMBER => pipeline_number, + Providers::TAG_PIPELINE_URL => pipeline_url, + Providers::TAG_PROVIDER_NAME => provider_name, + Providers::TAG_STAGE_NAME => stage_name, + Providers::TAG_WORKSPACE_PATH => workspace_path, + Providers::TAG_NODE_LABELS => node_labels, + Providers::TAG_NODE_NAME => node_name, + Providers::TAG_CI_ENV_VARS => ci_env_vars, + + Git::TAG_BRANCH => git_branch, + Git::TAG_REPOSITORY_URL => git_repository_url, + Git::TAG_TAG => git_tag, + Git::TAG_COMMIT_AUTHOR_DATE => git_commit_author_date, + Git::TAG_COMMIT_AUTHOR_EMAIL => git_commit_author_email, + Git::TAG_COMMIT_AUTHOR_NAME => git_commit_author_name, + Git::TAG_COMMIT_COMMITTER_DATE => git_commit_committer_date, + Git::TAG_COMMIT_COMMITTER_EMAIL => git_commit_committer_email, + Git::TAG_COMMIT_COMMITTER_NAME => git_commit_committer_name, + Git::TAG_COMMIT_MESSAGE => git_commit_message, + Git::TAG_COMMIT_SHA => git_commit_sha + }.reject { |_, v| v.nil? } + end + + private + + attr_reader :env + + def job_name + end + + def job_url + end + + def pipeline_id + end + + def pipeline_name + end + + def pipeline_number + end + + def pipeline_url + end + + def provider_name + end + + def stage_name + end + + def workspace_path + end + + def node_labels + end + + def node_name + end + + def ci_env_vars + end + + def git_branch + end + + def git_repository_url + end + + def git_tag + end + + def git_commit_author_date + end + + def git_commit_author_email + end + + def git_commit_author_name + end + + def git_commit_committer_date + end + + def git_commit_committer_email + end + + def git_commit_committer_name + end + + def git_commit_message + end + + def git_commit_sha + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/providers.rbs b/sig/datadog/ci/ext/providers.rbs new file mode 100644 index 00000000..44f813a2 --- /dev/null +++ b/sig/datadog/ci/ext/providers.rbs @@ -0,0 +1,31 @@ +module Datadog + module CI + module Ext + module Providers + TAG_JOB_NAME: "ci.job.name" + + TAG_JOB_URL: "ci.job.url" + + TAG_PIPELINE_ID: "ci.pipeline.id" + + TAG_PIPELINE_NAME: "ci.pipeline.name" + + TAG_PIPELINE_NUMBER: "ci.pipeline.number" + + TAG_PIPELINE_URL: "ci.pipeline.url" + + TAG_PROVIDER_NAME: "ci.provider.name" + + TAG_STAGE_NAME: "ci.stage.name" + + TAG_WORKSPACE_PATH: "ci.workspace_path" + + TAG_NODE_LABELS: "ci.node.labels" + + TAG_NODE_NAME: "ci.node.name" + + TAG_CI_ENV_VARS: "_dd.ci.env_vars" + end + end + end +end diff --git a/sig/datadog/ci/ext/providers/appveyor.rbs b/sig/datadog/ci/ext/providers/appveyor.rbs new file mode 100644 index 00000000..f3083bb2 --- /dev/null +++ b/sig/datadog/ci/ext/providers/appveyor.rbs @@ -0,0 +1,45 @@ +module Datadog + module CI + module Ext + module Providers + class Appveyor < Extractor + private + + @github_repo_provider: bool + + def provider_name: () -> "appveyor" + + def pipeline_url: () -> String? + + def job_url: () -> String? + + def workspace_path: () -> String? + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_message: () -> String? + + def github_repo_provider?: () -> bool + + def url: () -> String? + end + end + end + end +end diff --git a/sig/datadog/ci/ext/providers/default.rbs b/sig/datadog/ci/ext/providers/default.rbs new file mode 100644 index 00000000..ce93a465 --- /dev/null +++ b/sig/datadog/ci/ext/providers/default.rbs @@ -0,0 +1,11 @@ +module Datadog + module CI + module Ext + module Providers + class Default < Extractor + def tags: () -> ::Hash[String, untyped] + end + end + end + end +end diff --git a/sig/datadog/ci/ext/providers/extractor.rbs b/sig/datadog/ci/ext/providers/extractor.rbs new file mode 100644 index 00000000..24f65cdd --- /dev/null +++ b/sig/datadog/ci/ext/providers/extractor.rbs @@ -0,0 +1,67 @@ +module Datadog + module CI + module Ext + module Providers + class Extractor + EXTRACTORS: ::Array[::Array["APPVEYOR" | untyped]] + + def self.for_environment: (untyped env) -> Extractor + + def initialize: (Hash[String, String] env) -> void + + def tags: () -> Hash[String, untyped] + + private + + attr_reader env: untyped + + def job_name: () -> nil + + def job_url: () -> nil + + def pipeline_id: () -> nil + + def pipeline_name: () -> nil + + def pipeline_number: () -> nil + + def pipeline_url: () -> nil + + def provider_name: () -> nil + + def stage_name: () -> nil + + def workspace_path: () -> nil + + def node_labels: () -> nil + + def node_name: () -> nil + + def ci_env_vars: () -> nil + + def git_branch: () -> nil + + def git_repository_url: () -> nil + + def git_tag: () -> nil + + def git_commit_author_date: () -> nil + + def git_commit_author_email: () -> nil + + def git_commit_author_name: () -> nil + + def git_commit_committer_date: () -> nil + + def git_commit_committer_email: () -> nil + + def git_commit_committer_name: () -> nil + + def git_commit_message: () -> nil + + def git_commit_sha: () -> nil + end + end + end + end +end From 895ee04ed5515ea16ff8543e3fb4fd6f51f3d4f9 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 15:54:49 +0200 Subject: [PATCH 03/31] extract Azure environment extractor to its own class --- lib/datadog/ci/ext/environment.rb | 42 ------- lib/datadog/ci/ext/providers.rb | 21 ---- lib/datadog/ci/ext/providers/appveyor.rb | 8 +- lib/datadog/ci/ext/providers/azure.rb | 124 +++++++++++++++++++++ lib/datadog/ci/ext/providers/extractor.rb | 42 ++++--- sig/datadog/ci/ext/providers/appveyor.rbs | 1 + sig/datadog/ci/ext/providers/azure.rbs | 58 ++++++++++ sig/datadog/ci/ext/providers/extractor.rbs | 7 +- 8 files changed, 223 insertions(+), 80 deletions(-) delete mode 100644 lib/datadog/ci/ext/providers.rb create mode 100644 lib/datadog/ci/ext/providers/azure.rb create mode 100644 sig/datadog/ci/ext/providers/azure.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index b677c428..cf3401d9 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["TF_BUILD", :extract_azure_pipelines], ["BITBUCKET_COMMIT", :extract_bitbucket], ["BUDDY", :extract_buddy], ["BUILDKITE", :extract_buildkite], @@ -86,47 +85,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_azure_pipelines(env) - build_id = env["BUILD_BUILDID"] - - if build_id && - (team_foundation_server_uri = env["SYSTEM_TEAMFOUNDATIONSERVERURI"]) && - (team_project_id = env["SYSTEM_TEAMPROJECTID"]) - pipeline_url = "#{team_foundation_server_uri}#{team_project_id}/_build/results?buildId=#{build_id}" - job_url = "#{pipeline_url}&view=logs&j=#{env["SYSTEM_JOBID"]}&t=#{env["SYSTEM_TASKINSTANCEID"]}" - end - - branch, tag = branch_or_tag( - env["SYSTEM_PULLREQUEST_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCHNAME"] - ) - - { - TAG_PROVIDER_NAME => "azurepipelines", - TAG_WORKSPACE_PATH => env["BUILD_SOURCESDIRECTORY"], - TAG_PIPELINE_ID => build_id, - TAG_PIPELINE_NAME => env["BUILD_DEFINITIONNAME"], - TAG_PIPELINE_NUMBER => build_id, - TAG_PIPELINE_URL => pipeline_url, - TAG_JOB_URL => job_url, - TAG_STAGE_NAME => env["SYSTEM_STAGEDISPLAYNAME"], - TAG_JOB_NAME => env["SYSTEM_JOBDISPLAYNAME"], - Git::TAG_REPOSITORY_URL => - env["SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI"] || env["BUILD_REPOSITORY_URI"], - Git::TAG_COMMIT_SHA => env["SYSTEM_PULLREQUEST_SOURCECOMMITID"] \ - || env["BUILD_SOURCEVERSION"], - Git::TAG_BRANCH => branch, - Git::TAG_TAG => tag, - Git::TAG_COMMIT_AUTHOR_NAME => env["BUILD_REQUESTEDFORID"], - Git::TAG_COMMIT_AUTHOR_EMAIL => env["BUILD_REQUESTEDFOREMAIL"], - Git::TAG_COMMIT_MESSAGE => env["BUILD_SOURCEVERSIONMESSAGE"], - TAG_CI_ENV_VARS => { - "SYSTEM_TEAMPROJECTID" => env["SYSTEM_TEAMPROJECTID"], - "BUILD_BUILDID" => env["BUILD_BUILDID"], - "SYSTEM_JOBID" => env["SYSTEM_JOBID"] - }.to_json - } - end - def extract_bitbucket(env) pipeline_url = "https://bitbucket.org/#{env["BITBUCKET_REPO_FULL_NAME"]}/addon/pipelines/home#" \ "!/results/#{env["BITBUCKET_BUILD_NUMBER"]}" diff --git a/lib/datadog/ci/ext/providers.rb b/lib/datadog/ci/ext/providers.rb deleted file mode 100644 index 7522ac76..00000000 --- a/lib/datadog/ci/ext/providers.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Datadog - module CI - module Ext - # Provider is a specific CI provider like Azure Pipelines, Github Actions, Gitlab CI, etc - module Providers - TAG_JOB_NAME = "ci.job.name" - TAG_JOB_URL = "ci.job.url" - TAG_PIPELINE_ID = "ci.pipeline.id" - TAG_PIPELINE_NAME = "ci.pipeline.name" - TAG_PIPELINE_NUMBER = "ci.pipeline.number" - TAG_PIPELINE_URL = "ci.pipeline.url" - TAG_PROVIDER_NAME = "ci.provider.name" - TAG_STAGE_NAME = "ci.stage.name" - TAG_WORKSPACE_PATH = "ci.workspace_path" - TAG_NODE_LABELS = "ci.node.labels" - TAG_NODE_NAME = "ci.node.name" - TAG_CI_ENV_VARS = "_dd.ci.env_vars" - end - end - end -end diff --git a/lib/datadog/ci/ext/providers/appveyor.rb b/lib/datadog/ci/ext/providers/appveyor.rb index 54b17499..16a1487f 100644 --- a/lib/datadog/ci/ext/providers/appveyor.rb +++ b/lib/datadog/ci/ext/providers/appveyor.rb @@ -6,10 +6,12 @@ module Datadog module CI module Ext module Providers - # TODO + # Appveyor: https://www.appveyor.com/ + # Environment variables docs: https://www.appveyor.com/docs/environment-variables/ class Appveyor < Extractor private + # overridden methods def provider_name "appveyor" end @@ -79,6 +81,8 @@ def git_commit_message commit_message end + # appveyor-specific logic + def github_repo_provider? return @github_repo_provider if defined?(@github_repo_provider) @@ -86,7 +90,7 @@ def github_repo_provider? end def url - "https://ci.appveyor.com/project/#{env["APPVEYOR_REPO_NAME"]}/builds/#{env["APPVEYOR_BUILD_ID"]}" + @url ||= "https://ci.appveyor.com/project/#{env["APPVEYOR_REPO_NAME"]}/builds/#{env["APPVEYOR_BUILD_ID"]}" end end end diff --git a/lib/datadog/ci/ext/providers/azure.rb b/lib/datadog/ci/ext/providers/azure.rb new file mode 100644 index 00000000..f990b06a --- /dev/null +++ b/lib/datadog/ci/ext/providers/azure.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +require_relative "extractor" + +module Datadog + module CI + module Ext + module Providers + # Azure Pipelines: https://azure.microsoft.com/en-us/products/devops/pipelines + # Environment variables docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml + class Azure < Extractor + private + + # overridden methods + def provider_name + "azurepipelines" + end + + def pipeline_url + return unless url_defined? + + @pipeline_url ||= "#{team_foundation_server_uri}#{team_project_id}/_build/results?buildId=#{build_id}" + end + + def job_url + return unless url_defined? + + @job_url ||= "#{pipeline_url}&view=logs&j=#{env["SYSTEM_JOBID"]}&t=#{env["SYSTEM_TASKINSTANCEID"]}" + end + + def workspace_path + env["BUILD_SOURCESDIRECTORY"] + end + + def pipeline_id + build_id + end + + def pipeline_number + build_id + end + + def pipeline_name + env["BUILD_DEFINITIONNAME"] + end + + def stage_name + env["SYSTEM_STAGEDISPLAYNAME"] + end + + def job_name + env["SYSTEM_JOBDISPLAYNAME"] + end + + def git_repository_url + env["SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI"] || env["BUILD_REPOSITORY_URI"] + end + + def git_commit_sha + env["SYSTEM_PULLREQUEST_SOURCECOMMITID"] || env["BUILD_SOURCEVERSION"] + end + + def git_branch + return @branch if defined?(@branch) + + set_branch_and_tag + @branch + end + + def git_tag + return @tag if defined?(@tag) + + set_branch_and_tag + @tag + end + + def git_commit_author_name + env["BUILD_REQUESTEDFORID"] + end + + def git_commit_author_email + env["BUILD_REQUESTEDFOREMAIL"] + end + + def git_commit_message + env["BUILD_SOURCEVERSIONMESSAGE"] + end + + def ci_env_vars + { + "SYSTEM_TEAMPROJECTID" => env["SYSTEM_TEAMPROJECTID"], + "BUILD_BUILDID" => env["BUILD_BUILDID"], + "SYSTEM_JOBID" => env["SYSTEM_JOBID"] + }.to_json + end + + # azure-specific logic + + def build_id + env["BUILD_BUILDID"] + end + + def team_foundation_server_uri + env["SYSTEM_TEAMFOUNDATIONSERVERURI"] + end + + def team_project_id + env["SYSTEM_TEAMPROJECTID"] + end + + def url_defined? + !(build_id && team_foundation_server_uri && team_project_id).nil? + end + + def set_branch_and_tag + @branch, @tag = branch_or_tag( + env["SYSTEM_PULLREQUEST_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCHNAME"] + ) + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/providers/extractor.rb b/lib/datadog/ci/ext/providers/extractor.rb index 07fc44b9..3faacdf7 100644 --- a/lib/datadog/ci/ext/providers/extractor.rb +++ b/lib/datadog/ci/ext/providers/extractor.rb @@ -1,20 +1,23 @@ # frozen_string_literal: true -require_relative "../providers" +require_relative "../environment" require_relative "../git" module Datadog module CI module Ext module Providers + # Provider is a specific CI provider like Azure Pipelines, Github Actions, Gitlab CI, etc # Providers::Extractor is responsible for detecting where pipeline is being executed based on environment vars # and return the specific extractor that is able to return environment- and git-specific tags class Extractor require_relative "default" require_relative "appveyor" + require_relative "azure" EXTRACTORS = [ - ["APPVEYOR", Appveyor] + ["APPVEYOR", Appveyor], + ["TF_BUILD", Azure] ] def self.for_environment(env) @@ -30,18 +33,18 @@ def initialize(env) def tags { - Providers::TAG_JOB_NAME => job_name, - Providers::TAG_JOB_URL => job_url, - Providers::TAG_PIPELINE_ID => pipeline_id, - Providers::TAG_PIPELINE_NAME => pipeline_name, - Providers::TAG_PIPELINE_NUMBER => pipeline_number, - Providers::TAG_PIPELINE_URL => pipeline_url, - Providers::TAG_PROVIDER_NAME => provider_name, - Providers::TAG_STAGE_NAME => stage_name, - Providers::TAG_WORKSPACE_PATH => workspace_path, - Providers::TAG_NODE_LABELS => node_labels, - Providers::TAG_NODE_NAME => node_name, - Providers::TAG_CI_ENV_VARS => ci_env_vars, + Environment::TAG_JOB_NAME => job_name, + Environment::TAG_JOB_URL => job_url, + Environment::TAG_PIPELINE_ID => pipeline_id, + Environment::TAG_PIPELINE_NAME => pipeline_name, + Environment::TAG_PIPELINE_NUMBER => pipeline_number, + Environment::TAG_PIPELINE_URL => pipeline_url, + Environment::TAG_PROVIDER_NAME => provider_name, + Environment::TAG_STAGE_NAME => stage_name, + Environment::TAG_WORKSPACE_PATH => workspace_path, + Environment::TAG_NODE_LABELS => node_labels, + Environment::TAG_NODE_NAME => node_name, + Environment::TAG_CI_ENV_VARS => ci_env_vars, Git::TAG_BRANCH => git_branch, Git::TAG_REPOSITORY_URL => git_repository_url, @@ -129,6 +132,17 @@ def git_commit_message def git_commit_sha end + + def branch_or_tag(branch_or_tag_string) + @branch = @tag = nil + if branch_or_tag_string && branch_or_tag_string.include?("tags/") + @tag = branch_or_tag_string + else + @branch = branch_or_tag_string + end + + [@branch, @tag] + end end end end diff --git a/sig/datadog/ci/ext/providers/appveyor.rbs b/sig/datadog/ci/ext/providers/appveyor.rbs index f3083bb2..e9f063bb 100644 --- a/sig/datadog/ci/ext/providers/appveyor.rbs +++ b/sig/datadog/ci/ext/providers/appveyor.rbs @@ -6,6 +6,7 @@ module Datadog private @github_repo_provider: bool + @url: String def provider_name: () -> "appveyor" diff --git a/sig/datadog/ci/ext/providers/azure.rbs b/sig/datadog/ci/ext/providers/azure.rbs new file mode 100644 index 00000000..d4ffbc6d --- /dev/null +++ b/sig/datadog/ci/ext/providers/azure.rbs @@ -0,0 +1,58 @@ +module Datadog + module CI + module Ext + module Providers + class Azure < Extractor + private + + @pipeline_url: String + @job_url: String + + def provider_name: () -> "azurepipelines" + + def pipeline_url: () -> String? + + def job_url: () -> String? + + def workspace_path: () -> String? + + def pipeline_id: () -> String? + + def pipeline_number: () -> String? + + def pipeline_name: () -> String? + + def stage_name: () -> String? + + def job_name: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_message: () -> String? + + def ci_env_vars: () -> String? + + def build_id: () -> String? + + def team_foundation_server_uri: () -> String? + + def team_project_id: () -> String? + + def url_defined?: () -> bool + + def set_branch_and_tag: () -> [String?, String?] + end + end + end + end +end diff --git a/sig/datadog/ci/ext/providers/extractor.rbs b/sig/datadog/ci/ext/providers/extractor.rbs index 24f65cdd..d8cac7e3 100644 --- a/sig/datadog/ci/ext/providers/extractor.rbs +++ b/sig/datadog/ci/ext/providers/extractor.rbs @@ -3,7 +3,10 @@ module Datadog module Ext module Providers class Extractor - EXTRACTORS: ::Array[::Array["APPVEYOR" | untyped]] + + EXTRACTORS: ::Array[::Array[String | untyped]] + @branch: String? + @tag: String? def self.for_environment: (untyped env) -> Extractor @@ -60,6 +63,8 @@ module Datadog def git_commit_message: () -> nil def git_commit_sha: () -> nil + + def branch_or_tag: (String? branch_or_tag_string) -> [String?, String?] end end end From 1f702940c797d80eef59767ad508e3144eb86eeb Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 16:25:57 +0200 Subject: [PATCH 04/31] extract bitbucket extractor to its own class --- lib/datadog/ci/ext/environment.rb | 24 -------- lib/datadog/ci/ext/providers/appveyor.rb | 2 +- lib/datadog/ci/ext/providers/azure.rb | 2 +- lib/datadog/ci/ext/providers/bitbucket.rb | 70 ++++++++++++++++++++++ lib/datadog/ci/ext/providers/extractor.rb | 6 +- sig/datadog/ci/ext/providers.rbs | 31 ---------- sig/datadog/ci/ext/providers/bitbucket.rbs | 34 +++++++++++ 7 files changed, 111 insertions(+), 58 deletions(-) create mode 100644 lib/datadog/ci/ext/providers/bitbucket.rb delete mode 100644 sig/datadog/ci/ext/providers.rbs create mode 100644 sig/datadog/ci/ext/providers/bitbucket.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index cf3401d9..8b650f05 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["BITBUCKET_COMMIT", :extract_bitbucket], ["BUDDY", :extract_buddy], ["BUILDKITE", :extract_buildkite], ["CIRCLECI", :extract_circle_ci], @@ -85,29 +84,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_bitbucket(env) - pipeline_url = "https://bitbucket.org/#{env["BITBUCKET_REPO_FULL_NAME"]}/addon/pipelines/home#" \ - "!/results/#{env["BITBUCKET_BUILD_NUMBER"]}" - - repository_url = filter_sensitive_info( - env["BITBUCKET_GIT_SSH_ORIGIN"] || env["BITBUCKET_GIT_HTTP_ORIGIN"] - ) - - { - Git::TAG_BRANCH => env["BITBUCKET_BRANCH"], - Git::TAG_COMMIT_SHA => env["BITBUCKET_COMMIT"], - Git::TAG_REPOSITORY_URL => repository_url, - Git::TAG_TAG => env["BITBUCKET_TAG"], - TAG_JOB_URL => pipeline_url, - TAG_PIPELINE_ID => env["BITBUCKET_PIPELINE_UUID"] ? env["BITBUCKET_PIPELINE_UUID"].tr("{}", "") : nil, - TAG_PIPELINE_NAME => env["BITBUCKET_REPO_FULL_NAME"], - TAG_PIPELINE_NUMBER => env["BITBUCKET_BUILD_NUMBER"], - TAG_PIPELINE_URL => pipeline_url, - TAG_PROVIDER_NAME => "bitbucket", - TAG_WORKSPACE_PATH => env["BITBUCKET_CLONE_DIR"] - } - end - def extract_buddy(env) { TAG_PROVIDER_NAME => "buddy", diff --git a/lib/datadog/ci/ext/providers/appveyor.rb b/lib/datadog/ci/ext/providers/appveyor.rb index 16a1487f..1d3af293 100644 --- a/lib/datadog/ci/ext/providers/appveyor.rb +++ b/lib/datadog/ci/ext/providers/appveyor.rb @@ -81,7 +81,7 @@ def git_commit_message commit_message end - # appveyor-specific logic + # appveyor-specific methods def github_repo_provider? return @github_repo_provider if defined?(@github_repo_provider) diff --git a/lib/datadog/ci/ext/providers/azure.rb b/lib/datadog/ci/ext/providers/azure.rb index f990b06a..796278eb 100644 --- a/lib/datadog/ci/ext/providers/azure.rb +++ b/lib/datadog/ci/ext/providers/azure.rb @@ -94,7 +94,7 @@ def ci_env_vars }.to_json end - # azure-specific logic + # azure-specific methods def build_id env["BUILD_BUILDID"] diff --git a/lib/datadog/ci/ext/providers/bitbucket.rb b/lib/datadog/ci/ext/providers/bitbucket.rb new file mode 100644 index 00000000..57b04897 --- /dev/null +++ b/lib/datadog/ci/ext/providers/bitbucket.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require_relative "extractor" + +module Datadog + module CI + module Ext + module Providers + # Bitbucket Pipelines: https://bitbucket.org/product/features/pipelines + # Environment variables docs: https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ + class Bitbucket < Extractor + private + + # overridden methods + def provider_name + "bitbucket" + end + + def pipeline_id + env["BITBUCKET_PIPELINE_UUID"] ? env["BITBUCKET_PIPELINE_UUID"].tr("{}", "") : nil + end + + def pipeline_name + env["BITBUCKET_REPO_FULL_NAME"] + end + + def pipeline_number + env["BITBUCKET_BUILD_NUMBER"] + end + + def pipeline_url + url + end + + def job_url + url + end + + def workspace_path + env["BITBUCKET_CLONE_DIR"] + end + + def git_repository_url + env["BITBUCKET_GIT_SSH_ORIGIN"] || env["BITBUCKET_GIT_HTTP_ORIGIN"] + end + + def git_commit_sha + env["BITBUCKET_COMMIT"] + end + + def git_branch + env["BITBUCKET_BRANCH"] + end + + def git_tag + env["BITBUCKET_TAG"] + end + + # bitbucket-specific methods + + def url + "https://bitbucket.org/#{env["BITBUCKET_REPO_FULL_NAME"]}/addon/pipelines/home#" \ + "!/results/#{env["BITBUCKET_BUILD_NUMBER"]}" + end + + end + end + end + end +end diff --git a/lib/datadog/ci/ext/providers/extractor.rb b/lib/datadog/ci/ext/providers/extractor.rb index 3faacdf7..1ce2a7aa 100644 --- a/lib/datadog/ci/ext/providers/extractor.rb +++ b/lib/datadog/ci/ext/providers/extractor.rb @@ -14,10 +14,12 @@ class Extractor require_relative "default" require_relative "appveyor" require_relative "azure" + require_relative "bitbucket" EXTRACTORS = [ ["APPVEYOR", Appveyor], - ["TF_BUILD", Azure] + ["TF_BUILD", Azure], + ["BITBUCKET_COMMIT", Bitbucket] ] def self.for_environment(env) @@ -104,6 +106,7 @@ def git_branch end def git_repository_url + raise NoMethodError.new("This method must be overridden") end def git_tag @@ -131,6 +134,7 @@ def git_commit_message end def git_commit_sha + raise NoMethodError.new("This method must be overridden") end def branch_or_tag(branch_or_tag_string) diff --git a/sig/datadog/ci/ext/providers.rbs b/sig/datadog/ci/ext/providers.rbs deleted file mode 100644 index 44f813a2..00000000 --- a/sig/datadog/ci/ext/providers.rbs +++ /dev/null @@ -1,31 +0,0 @@ -module Datadog - module CI - module Ext - module Providers - TAG_JOB_NAME: "ci.job.name" - - TAG_JOB_URL: "ci.job.url" - - TAG_PIPELINE_ID: "ci.pipeline.id" - - TAG_PIPELINE_NAME: "ci.pipeline.name" - - TAG_PIPELINE_NUMBER: "ci.pipeline.number" - - TAG_PIPELINE_URL: "ci.pipeline.url" - - TAG_PROVIDER_NAME: "ci.provider.name" - - TAG_STAGE_NAME: "ci.stage.name" - - TAG_WORKSPACE_PATH: "ci.workspace_path" - - TAG_NODE_LABELS: "ci.node.labels" - - TAG_NODE_NAME: "ci.node.name" - - TAG_CI_ENV_VARS: "_dd.ci.env_vars" - end - end - end -end diff --git a/sig/datadog/ci/ext/providers/bitbucket.rbs b/sig/datadog/ci/ext/providers/bitbucket.rbs new file mode 100644 index 00000000..f2a5ee4b --- /dev/null +++ b/sig/datadog/ci/ext/providers/bitbucket.rbs @@ -0,0 +1,34 @@ +module Datadog + module CI + module Ext + module Providers + class Bitbucket < Extractor + private + def provider_name: () -> "bitbucket" + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def job_url: () -> String? + + def workspace_path: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def url: () -> ::String? + end + end + end + end +end From d01f763f4780f9f87b9d74b0e8a7034d26d9699b Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 16:48:04 +0200 Subject: [PATCH 05/31] reshuffle code locations, extract Buddy extractor to a separate class --- lib/datadog/ci/ext/environment.rb | 23 +--- .../{providers => environment}/extractor.rb | 22 +-- .../ci/ext/environment/providers/appveyor.rb | 101 ++++++++++++++ .../ci/ext/environment/providers/azure.rb | 126 ++++++++++++++++++ .../ci/ext/environment/providers/bitbucket.rb | 71 ++++++++++ .../ci/ext/environment/providers/buddy.rb | 72 ++++++++++ .../ci/ext/environment/providers/default.rb | 20 +++ lib/datadog/ci/ext/providers/appveyor.rb | 99 -------------- lib/datadog/ci/ext/providers/azure.rb | 124 ----------------- lib/datadog/ci/ext/providers/bitbucket.rb | 70 ---------- lib/datadog/ci/ext/providers/default.rb | 18 --- .../{providers => environment}/extractor.rbs | 2 +- .../ci/ext/environment/providers/appveyor.rbs | 48 +++++++ .../ci/ext/environment/providers/azure.rbs | 60 +++++++++ .../ext/environment/providers/bitbucket.rbs | 36 +++++ .../ci/ext/environment/providers/buddy.rbs | 38 ++++++ .../ci/ext/environment/providers/default.rbs | 13 ++ sig/datadog/ci/ext/providers/appveyor.rbs | 46 ------- sig/datadog/ci/ext/providers/azure.rbs | 58 -------- sig/datadog/ci/ext/providers/bitbucket.rbs | 34 ----- sig/datadog/ci/ext/providers/default.rbs | 11 -- 21 files changed, 600 insertions(+), 492 deletions(-) rename lib/datadog/ci/ext/{providers => environment}/extractor.rb (85%) create mode 100644 lib/datadog/ci/ext/environment/providers/appveyor.rb create mode 100644 lib/datadog/ci/ext/environment/providers/azure.rb create mode 100644 lib/datadog/ci/ext/environment/providers/bitbucket.rb create mode 100644 lib/datadog/ci/ext/environment/providers/buddy.rb create mode 100644 lib/datadog/ci/ext/environment/providers/default.rb delete mode 100644 lib/datadog/ci/ext/providers/appveyor.rb delete mode 100644 lib/datadog/ci/ext/providers/azure.rb delete mode 100644 lib/datadog/ci/ext/providers/bitbucket.rb delete mode 100644 lib/datadog/ci/ext/providers/default.rb rename sig/datadog/ci/ext/{providers => environment}/extractor.rbs (98%) create mode 100644 sig/datadog/ci/ext/environment/providers/appveyor.rbs create mode 100644 sig/datadog/ci/ext/environment/providers/azure.rbs create mode 100644 sig/datadog/ci/ext/environment/providers/bitbucket.rbs create mode 100644 sig/datadog/ci/ext/environment/providers/buddy.rbs create mode 100644 sig/datadog/ci/ext/environment/providers/default.rbs delete mode 100644 sig/datadog/ci/ext/providers/appveyor.rbs delete mode 100644 sig/datadog/ci/ext/providers/azure.rbs delete mode 100644 sig/datadog/ci/ext/providers/bitbucket.rbs delete mode 100644 sig/datadog/ci/ext/providers/default.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 8b650f05..a51e9ab6 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -4,7 +4,7 @@ require "json" require_relative "git" -require_relative "providers/extractor" +require_relative "environment/extractor" module Datadog module CI @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["BUDDY", :extract_buddy], ["BUILDKITE", :extract_buildkite], ["CIRCLECI", :extract_circle_ci], ["GITHUB_SHA", :extract_github_actions], @@ -42,7 +41,7 @@ module Environment def tags(env) # Extract metadata from CI provider environment variables _, extractor = PROVIDERS.find { |provider_env_var, _| env.key?(provider_env_var) } - tags = extractor ? public_send(extractor, env).reject { |_, v| v.nil? || v.strip.empty? } : Providers::Extractor.for_environment(env).tags + tags = extractor ? public_send(extractor, env).reject { |_, v| v.nil? || v.strip.empty? } : Environment::Extractor.for_environment(env).tags # If user defined metadata is defined, overwrite tags.merge!(extract_user_defined_git(env)) @@ -84,24 +83,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_buddy(env) - { - TAG_PROVIDER_NAME => "buddy", - TAG_PIPELINE_ID => "#{env["BUDDY_PIPELINE_ID"]}/#{env["BUDDY_EXECUTION_ID"]}", - TAG_PIPELINE_NAME => env["BUDDY_PIPELINE_NAME"], - TAG_PIPELINE_NUMBER => env["BUDDY_EXECUTION_ID"], - TAG_PIPELINE_URL => env["BUDDY_EXECUTION_URL"], - TAG_WORKSPACE_PATH => env["CI_WORKSPACE_PATH"], - Git::TAG_REPOSITORY_URL => env["BUDDY_SCM_URL"], - Git::TAG_COMMIT_SHA => env["BUDDY_EXECUTION_REVISION"], - Git::TAG_BRANCH => env["BUDDY_EXECUTION_BRANCH"], - Git::TAG_TAG => env["BUDDY_EXECUTION_TAG"], - Git::TAG_COMMIT_MESSAGE => env["BUDDY_EXECUTION_REVISION_MESSAGE"], - Git::TAG_COMMIT_COMMITTER_NAME => env["BUDDY_EXECUTION_REVISION_COMMITTER_NAME"], - Git::TAG_COMMIT_COMMITTER_EMAIL => env["BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL"] - } - end - def extract_buildkite(env) tags = { Git::TAG_BRANCH => env["BUILDKITE_BRANCH"], diff --git a/lib/datadog/ci/ext/providers/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb similarity index 85% rename from lib/datadog/ci/ext/providers/extractor.rb rename to lib/datadog/ci/ext/environment/extractor.rb index 1ce2a7aa..5130b077 100644 --- a/lib/datadog/ci/ext/providers/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -6,25 +6,27 @@ module Datadog module CI module Ext - module Providers + module Environment # Provider is a specific CI provider like Azure Pipelines, Github Actions, Gitlab CI, etc - # Providers::Extractor is responsible for detecting where pipeline is being executed based on environment vars + # Extractor is responsible for detecting where pipeline is being executed based on environment vars # and return the specific extractor that is able to return environment- and git-specific tags class Extractor - require_relative "default" - require_relative "appveyor" - require_relative "azure" - require_relative "bitbucket" + require_relative "providers/default" + require_relative "providers/appveyor" + require_relative "providers/azure" + require_relative "providers/bitbucket" + require_relative "providers/buddy" EXTRACTORS = [ - ["APPVEYOR", Appveyor], - ["TF_BUILD", Azure], - ["BITBUCKET_COMMIT", Bitbucket] + ["APPVEYOR", Providers::Appveyor], + ["TF_BUILD", Providers::Azure], + ["BITBUCKET_COMMIT", Providers::Bitbucket], + ["BUDDY", Providers::Buddy] ] def self.for_environment(env) _, extractor_klass = EXTRACTORS.find { |provider_env_var, _| env.key?(provider_env_var) } - extractor_klass = Default if extractor_klass.nil? + extractor_klass = Providers::Default if extractor_klass.nil? extractor_klass.new(env) end diff --git a/lib/datadog/ci/ext/environment/providers/appveyor.rb b/lib/datadog/ci/ext/environment/providers/appveyor.rb new file mode 100644 index 00000000..26ea0aca --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/appveyor.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Appveyor: https://www.appveyor.com/ + # Environment variables docs: https://www.appveyor.com/docs/environment-variables/ + class Appveyor < Extractor + private + + # overridden methods + def provider_name + "appveyor" + end + + def pipeline_url + url + end + + def job_url + url + end + + def workspace_path + env["APPVEYOR_BUILD_FOLDER"] + end + + def pipeline_id + env["APPVEYOR_BUILD_ID"] + end + + def pipeline_name + env["APPVEYOR_REPO_NAME"] + end + + def pipeline_number + env["APPVEYOR_BUILD_NUMBER"] + end + + def git_repository_url + return nil unless github_repo_provider? + + "https://github.com/#{env["APPVEYOR_REPO_NAME"]}.git" + end + + def git_commit_sha + return nil unless github_repo_provider? + + env["APPVEYOR_REPO_COMMIT"] + end + + def git_branch + return nil unless github_repo_provider? + + env["APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH"] || env["APPVEYOR_REPO_BRANCH"] + end + + def git_tag + return nil unless github_repo_provider? + + env["APPVEYOR_REPO_TAG_NAME"] + end + + def git_commit_author_name + env["APPVEYOR_REPO_COMMIT_AUTHOR"] + end + + def git_commit_author_email + env["APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL"] + end + + def git_commit_message + commit_message = env["APPVEYOR_REPO_COMMIT_MESSAGE"] + if commit_message + extended = env["APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED"] + commit_message = "#{commit_message}\n#{extended}" if extended + end + commit_message + end + + # appveyor-specific methods + + def github_repo_provider? + return @github_repo_provider if defined?(@github_repo_provider) + + @github_repo_provider = env["APPVEYOR_REPO_PROVIDER"] == "github" + end + + def url + @url ||= "https://ci.appveyor.com/project/#{env["APPVEYOR_REPO_NAME"]}/builds/#{env["APPVEYOR_BUILD_ID"]}" + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/providers/azure.rb b/lib/datadog/ci/ext/environment/providers/azure.rb new file mode 100644 index 00000000..38c83d9c --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/azure.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Azure Pipelines: https://azure.microsoft.com/en-us/products/devops/pipelines + # Environment variables docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml + class Azure < Extractor + private + + # overridden methods + def provider_name + "azurepipelines" + end + + def pipeline_url + return unless url_defined? + + @pipeline_url ||= "#{team_foundation_server_uri}#{team_project_id}/_build/results?buildId=#{build_id}" + end + + def job_url + return unless url_defined? + + @job_url ||= "#{pipeline_url}&view=logs&j=#{env["SYSTEM_JOBID"]}&t=#{env["SYSTEM_TASKINSTANCEID"]}" + end + + def workspace_path + env["BUILD_SOURCESDIRECTORY"] + end + + def pipeline_id + build_id + end + + def pipeline_number + build_id + end + + def pipeline_name + env["BUILD_DEFINITIONNAME"] + end + + def stage_name + env["SYSTEM_STAGEDISPLAYNAME"] + end + + def job_name + env["SYSTEM_JOBDISPLAYNAME"] + end + + def git_repository_url + env["SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI"] || env["BUILD_REPOSITORY_URI"] + end + + def git_commit_sha + env["SYSTEM_PULLREQUEST_SOURCECOMMITID"] || env["BUILD_SOURCEVERSION"] + end + + def git_branch + return @branch if defined?(@branch) + + set_branch_and_tag + @branch + end + + def git_tag + return @tag if defined?(@tag) + + set_branch_and_tag + @tag + end + + def git_commit_author_name + env["BUILD_REQUESTEDFORID"] + end + + def git_commit_author_email + env["BUILD_REQUESTEDFOREMAIL"] + end + + def git_commit_message + env["BUILD_SOURCEVERSIONMESSAGE"] + end + + def ci_env_vars + { + "SYSTEM_TEAMPROJECTID" => env["SYSTEM_TEAMPROJECTID"], + "BUILD_BUILDID" => env["BUILD_BUILDID"], + "SYSTEM_JOBID" => env["SYSTEM_JOBID"] + }.to_json + end + + # azure-specific methods + + def build_id + env["BUILD_BUILDID"] + end + + def team_foundation_server_uri + env["SYSTEM_TEAMFOUNDATIONSERVERURI"] + end + + def team_project_id + env["SYSTEM_TEAMPROJECTID"] + end + + def url_defined? + !(build_id && team_foundation_server_uri && team_project_id).nil? + end + + def set_branch_and_tag + @branch, @tag = branch_or_tag( + env["SYSTEM_PULLREQUEST_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCHNAME"] + ) + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/providers/bitbucket.rb b/lib/datadog/ci/ext/environment/providers/bitbucket.rb new file mode 100644 index 00000000..e6bc4fb7 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/bitbucket.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Bitbucket Pipelines: https://bitbucket.org/product/features/pipelines + # Environment variables docs: https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ + class Bitbucket < Extractor + private + + # overridden methods + def provider_name + "bitbucket" + end + + def pipeline_id + env["BITBUCKET_PIPELINE_UUID"] ? env["BITBUCKET_PIPELINE_UUID"].tr("{}", "") : nil + end + + def pipeline_name + env["BITBUCKET_REPO_FULL_NAME"] + end + + def pipeline_number + env["BITBUCKET_BUILD_NUMBER"] + end + + def pipeline_url + url + end + + def job_url + url + end + + def workspace_path + env["BITBUCKET_CLONE_DIR"] + end + + def git_repository_url + env["BITBUCKET_GIT_SSH_ORIGIN"] || env["BITBUCKET_GIT_HTTP_ORIGIN"] + end + + def git_commit_sha + env["BITBUCKET_COMMIT"] + end + + def git_branch + env["BITBUCKET_BRANCH"] + end + + def git_tag + env["BITBUCKET_TAG"] + end + + # bitbucket-specific methods + + def url + "https://bitbucket.org/#{env["BITBUCKET_REPO_FULL_NAME"]}/addon/pipelines/home#" \ + "!/results/#{env["BITBUCKET_BUILD_NUMBER"]}" + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/providers/buddy.rb b/lib/datadog/ci/ext/environment/providers/buddy.rb new file mode 100644 index 00000000..f2518a57 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/buddy.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Buddy: https://buddy.works/ + # Environment variables docs: https://buddy.works/docs/pipelines/environment-variables + class Buddy < Extractor + private + + # overridden methods + def provider_name + "buddy" + end + + def pipeline_id + "#{env["BUDDY_PIPELINE_ID"]}/#{env["BUDDY_EXECUTION_ID"]}" + end + + def pipeline_name + env["BUDDY_PIPELINE_NAME"] + end + + def pipeline_number + env["BUDDY_EXECUTION_ID"] + end + + def pipeline_url + env["BUDDY_EXECUTION_URL"] + end + + def workspace_path + env["CI_WORKSPACE_PATH"] + end + + def git_repository_url + env["BUDDY_SCM_URL"] + end + + def git_commit_sha + env["BUDDY_EXECUTION_REVISION"] + end + + def git_branch + env["BUDDY_EXECUTION_BRANCH"] + end + + def git_tag + env["BUDDY_EXECUTION_TAG"] + end + + def git_commit_message + env["BUDDY_EXECUTION_REVISION_MESSAGE"] + end + + def git_commit_committer_name + env["BUDDY_EXECUTION_REVISION_COMMITTER_NAME"] + end + + def git_commit_committer_email + env["BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL"] + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/providers/default.rb b/lib/datadog/ci/ext/environment/providers/default.rb new file mode 100644 index 00000000..53864611 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/default.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # TODO + class Default < Extractor + def tags + {} + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/providers/appveyor.rb b/lib/datadog/ci/ext/providers/appveyor.rb deleted file mode 100644 index 1d3af293..00000000 --- a/lib/datadog/ci/ext/providers/appveyor.rb +++ /dev/null @@ -1,99 +0,0 @@ -# frozen_string_literal: true - -require_relative "extractor" - -module Datadog - module CI - module Ext - module Providers - # Appveyor: https://www.appveyor.com/ - # Environment variables docs: https://www.appveyor.com/docs/environment-variables/ - class Appveyor < Extractor - private - - # overridden methods - def provider_name - "appveyor" - end - - def pipeline_url - url - end - - def job_url - url - end - - def workspace_path - env["APPVEYOR_BUILD_FOLDER"] - end - - def pipeline_id - env["APPVEYOR_BUILD_ID"] - end - - def pipeline_name - env["APPVEYOR_REPO_NAME"] - end - - def pipeline_number - env["APPVEYOR_BUILD_NUMBER"] - end - - def git_repository_url - return nil unless github_repo_provider? - - "https://github.com/#{env["APPVEYOR_REPO_NAME"]}.git" - end - - def git_commit_sha - return nil unless github_repo_provider? - - env["APPVEYOR_REPO_COMMIT"] - end - - def git_branch - return nil unless github_repo_provider? - - env["APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH"] || env["APPVEYOR_REPO_BRANCH"] - end - - def git_tag - return nil unless github_repo_provider? - - env["APPVEYOR_REPO_TAG_NAME"] - end - - def git_commit_author_name - env["APPVEYOR_REPO_COMMIT_AUTHOR"] - end - - def git_commit_author_email - env["APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL"] - end - - def git_commit_message - commit_message = env["APPVEYOR_REPO_COMMIT_MESSAGE"] - if commit_message - extended = env["APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED"] - commit_message = "#{commit_message}\n#{extended}" if extended - end - commit_message - end - - # appveyor-specific methods - - def github_repo_provider? - return @github_repo_provider if defined?(@github_repo_provider) - - @github_repo_provider = env["APPVEYOR_REPO_PROVIDER"] == "github" - end - - def url - @url ||= "https://ci.appveyor.com/project/#{env["APPVEYOR_REPO_NAME"]}/builds/#{env["APPVEYOR_BUILD_ID"]}" - end - end - end - end - end -end diff --git a/lib/datadog/ci/ext/providers/azure.rb b/lib/datadog/ci/ext/providers/azure.rb deleted file mode 100644 index 796278eb..00000000 --- a/lib/datadog/ci/ext/providers/azure.rb +++ /dev/null @@ -1,124 +0,0 @@ -# frozen_string_literal: true - -require_relative "extractor" - -module Datadog - module CI - module Ext - module Providers - # Azure Pipelines: https://azure.microsoft.com/en-us/products/devops/pipelines - # Environment variables docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - class Azure < Extractor - private - - # overridden methods - def provider_name - "azurepipelines" - end - - def pipeline_url - return unless url_defined? - - @pipeline_url ||= "#{team_foundation_server_uri}#{team_project_id}/_build/results?buildId=#{build_id}" - end - - def job_url - return unless url_defined? - - @job_url ||= "#{pipeline_url}&view=logs&j=#{env["SYSTEM_JOBID"]}&t=#{env["SYSTEM_TASKINSTANCEID"]}" - end - - def workspace_path - env["BUILD_SOURCESDIRECTORY"] - end - - def pipeline_id - build_id - end - - def pipeline_number - build_id - end - - def pipeline_name - env["BUILD_DEFINITIONNAME"] - end - - def stage_name - env["SYSTEM_STAGEDISPLAYNAME"] - end - - def job_name - env["SYSTEM_JOBDISPLAYNAME"] - end - - def git_repository_url - env["SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI"] || env["BUILD_REPOSITORY_URI"] - end - - def git_commit_sha - env["SYSTEM_PULLREQUEST_SOURCECOMMITID"] || env["BUILD_SOURCEVERSION"] - end - - def git_branch - return @branch if defined?(@branch) - - set_branch_and_tag - @branch - end - - def git_tag - return @tag if defined?(@tag) - - set_branch_and_tag - @tag - end - - def git_commit_author_name - env["BUILD_REQUESTEDFORID"] - end - - def git_commit_author_email - env["BUILD_REQUESTEDFOREMAIL"] - end - - def git_commit_message - env["BUILD_SOURCEVERSIONMESSAGE"] - end - - def ci_env_vars - { - "SYSTEM_TEAMPROJECTID" => env["SYSTEM_TEAMPROJECTID"], - "BUILD_BUILDID" => env["BUILD_BUILDID"], - "SYSTEM_JOBID" => env["SYSTEM_JOBID"] - }.to_json - end - - # azure-specific methods - - def build_id - env["BUILD_BUILDID"] - end - - def team_foundation_server_uri - env["SYSTEM_TEAMFOUNDATIONSERVERURI"] - end - - def team_project_id - env["SYSTEM_TEAMPROJECTID"] - end - - def url_defined? - !(build_id && team_foundation_server_uri && team_project_id).nil? - end - - def set_branch_and_tag - @branch, @tag = branch_or_tag( - env["SYSTEM_PULLREQUEST_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCHNAME"] - ) - end - end - end - end - end -end diff --git a/lib/datadog/ci/ext/providers/bitbucket.rb b/lib/datadog/ci/ext/providers/bitbucket.rb deleted file mode 100644 index 57b04897..00000000 --- a/lib/datadog/ci/ext/providers/bitbucket.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require_relative "extractor" - -module Datadog - module CI - module Ext - module Providers - # Bitbucket Pipelines: https://bitbucket.org/product/features/pipelines - # Environment variables docs: https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ - class Bitbucket < Extractor - private - - # overridden methods - def provider_name - "bitbucket" - end - - def pipeline_id - env["BITBUCKET_PIPELINE_UUID"] ? env["BITBUCKET_PIPELINE_UUID"].tr("{}", "") : nil - end - - def pipeline_name - env["BITBUCKET_REPO_FULL_NAME"] - end - - def pipeline_number - env["BITBUCKET_BUILD_NUMBER"] - end - - def pipeline_url - url - end - - def job_url - url - end - - def workspace_path - env["BITBUCKET_CLONE_DIR"] - end - - def git_repository_url - env["BITBUCKET_GIT_SSH_ORIGIN"] || env["BITBUCKET_GIT_HTTP_ORIGIN"] - end - - def git_commit_sha - env["BITBUCKET_COMMIT"] - end - - def git_branch - env["BITBUCKET_BRANCH"] - end - - def git_tag - env["BITBUCKET_TAG"] - end - - # bitbucket-specific methods - - def url - "https://bitbucket.org/#{env["BITBUCKET_REPO_FULL_NAME"]}/addon/pipelines/home#" \ - "!/results/#{env["BITBUCKET_BUILD_NUMBER"]}" - end - - end - end - end - end -end diff --git a/lib/datadog/ci/ext/providers/default.rb b/lib/datadog/ci/ext/providers/default.rb deleted file mode 100644 index da9b81aa..00000000 --- a/lib/datadog/ci/ext/providers/default.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require_relative "extractor" - -module Datadog - module CI - module Ext - module Providers - # TODO - class Default < Extractor - def tags - {} - end - end - end - end - end -end diff --git a/sig/datadog/ci/ext/providers/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs similarity index 98% rename from sig/datadog/ci/ext/providers/extractor.rbs rename to sig/datadog/ci/ext/environment/extractor.rbs index d8cac7e3..64d3f277 100644 --- a/sig/datadog/ci/ext/providers/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -1,7 +1,7 @@ module Datadog module CI module Ext - module Providers + module Environment class Extractor EXTRACTORS: ::Array[::Array[String | untyped]] diff --git a/sig/datadog/ci/ext/environment/providers/appveyor.rbs b/sig/datadog/ci/ext/environment/providers/appveyor.rbs new file mode 100644 index 00000000..1508c74d --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/appveyor.rbs @@ -0,0 +1,48 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Appveyor < Extractor + private + + @github_repo_provider: bool + @url: String + + def provider_name: () -> "appveyor" + + def pipeline_url: () -> String? + + def job_url: () -> String? + + def workspace_path: () -> String? + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_message: () -> String? + + def github_repo_provider?: () -> bool + + def url: () -> String? + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/azure.rbs b/sig/datadog/ci/ext/environment/providers/azure.rbs new file mode 100644 index 00000000..3b89b88a --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/azure.rbs @@ -0,0 +1,60 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Azure < Extractor + private + + @pipeline_url: String + @job_url: String + + def provider_name: () -> "azurepipelines" + + def pipeline_url: () -> String? + + def job_url: () -> String? + + def workspace_path: () -> String? + + def pipeline_id: () -> String? + + def pipeline_number: () -> String? + + def pipeline_name: () -> String? + + def stage_name: () -> String? + + def job_name: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_message: () -> String? + + def ci_env_vars: () -> String? + + def build_id: () -> String? + + def team_foundation_server_uri: () -> String? + + def team_project_id: () -> String? + + def url_defined?: () -> bool + + def set_branch_and_tag: () -> [String?, String?] + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/bitbucket.rbs b/sig/datadog/ci/ext/environment/providers/bitbucket.rbs new file mode 100644 index 00000000..3dbe8af9 --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/bitbucket.rbs @@ -0,0 +1,36 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Bitbucket < Extractor + private + def provider_name: () -> "bitbucket" + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def job_url: () -> String? + + def workspace_path: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def url: () -> ::String? + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/buddy.rbs b/sig/datadog/ci/ext/environment/providers/buddy.rbs new file mode 100644 index 00000000..07f01a1c --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/buddy.rbs @@ -0,0 +1,38 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Buddy < Extractor + private + def provider_name: () -> "buddy" + + def pipeline_id: () -> ::String + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def workspace_path: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_message: () -> String? + + def git_commit_committer_name: () -> String? + + def git_commit_committer_email: () -> String? + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/default.rbs b/sig/datadog/ci/ext/environment/providers/default.rbs new file mode 100644 index 00000000..2b00c8fa --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/default.rbs @@ -0,0 +1,13 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Default < Extractor + def tags: () -> ::Hash[String, untyped] + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/providers/appveyor.rbs b/sig/datadog/ci/ext/providers/appveyor.rbs deleted file mode 100644 index e9f063bb..00000000 --- a/sig/datadog/ci/ext/providers/appveyor.rbs +++ /dev/null @@ -1,46 +0,0 @@ -module Datadog - module CI - module Ext - module Providers - class Appveyor < Extractor - private - - @github_repo_provider: bool - @url: String - - def provider_name: () -> "appveyor" - - def pipeline_url: () -> String? - - def job_url: () -> String? - - def workspace_path: () -> String? - - def pipeline_id: () -> String? - - def pipeline_name: () -> String? - - def pipeline_number: () -> String? - - def git_repository_url: () -> String? - - def git_commit_sha: () -> String? - - def git_branch: () -> String? - - def git_tag: () -> String? - - def git_commit_author_name: () -> String? - - def git_commit_author_email: () -> String? - - def git_commit_message: () -> String? - - def github_repo_provider?: () -> bool - - def url: () -> String? - end - end - end - end -end diff --git a/sig/datadog/ci/ext/providers/azure.rbs b/sig/datadog/ci/ext/providers/azure.rbs deleted file mode 100644 index d4ffbc6d..00000000 --- a/sig/datadog/ci/ext/providers/azure.rbs +++ /dev/null @@ -1,58 +0,0 @@ -module Datadog - module CI - module Ext - module Providers - class Azure < Extractor - private - - @pipeline_url: String - @job_url: String - - def provider_name: () -> "azurepipelines" - - def pipeline_url: () -> String? - - def job_url: () -> String? - - def workspace_path: () -> String? - - def pipeline_id: () -> String? - - def pipeline_number: () -> String? - - def pipeline_name: () -> String? - - def stage_name: () -> String? - - def job_name: () -> String? - - def git_repository_url: () -> String? - - def git_commit_sha: () -> String? - - def git_branch: () -> String? - - def git_tag: () -> String? - - def git_commit_author_name: () -> String? - - def git_commit_author_email: () -> String? - - def git_commit_message: () -> String? - - def ci_env_vars: () -> String? - - def build_id: () -> String? - - def team_foundation_server_uri: () -> String? - - def team_project_id: () -> String? - - def url_defined?: () -> bool - - def set_branch_and_tag: () -> [String?, String?] - end - end - end - end -end diff --git a/sig/datadog/ci/ext/providers/bitbucket.rbs b/sig/datadog/ci/ext/providers/bitbucket.rbs deleted file mode 100644 index f2a5ee4b..00000000 --- a/sig/datadog/ci/ext/providers/bitbucket.rbs +++ /dev/null @@ -1,34 +0,0 @@ -module Datadog - module CI - module Ext - module Providers - class Bitbucket < Extractor - private - def provider_name: () -> "bitbucket" - - def pipeline_id: () -> String? - - def pipeline_name: () -> String? - - def pipeline_number: () -> String? - - def pipeline_url: () -> String? - - def job_url: () -> String? - - def workspace_path: () -> String? - - def git_repository_url: () -> String? - - def git_commit_sha: () -> String? - - def git_branch: () -> String? - - def git_tag: () -> String? - - def url: () -> ::String? - end - end - end - end -end diff --git a/sig/datadog/ci/ext/providers/default.rbs b/sig/datadog/ci/ext/providers/default.rbs deleted file mode 100644 index ce93a465..00000000 --- a/sig/datadog/ci/ext/providers/default.rbs +++ /dev/null @@ -1,11 +0,0 @@ -module Datadog - module CI - module Ext - module Providers - class Default < Extractor - def tags: () -> ::Hash[String, untyped] - end - end - end - end -end From ee395893a4c610209fc5b465eb0774a6067d754c Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 17:53:23 +0200 Subject: [PATCH 06/31] extract buildkite extractor to a separate class --- lib/datadog/ci/ext/environment.rb | 1 - lib/datadog/ci/ext/environment/extractor.rb | 12 ++- .../ci/ext/environment/providers/buildkite.rb | 99 +++++++++++++++++++ .../ext/environment/providers/buildkite.rbs | 46 +++++++++ 4 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/buildkite.rb create mode 100644 sig/datadog/ci/ext/environment/providers/buildkite.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index a51e9ab6..911f405d 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["BUILDKITE", :extract_buildkite], ["CIRCLECI", :extract_circle_ci], ["GITHUB_SHA", :extract_github_actions], ["GITLAB_CI", :extract_gitlab], diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 5130b077..70be38a2 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -16,12 +16,14 @@ class Extractor require_relative "providers/azure" require_relative "providers/bitbucket" require_relative "providers/buddy" + require_relative "providers/buildkite" EXTRACTORS = [ ["APPVEYOR", Providers::Appveyor], ["TF_BUILD", Providers::Azure], ["BITBUCKET_COMMIT", Providers::Bitbucket], - ["BUDDY", Providers::Buddy] + ["BUDDY", Providers::Buddy], + ["BUILDKITE", Providers::Buildkite] ] def self.for_environment(env) @@ -61,7 +63,13 @@ def tags Git::TAG_COMMIT_COMMITTER_NAME => git_commit_committer_name, Git::TAG_COMMIT_MESSAGE => git_commit_message, Git::TAG_COMMIT_SHA => git_commit_sha - }.reject { |_, v| v.nil? } + }.reject do |_, v| + # setting type of v here to untyped because steep does not + # understand `v.nil? || something` + + # @type var v: untyped + v.nil? || v.strip.empty? + end end private diff --git a/lib/datadog/ci/ext/environment/providers/buildkite.rb b/lib/datadog/ci/ext/environment/providers/buildkite.rb new file mode 100644 index 00000000..1d98dd03 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/buildkite.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Buildkite: https://buildkite.com/ + # Environment variables docs: https://buildkite.com/docs/pipelines/environment-variables + class Buildkite < Extractor + private + + # overridden methods + def provider_name + "buildkite" + end + + def job_url + "#{env["BUILDKITE_BUILD_URL"]}##{env["BUILDKITE_JOB_ID"]}" + end + + def pipeline_id + env["BUILDKITE_BUILD_ID"] + end + + def pipeline_name + env["BUILDKITE_PIPELINE_SLUG"] + end + + def pipeline_number + env["BUILDKITE_BUILD_NUMBER"] + end + + def pipeline_url + env["BUILDKITE_BUILD_URL"] + end + + def node_name + env["BUILDKITE_AGENT_ID"] + end + + def node_labels + labels = env + .select { |key| key.start_with?("BUILDKITE_AGENT_META_DATA_") } + .map { |key, value| "#{key.to_s.sub("BUILDKITE_AGENT_META_DATA_", "").downcase}:#{value}" } + .sort_by(&:length) + + labels.to_json unless labels.empty? + end + + def workspace_path + env["BUILDKITE_BUILD_CHECKOUT_PATH"] + end + + def git_repository_url + env["BUILDKITE_REPO"] + end + + def git_commit_sha + env["BUILDKITE_COMMIT"] + end + + def git_branch + env["BUILDKITE_BRANCH"] + end + + def git_tag + env["BUILDKITE_TAG"] + end + + def git_commit_author_name + env["BUILDKITE_BUILD_AUTHOR"] + end + + def git_commit_author_email + env["BUILDKITE_BUILD_AUTHOR_EMAIL"] + end + + def git_commit_message + env["BUILDKITE_MESSAGE"] + end + + def ci_env_vars + { + "BUILDKITE_BUILD_ID" => env["BUILDKITE_BUILD_ID"], + "BUILDKITE_JOB_ID" => env["BUILDKITE_JOB_ID"] + }.to_json + end + + # buildkite-specific methods + + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/buildkite.rbs b/sig/datadog/ci/ext/environment/providers/buildkite.rbs new file mode 100644 index 00000000..f1f30ba1 --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/buildkite.rbs @@ -0,0 +1,46 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Buildkite < Extractor + private + def provider_name: () -> "buildkite" + + def job_url: () -> ::String + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def node_name: () -> String? + + def node_labels: () -> String? + + def workspace_path: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_message: () -> String? + + def ci_env_vars: () -> String? + end + end + end + end + end +end From ba855095351a6afa9175cea858ea8da8f4ebe065 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 17:56:33 +0200 Subject: [PATCH 07/31] finish extracting buildkite --- lib/datadog/ci/ext/environment.rb | 33 ------------------------------- 1 file changed, 33 deletions(-) diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 911f405d..5bab72a8 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -82,39 +82,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_buildkite(env) - tags = { - Git::TAG_BRANCH => env["BUILDKITE_BRANCH"], - Git::TAG_COMMIT_SHA => env["BUILDKITE_COMMIT"], - Git::TAG_REPOSITORY_URL => env["BUILDKITE_REPO"], - Git::TAG_TAG => env["BUILDKITE_TAG"], - TAG_PIPELINE_ID => env["BUILDKITE_BUILD_ID"], - TAG_PIPELINE_NAME => env["BUILDKITE_PIPELINE_SLUG"], - TAG_PIPELINE_NUMBER => env["BUILDKITE_BUILD_NUMBER"], - TAG_PIPELINE_URL => env["BUILDKITE_BUILD_URL"], - TAG_JOB_URL => "#{env["BUILDKITE_BUILD_URL"]}##{env["BUILDKITE_JOB_ID"]}", - TAG_PROVIDER_NAME => "buildkite", - TAG_WORKSPACE_PATH => env["BUILDKITE_BUILD_CHECKOUT_PATH"], - Git::TAG_COMMIT_AUTHOR_NAME => env["BUILDKITE_BUILD_AUTHOR"], - Git::TAG_COMMIT_AUTHOR_EMAIL => env["BUILDKITE_BUILD_AUTHOR_EMAIL"], - Git::TAG_COMMIT_MESSAGE => env["BUILDKITE_MESSAGE"], - TAG_NODE_NAME => env["BUILDKITE_AGENT_ID"], - TAG_CI_ENV_VARS => { - "BUILDKITE_BUILD_ID" => env["BUILDKITE_BUILD_ID"], - "BUILDKITE_JOB_ID" => env["BUILDKITE_JOB_ID"] - }.to_json - } - - extra_tags = env - .select { |key| key.start_with?("BUILDKITE_AGENT_META_DATA_") } - .map { |key, value| "#{key.to_s.sub("BUILDKITE_AGENT_META_DATA_", "").downcase}:#{value}" } - .sort_by(&:length) - - tags[TAG_NODE_LABELS] = extra_tags.to_json unless extra_tags.empty? - - tags - end - def extract_circle_ci(env) { Git::TAG_BRANCH => env["CIRCLE_BRANCH"], From c6d0401fe36bc3d32c6c0989624e71d813904ed2 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 18:09:45 +0200 Subject: [PATCH 08/31] fix linting and better naming and typing --- lib/datadog/ci/ext/environment/extractor.rb | 4 ++-- lib/datadog/ci/ext/environment/providers/buildkite.rb | 1 - sig/datadog/ci/ext/environment/extractor.rbs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 70be38a2..41eb80ed 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -18,7 +18,7 @@ class Extractor require_relative "providers/buddy" require_relative "providers/buildkite" - EXTRACTORS = [ + PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], ["TF_BUILD", Providers::Azure], ["BITBUCKET_COMMIT", Providers::Bitbucket], @@ -27,7 +27,7 @@ class Extractor ] def self.for_environment(env) - _, extractor_klass = EXTRACTORS.find { |provider_env_var, _| env.key?(provider_env_var) } + _, extractor_klass = PROVIDERS.find { |provider_env_var, _| env.key?(provider_env_var) } extractor_klass = Providers::Default if extractor_klass.nil? extractor_klass.new(env) diff --git a/lib/datadog/ci/ext/environment/providers/buildkite.rb b/lib/datadog/ci/ext/environment/providers/buildkite.rb index 1d98dd03..d368c80e 100644 --- a/lib/datadog/ci/ext/environment/providers/buildkite.rb +++ b/lib/datadog/ci/ext/environment/providers/buildkite.rb @@ -90,7 +90,6 @@ def ci_env_vars end # buildkite-specific methods - end end end diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index 64d3f277..660e6b1b 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -4,7 +4,7 @@ module Datadog module Environment class Extractor - EXTRACTORS: ::Array[::Array[String | untyped]] + PROVIDERS: ::Array[[String, singleton(Extractor)]] @branch: String? @tag: String? From 852bd81f2bb01242455add7097906068bb1f4a94 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 11:08:52 +0200 Subject: [PATCH 09/31] extract Circle CI to a separate extractor class --- lib/datadog/ci/ext/environment.rb | 5 +- lib/datadog/ci/ext/environment/extractor.rb | 4 +- .../ci/ext/environment/providers/buildkite.rb | 2 - .../ci/ext/environment/providers/circleci.rb | 83 +++++++++++++++++++ .../ci/ext/environment/providers/circleci.rbs | 42 ++++++++++ 5 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/circleci.rb create mode 100644 sig/datadog/ci/ext/environment/providers/circleci.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 5bab72a8..e818a3a2 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["CIRCLECI", :extract_circle_ci], ["GITHUB_SHA", :extract_github_actions], ["GITLAB_CI", :extract_gitlab], ["JENKINS_URL", :extract_jenkins], @@ -44,12 +43,12 @@ def tags(env) # If user defined metadata is defined, overwrite tags.merge!(extract_user_defined_git(env)) + + # Normalize Git references if !tags[Git::TAG_BRANCH].nil? && tags[Git::TAG_BRANCH].include?("tags/") tags[Git::TAG_TAG] = tags[Git::TAG_BRANCH] tags.delete(Git::TAG_BRANCH) end - - # Normalize Git references tags[Git::TAG_TAG] = normalize_ref(tags[Git::TAG_TAG]) tags[Git::TAG_BRANCH] = normalize_ref(tags[Git::TAG_BRANCH]) tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info( diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 41eb80ed..29799efc 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -17,13 +17,15 @@ class Extractor require_relative "providers/bitbucket" require_relative "providers/buddy" require_relative "providers/buildkite" + require_relative "providers/circleci" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], ["TF_BUILD", Providers::Azure], ["BITBUCKET_COMMIT", Providers::Bitbucket], ["BUDDY", Providers::Buddy], - ["BUILDKITE", Providers::Buildkite] + ["BUILDKITE", Providers::Buildkite], + ["CIRCLECI", Providers::Circleci] ] def self.for_environment(env) diff --git a/lib/datadog/ci/ext/environment/providers/buildkite.rb b/lib/datadog/ci/ext/environment/providers/buildkite.rb index d368c80e..a871d357 100644 --- a/lib/datadog/ci/ext/environment/providers/buildkite.rb +++ b/lib/datadog/ci/ext/environment/providers/buildkite.rb @@ -88,8 +88,6 @@ def ci_env_vars "BUILDKITE_JOB_ID" => env["BUILDKITE_JOB_ID"] }.to_json end - - # buildkite-specific methods end end end diff --git a/lib/datadog/ci/ext/environment/providers/circleci.rb b/lib/datadog/ci/ext/environment/providers/circleci.rb new file mode 100644 index 00000000..71488e75 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/circleci.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Circle CI: https://circleci.com/ + # Environment variables docs: https://circleci.com/docs/variables/#built-in-environment-variables + class Circleci < Extractor + private + + # overridden methods + def provider_name + "circleci" + end + + def job_url + env["CIRCLE_BUILD_URL"] + end + + def job_name + env["CIRCLE_JOB"] + end + + def pipeline_id + env["CIRCLE_WORKFLOW_ID"] + end + + def pipeline_name + env["CIRCLE_PROJECT_REPONAME"] + end + + def pipeline_url + "https://app.circleci.com/pipelines/workflows/#{env["CIRCLE_WORKFLOW_ID"]}" + end + + def workspace_path + env["CIRCLE_WORKING_DIRECTORY"] + end + + def git_repository_url + env["CIRCLE_REPOSITORY_URL"] + end + + def git_commit_sha + env["CIRCLE_SHA1"] + end + + def git_branch + env["CIRCLE_BRANCH"] + end + + def git_tag + env["CIRCLE_TAG"] + end + + def git_commit_author_name + env["BUILD_REQUESTEDFORID"] + end + + def git_commit_author_email + env["BUILD_REQUESTEDFOREMAIL"] + end + + def git_commit_message + env["BUILD_SOURCEVERSIONMESSAGE"] + end + + def ci_env_vars + { + "CIRCLE_WORKFLOW_ID" => env["CIRCLE_WORKFLOW_ID"], + "CIRCLE_BUILD_NUM" => env["CIRCLE_BUILD_NUM"] + }.to_json + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/circleci.rbs b/sig/datadog/ci/ext/environment/providers/circleci.rbs new file mode 100644 index 00000000..b7c9bbce --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/circleci.rbs @@ -0,0 +1,42 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Circleci < Extractor + private + def provider_name: () -> "circleci" + + def job_url: () -> String? + + def job_name: () -> String? + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_url: () -> ::String + + def workspace_path: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_message: () -> String? + + def ci_env_vars: () -> ::String + end + end + end + end + end +end From d7ec84d8e86d782d49cd401d57198a49cd2a7bc2 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 11:23:11 +0200 Subject: [PATCH 10/31] extract GithubActions provider --- lib/datadog/ci/ext/environment.rb | 54 ---------- lib/datadog/ci/ext/environment/extractor.rb | 4 +- .../environment/providers/github_actions.rb | 99 +++++++++++++++++++ .../environment/providers/github_actions.rbs | 44 +++++++++ 4 files changed, 146 insertions(+), 55 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/github_actions.rb create mode 100644 sig/datadog/ci/ext/environment/providers/github_actions.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index e818a3a2..4d941c87 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["GITHUB_SHA", :extract_github_actions], ["GITLAB_CI", :extract_gitlab], ["JENKINS_URL", :extract_jenkins], ["TEAMCITY_VERSION", :extract_teamcity], @@ -81,59 +80,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_circle_ci(env) - { - Git::TAG_BRANCH => env["CIRCLE_BRANCH"], - Git::TAG_COMMIT_SHA => env["CIRCLE_SHA1"], - Git::TAG_REPOSITORY_URL => env["CIRCLE_REPOSITORY_URL"], - Git::TAG_TAG => env["CIRCLE_TAG"], - TAG_PIPELINE_ID => env["CIRCLE_WORKFLOW_ID"], - TAG_PIPELINE_NAME => env["CIRCLE_PROJECT_REPONAME"], - TAG_PIPELINE_URL => "https://app.circleci.com/pipelines/workflows/#{env["CIRCLE_WORKFLOW_ID"]}", - TAG_JOB_NAME => env["CIRCLE_JOB"], - TAG_JOB_URL => env["CIRCLE_BUILD_URL"], - TAG_PROVIDER_NAME => "circleci", - TAG_WORKSPACE_PATH => env["CIRCLE_WORKING_DIRECTORY"], - Git::TAG_COMMIT_AUTHOR_NAME => env["BUILD_REQUESTEDFORID"], - Git::TAG_COMMIT_AUTHOR_EMAIL => env["BUILD_REQUESTEDFOREMAIL"], - Git::TAG_COMMIT_MESSAGE => env["BUILD_SOURCEVERSIONMESSAGE"], - TAG_CI_ENV_VARS => { - "CIRCLE_WORKFLOW_ID" => env["CIRCLE_WORKFLOW_ID"], - "CIRCLE_BUILD_NUM" => env["CIRCLE_BUILD_NUM"] - }.to_json - } - end - - def extract_github_actions(env) - ref = env["GITHUB_HEAD_REF"] - ref = env["GITHUB_REF"] if ref.nil? || ref.empty? - branch, tag = branch_or_tag(ref) - - pipeline_url = "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/actions/runs/#{env["GITHUB_RUN_ID"]}" - pipeline_url = "#{pipeline_url}/attempts/#{env["GITHUB_RUN_ATTEMPT"]}" if env["GITHUB_RUN_ATTEMPT"] - - { - Git::TAG_BRANCH => branch, - Git::TAG_COMMIT_SHA => env["GITHUB_SHA"], - Git::TAG_REPOSITORY_URL => "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}.git", - Git::TAG_TAG => tag, - TAG_JOB_URL => "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks", - TAG_JOB_NAME => env["GITHUB_JOB"], - TAG_PIPELINE_ID => env["GITHUB_RUN_ID"], - TAG_PIPELINE_NAME => env["GITHUB_WORKFLOW"], - TAG_PIPELINE_NUMBER => env["GITHUB_RUN_NUMBER"], - TAG_PIPELINE_URL => pipeline_url, - TAG_PROVIDER_NAME => "github", - TAG_WORKSPACE_PATH => env["GITHUB_WORKSPACE"], - TAG_CI_ENV_VARS => { - "GITHUB_SERVER_URL" => env["GITHUB_SERVER_URL"], - "GITHUB_REPOSITORY" => env["GITHUB_REPOSITORY"], - "GITHUB_RUN_ID" => env["GITHUB_RUN_ID"], - "GITHUB_RUN_ATTEMPT" => env["GITHUB_RUN_ATTEMPT"] - }.reject { |_k, v| v.nil? }.to_json - } - end - def extract_gitlab(env) commit_author_name, commit_author_email = extract_name_email(env["CI_COMMIT_AUTHOR"]) diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 29799efc..8a57f84e 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -18,6 +18,7 @@ class Extractor require_relative "providers/buddy" require_relative "providers/buildkite" require_relative "providers/circleci" + require_relative "providers/github_actions" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], @@ -25,7 +26,8 @@ class Extractor ["BITBUCKET_COMMIT", Providers::Bitbucket], ["BUDDY", Providers::Buddy], ["BUILDKITE", Providers::Buildkite], - ["CIRCLECI", Providers::Circleci] + ["CIRCLECI", Providers::Circleci], + ["GITHUB_SHA", Providers::GithubActions] ] def self.for_environment(env) diff --git a/lib/datadog/ci/ext/environment/providers/github_actions.rb b/lib/datadog/ci/ext/environment/providers/github_actions.rb new file mode 100644 index 00000000..730f4635 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/github_actions.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Github Actions: https://github.com/features/actions + # Environment variables docs: https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables + class GithubActions < Extractor + private + + # overridden methods + def provider_name + "github" + end + + def job_name + env["GITHUB_JOB"] + end + + def job_url + "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks" + end + + def pipeline_id + env["GITHUB_RUN_ID"] + end + + def pipeline_name + env["GITHUB_WORKFLOW"] + end + + def pipeline_number + env["GITHUB_RUN_NUMBER"] + end + + def pipeline_url + res = "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/actions/runs/#{env["GITHUB_RUN_ID"]}" + res = "#{res}/attempts/#{env["GITHUB_RUN_ATTEMPT"]}" if env["GITHUB_RUN_ATTEMPT"] + res + end + + def workspace_path + env["GITHUB_WORKSPACE"] + end + + def git_repository_url + "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}.git" + end + + def git_commit_sha + env["GITHUB_SHA"] + end + + def git_branch + return @branch if defined?(@branch) + + set_branch_and_tag + @branch + end + + def git_tag + return @tag if defined?(@tag) + + set_branch_and_tag + @tag + end + + def ci_env_vars + { + "GITHUB_SERVER_URL" => env["GITHUB_SERVER_URL"], + "GITHUB_REPOSITORY" => env["GITHUB_REPOSITORY"], + "GITHUB_RUN_ID" => env["GITHUB_RUN_ID"], + "GITHUB_RUN_ATTEMPT" => env["GITHUB_RUN_ATTEMPT"] + }.reject { |_, v| v.nil? }.to_json + end + + # github-specific methods + + def ref + return @ref if defined?(@ref) + + @ref = env["GITHUB_HEAD_REF"] + @ref = env["GITHUB_REF"] if @ref.nil? || @ref.empty? + @ref + end + + def set_branch_and_tag + @branch, @tag = branch_or_tag(ref) + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/github_actions.rbs b/sig/datadog/ci/ext/environment/providers/github_actions.rbs new file mode 100644 index 00000000..4303a27a --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/github_actions.rbs @@ -0,0 +1,44 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class GithubActions < Extractor + private + @ref: String + + def provider_name: () -> "github" + + def job_name: () -> String? + + def job_url: () -> ::String + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def workspace_path: () -> String? + + def git_repository_url: () -> ::String + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def ci_env_vars: () -> String? + + def ref: () -> String + + def set_branch_and_tag: () -> [String?, String?] + end + end + end + end + end +end From 91943fb29c44e35387bdb2b8177a07d10319b7ba Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 11:55:44 +0200 Subject: [PATCH 11/31] extract gitlab CI --- lib/datadog/ci/ext/environment.rb | 43 ------ lib/datadog/ci/ext/environment/extractor.rb | 4 +- .../ci/ext/environment/providers/gitlab.rb | 122 ++++++++++++++++++ .../ci/ext/environment/providers/gitlab.rbs | 57 ++++++++ 4 files changed, 182 insertions(+), 44 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/gitlab.rb create mode 100644 sig/datadog/ci/ext/environment/providers/gitlab.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 4d941c87..74951709 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["GITLAB_CI", :extract_gitlab], ["JENKINS_URL", :extract_jenkins], ["TEAMCITY_VERSION", :extract_teamcity], ["TRAVIS", :extract_travis], @@ -80,37 +79,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_gitlab(env) - commit_author_name, commit_author_email = extract_name_email(env["CI_COMMIT_AUTHOR"]) - - { - Git::TAG_BRANCH => env["CI_COMMIT_REF_NAME"], - Git::TAG_COMMIT_SHA => env["CI_COMMIT_SHA"], - Git::TAG_REPOSITORY_URL => env["CI_REPOSITORY_URL"], - Git::TAG_TAG => env["CI_COMMIT_TAG"], - Git::TAG_COMMIT_AUTHOR_NAME => commit_author_name, - Git::TAG_COMMIT_AUTHOR_EMAIL => commit_author_email, - Git::TAG_COMMIT_AUTHOR_DATE => env["CI_COMMIT_TIMESTAMP"], - TAG_STAGE_NAME => env["CI_JOB_STAGE"], - TAG_JOB_NAME => env["CI_JOB_NAME"], - TAG_JOB_URL => env["CI_JOB_URL"], - TAG_PIPELINE_ID => env["CI_PIPELINE_ID"], - TAG_PIPELINE_NAME => env["CI_PROJECT_PATH"], - TAG_PIPELINE_NUMBER => env["CI_PIPELINE_IID"], - TAG_PIPELINE_URL => env["CI_PIPELINE_URL"], - TAG_PROVIDER_NAME => "gitlab", - TAG_WORKSPACE_PATH => env["CI_PROJECT_DIR"], - TAG_NODE_LABELS => env["CI_RUNNER_TAGS"], - TAG_NODE_NAME => env["CI_RUNNER_ID"], - Git::TAG_COMMIT_MESSAGE => env["CI_COMMIT_MESSAGE"], - TAG_CI_ENV_VARS => { - "CI_PROJECT_URL" => env["CI_PROJECT_URL"], - "CI_PIPELINE_ID" => env["CI_PIPELINE_ID"], - "CI_JOB_ID" => env["CI_JOB_ID"] - }.to_json - } - end - def extract_jenkins(env) branch, tag = branch_or_tag(env["GIT_BRANCH"]) @@ -354,17 +322,6 @@ def branch_or_tag(branch_or_tag) [branch, tag] end - - def extract_name_email(name_and_email) - if name_and_email.include?("<") && (match = /^([^<]*)<([^>]*)>$/.match(name_and_email)) - name = match[1] - name = name.strip if name - email = match[2] - return [name, email] if name && email - end - - [nil, name_and_email] - end end end end diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 8a57f84e..aaba725c 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -19,6 +19,7 @@ class Extractor require_relative "providers/buildkite" require_relative "providers/circleci" require_relative "providers/github_actions" + require_relative "providers/gitlab" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], @@ -27,7 +28,8 @@ class Extractor ["BUDDY", Providers::Buddy], ["BUILDKITE", Providers::Buildkite], ["CIRCLECI", Providers::Circleci], - ["GITHUB_SHA", Providers::GithubActions] + ["GITHUB_SHA", Providers::GithubActions], + ["GITLAB_CI", Providers::Gitlab] ] def self.for_environment(env) diff --git a/lib/datadog/ci/ext/environment/providers/gitlab.rb b/lib/datadog/ci/ext/environment/providers/gitlab.rb new file mode 100644 index 00000000..bad709cb --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/gitlab.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Gitlab CI: https://docs.gitlab.com/ee/ci/ + # Environment variables docs: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html + class Gitlab < Extractor + private + + # overridden methods + def provider_name + "gitlab" + end + + def job_name + env["CI_JOB_NAME"] + end + + def job_url + env["CI_JOB_URL"] + end + + def pipeline_id + env["CI_PIPELINE_ID"] + end + + def pipeline_name + env["CI_PROJECT_PATH"] + end + + def pipeline_number + env["CI_PIPELINE_IID"] + end + + def pipeline_url + env["CI_PIPELINE_URL"] + end + + def stage_name + env["CI_JOB_STAGE"] + end + + def workspace_path + env["CI_PROJECT_DIR"] + end + + def node_name + env["CI_RUNNER_ID"] + end + + def node_labels + env["CI_RUNNER_TAGS"] + end + + def git_repository_url + env["CI_REPOSITORY_URL"] + end + + def git_commit_sha + env["CI_COMMIT_SHA"] + end + + def git_branch + env["CI_COMMIT_REF_NAME"] + end + + def git_tag + env["CI_COMMIT_TAG"] + end + + def git_commit_author_name + name, _ = extract_name_email + name + end + + def git_commit_author_email + _, email = extract_name_email + email + end + + def git_commit_author_date + env["CI_COMMIT_TIMESTAMP"] + end + + def git_commit_message + env["CI_COMMIT_MESSAGE"] + end + + def ci_env_vars + { + "CI_PROJECT_URL" => env["CI_PROJECT_URL"], + "CI_PIPELINE_ID" => env["CI_PIPELINE_ID"], + "CI_JOB_ID" => env["CI_JOB_ID"] + }.to_json + end + + # gitlab-specific methods + + def extract_name_email + return @name_email_tuple if defined?(@name_email_tuple) + + name_and_email_string = env["CI_COMMIT_AUTHOR"] + if name_and_email_string.include?("<") && (match = /^([^<]*)<([^>]*)>$/.match(name_and_email_string)) + name = match[1] + name = name.strip if name + email = match[2] + return @name_email_tuple = [name, email] if name && email + end + + @name_email_tuple = [nil, name_and_email_string] + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/gitlab.rbs b/sig/datadog/ci/ext/environment/providers/gitlab.rbs new file mode 100644 index 00000000..b66bba79 --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/gitlab.rbs @@ -0,0 +1,57 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Gitlab < Extractor + private + + @name_email_tuple: [String?, String?] + + def provider_name: () -> "gitlab" + + def job_name: () -> String? + + def job_url: () -> String? + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def stage_name: () -> String? + + def workspace_path: () -> String? + + def node_name: () -> String? + + def node_labels: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_author_date: () -> String? + + def git_commit_message: () -> String? + + def ci_env_vars: () -> String? + + def extract_name_email: () -> [String?, String?] + end + end + end + end + end +end From 7a39ffe18e9f236d3a8cb7db0023759a9320f49f Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 12:19:01 +0200 Subject: [PATCH 12/31] extract Jenkins --- lib/datadog/ci/ext/environment.rb | 30 ------- lib/datadog/ci/ext/environment/extractor.rb | 15 +++- .../ci/ext/environment/providers/jenkins.rb | 90 +++++++++++++++++++ sig/datadog/ci/ext/environment/extractor.rbs | 4 + .../ci/ext/environment/providers/jenkins.rbs | 40 +++++++++ 5 files changed, 148 insertions(+), 31 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/jenkins.rb create mode 100644 sig/datadog/ci/ext/environment/providers/jenkins.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 74951709..2b6b7095 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["JENKINS_URL", :extract_jenkins], ["TEAMCITY_VERSION", :extract_teamcity], ["TRAVIS", :extract_travis], ["BITRISE_BUILD_SLUG", :extract_bitrise], @@ -79,35 +78,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_jenkins(env) - branch, tag = branch_or_tag(env["GIT_BRANCH"]) - - if (name = env["JOB_NAME"]) - name = name.gsub("/#{normalize_ref(branch)}", "") if branch - name = name.split("/").reject { |v| v.nil? || v.include?("=") }.join("/") - end - - node_labels = env["NODE_LABELS"] && env["NODE_LABELS"].split.to_json - - { - Git::TAG_BRANCH => branch, - Git::TAG_COMMIT_SHA => env["GIT_COMMIT"], - Git::TAG_REPOSITORY_URL => env["GIT_URL"] || env["GIT_URL_1"], - Git::TAG_TAG => tag, - TAG_PIPELINE_ID => env["BUILD_TAG"], - TAG_PIPELINE_NAME => name, - TAG_PIPELINE_NUMBER => env["BUILD_NUMBER"], - TAG_PIPELINE_URL => env["BUILD_URL"], - TAG_PROVIDER_NAME => "jenkins", - TAG_WORKSPACE_PATH => env["WORKSPACE"], - TAG_NODE_LABELS => node_labels, - TAG_NODE_NAME => env["NODE_NAME"], - TAG_CI_ENV_VARS => { - "DD_CUSTOM_TRACE_ID" => env["DD_CUSTOM_TRACE_ID"] - }.to_json - } - end - def extract_teamcity(env) { TAG_PROVIDER_NAME => "teamcity", diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index aaba725c..4cc13546 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -20,6 +20,7 @@ class Extractor require_relative "providers/circleci" require_relative "providers/github_actions" require_relative "providers/gitlab" + require_relative "providers/jenkins" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], @@ -29,7 +30,8 @@ class Extractor ["BUILDKITE", Providers::Buildkite], ["CIRCLECI", Providers::Circleci], ["GITHUB_SHA", Providers::GithubActions], - ["GITLAB_CI", Providers::Gitlab] + ["GITLAB_CI", Providers::Gitlab], + ["JENKINS_URL", Providers::Jenkins] ] def self.for_environment(env) @@ -163,6 +165,17 @@ def branch_or_tag(branch_or_tag_string) [@branch, @tag] end + + def normalize_ref(name) + refs = %r{^refs/(heads/)?} + origin = %r{^origin/} + tags = %r{^tags/} + name.gsub(refs, "").gsub(origin, "").gsub(tags, "") unless name.nil? + end + + def filter_sensitive_info(url) + url.gsub(%r{(https?://)[^/]*@}, '\1') unless url.nil? + end end end end diff --git a/lib/datadog/ci/ext/environment/providers/jenkins.rb b/lib/datadog/ci/ext/environment/providers/jenkins.rb new file mode 100644 index 00000000..856014ff --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/jenkins.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Jenkins: https://www.jenkins.io/ + # Environment variables docs: https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables + class Jenkins < Extractor + private + + # overridden methods + def provider_name + "jenkins" + end + + def pipeline_id + env["BUILD_TAG"] + end + + def pipeline_name + if (name = env["JOB_NAME"]) + name = name.gsub("/#{normalize_ref(git_branch)}", "") if git_branch + name = name.split("/").reject { |v| v.nil? || v.include?("=") }.join("/") + end + name + end + + def pipeline_number + env["BUILD_NUMBER"] + end + + def pipeline_url + env["BUILD_URL"] + end + + def workspace_path + env["WORKSPACE"] + end + + def node_name + env["NODE_NAME"] + end + + def node_labels + env["NODE_LABELS"] && env["NODE_LABELS"].split.to_json + end + + def git_repository_url + env["GIT_URL"] || env["GIT_URL_1"] + end + + def git_commit_sha + env["GIT_COMMIT"] + end + + def git_branch + return @branch if defined?(@branch) + + set_branch_and_tag + @branch + end + + def git_tag + return @tag if defined?(@tag) + + set_branch_and_tag + @tag + end + + def ci_env_vars + { + "DD_CUSTOM_TRACE_ID" => env["DD_CUSTOM_TRACE_ID"] + }.to_json + end + + # jenkins-specific methods + + def set_branch_and_tag + @branch, @tag = branch_or_tag(env["GIT_BRANCH"]) + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index 660e6b1b..b79fd1c2 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -65,6 +65,10 @@ module Datadog def git_commit_sha: () -> nil def branch_or_tag: (String? branch_or_tag_string) -> [String?, String?] + + def normalize_ref: (String? name) -> String? + + def filter_sensitive_info: (String? url) -> String? end end end diff --git a/sig/datadog/ci/ext/environment/providers/jenkins.rbs b/sig/datadog/ci/ext/environment/providers/jenkins.rbs new file mode 100644 index 00000000..605605e3 --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/jenkins.rbs @@ -0,0 +1,40 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Jenkins < Extractor + private + def provider_name: () -> "jenkins" + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def workspace_path: () -> String? + + def node_name: () -> String? + + def node_labels: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def ci_env_vars: () -> String? + + def set_branch_and_tag: () -> [String?, String?] + end + end + end + end + end +end From 67ca5fc9e152e9e7ac7d9fb44a907576e3ba8c44 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 12:24:57 +0200 Subject: [PATCH 13/31] extract teamcity --- lib/datadog/ci/ext/environment.rb | 1 - lib/datadog/ci/ext/environment/extractor.rb | 6 ++-- .../ci/ext/environment/providers/teamcity.rb | 32 +++++++++++++++++++ .../ci/ext/environment/providers/teamcity.rbs | 18 +++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/teamcity.rb create mode 100644 sig/datadog/ci/ext/environment/providers/teamcity.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 2b6b7095..a2413909 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["TEAMCITY_VERSION", :extract_teamcity], ["TRAVIS", :extract_travis], ["BITRISE_BUILD_SLUG", :extract_bitrise], ["CF_BUILD_ID", :extract_codefresh] diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 4cc13546..216bc402 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -21,6 +21,7 @@ class Extractor require_relative "providers/github_actions" require_relative "providers/gitlab" require_relative "providers/jenkins" + require_relative "providers/teamcity" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], @@ -31,7 +32,8 @@ class Extractor ["CIRCLECI", Providers::Circleci], ["GITHUB_SHA", Providers::GithubActions], ["GITLAB_CI", Providers::Gitlab], - ["JENKINS_URL", Providers::Jenkins] + ["JENKINS_URL", Providers::Jenkins], + ["TEAMCITY_VERSION", Providers::Teamcity] ] def self.for_environment(env) @@ -124,7 +126,6 @@ def git_branch end def git_repository_url - raise NoMethodError.new("This method must be overridden") end def git_tag @@ -152,7 +153,6 @@ def git_commit_message end def git_commit_sha - raise NoMethodError.new("This method must be overridden") end def branch_or_tag(branch_or_tag_string) diff --git a/lib/datadog/ci/ext/environment/providers/teamcity.rb b/lib/datadog/ci/ext/environment/providers/teamcity.rb new file mode 100644 index 00000000..80143942 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/teamcity.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Teamcity: https://www.jetbrains.com/teamcity/ + # Environment variables docs: https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html + class Teamcity < Extractor + private + + # overridden methods + def provider_name + "teamcity" + end + + def job_name + env["TEAMCITY_BUILDCONF_NAME"] + end + + def job_url + env["BUILD_URL"] + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/teamcity.rbs b/sig/datadog/ci/ext/environment/providers/teamcity.rbs new file mode 100644 index 00000000..6b4e841f --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/teamcity.rbs @@ -0,0 +1,18 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Teamcity < Extractor + private + def provider_name: () -> "teamcity" + + def job_name: () -> String? + + def job_url: () -> String? + end + end + end + end + end +end From 3b898c117aea0e979dbd7252d6804dd642565581 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 12:33:54 +0200 Subject: [PATCH 14/31] extract travis --- lib/datadog/ci/ext/environment.rb | 26 ------- lib/datadog/ci/ext/environment/extractor.rb | 4 +- .../ci/ext/environment/providers/travis.rb | 68 +++++++++++++++++++ .../ci/ext/environment/providers/travis.rbs | 36 ++++++++++ 4 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/travis.rb create mode 100644 sig/datadog/ci/ext/environment/providers/travis.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index a2413909..0017f832 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["TRAVIS", :extract_travis], ["BITRISE_BUILD_SLUG", :extract_bitrise], ["CF_BUILD_ID", :extract_codefresh] ].freeze @@ -77,31 +76,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_teamcity(env) - { - TAG_PROVIDER_NAME => "teamcity", - TAG_JOB_NAME => env["TEAMCITY_BUILDCONF_NAME"], - TAG_JOB_URL => env["BUILD_URL"] - } - end - - def extract_travis(env) - { - Git::TAG_BRANCH => (env["TRAVIS_PULL_REQUEST_BRANCH"] || env["TRAVIS_BRANCH"]), - Git::TAG_COMMIT_SHA => env["TRAVIS_COMMIT"], - Git::TAG_REPOSITORY_URL => "https://github.com/#{env["TRAVIS_REPO_SLUG"]}.git", - Git::TAG_TAG => env["TRAVIS_TAG"], - TAG_JOB_URL => env["TRAVIS_JOB_WEB_URL"], - TAG_PIPELINE_ID => env["TRAVIS_BUILD_ID"], - TAG_PIPELINE_NAME => env["TRAVIS_REPO_SLUG"], - TAG_PIPELINE_NUMBER => env["TRAVIS_BUILD_NUMBER"], - TAG_PIPELINE_URL => env["TRAVIS_BUILD_WEB_URL"], - TAG_PROVIDER_NAME => "travisci", - TAG_WORKSPACE_PATH => env["TRAVIS_BUILD_DIR"], - Git::TAG_COMMIT_MESSAGE => env["TRAVIS_COMMIT_MESSAGE"] - } - end - def extract_bitrise(env) commit = ( env["BITRISE_GIT_COMMIT"] || env["GIT_CLONE_COMMIT_HASH"] diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 216bc402..03648026 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -22,6 +22,7 @@ class Extractor require_relative "providers/gitlab" require_relative "providers/jenkins" require_relative "providers/teamcity" + require_relative "providers/travis" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], @@ -33,7 +34,8 @@ class Extractor ["GITHUB_SHA", Providers::GithubActions], ["GITLAB_CI", Providers::Gitlab], ["JENKINS_URL", Providers::Jenkins], - ["TEAMCITY_VERSION", Providers::Teamcity] + ["TEAMCITY_VERSION", Providers::Teamcity], + ["TRAVIS", Providers::Travis] ] def self.for_environment(env) diff --git a/lib/datadog/ci/ext/environment/providers/travis.rb b/lib/datadog/ci/ext/environment/providers/travis.rb new file mode 100644 index 00000000..4196e215 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/travis.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Travis CI: https://www.travis-ci.com/ + # Environment variables docs: https://docs.travis-ci.com/user/environment-variables#default-environment-variables + class Travis < Extractor + private + + # overridden methods + def provider_name + "travisci" + end + + def job_url + env["TRAVIS_JOB_WEB_URL"] + end + + def pipeline_id + env["TRAVIS_BUILD_ID"] + end + + def pipeline_name + env["TRAVIS_REPO_SLUG"] + end + + def pipeline_number + env["TRAVIS_BUILD_NUMBER"] + end + + def pipeline_url + env["TRAVIS_BUILD_WEB_URL"] + end + + def workspace_path + env["TRAVIS_BUILD_DIR"] + end + + def git_repository_url + "https://github.com/#{env["TRAVIS_REPO_SLUG"]}.git" + end + + def git_commit_sha + env["TRAVIS_COMMIT"] + end + + def git_branch + env["TRAVIS_PULL_REQUEST_BRANCH"] || env["TRAVIS_BRANCH"] + end + + def git_tag + env["TRAVIS_TAG"] + end + + def git_commit_message + env["TRAVIS_COMMIT_MESSAGE"] + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/travis.rbs b/sig/datadog/ci/ext/environment/providers/travis.rbs new file mode 100644 index 00000000..7cfc16ae --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/travis.rbs @@ -0,0 +1,36 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Travis < Extractor + private + def provider_name: () -> "travisci" + + def job_url: () -> String? + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def workspace_path: () -> String? + + def git_repository_url: () -> ::String + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_message: () -> String? + end + end + end + end + end +end From ca3b200d5f644b86bbabea1eced70664ae99c7c4 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 12:41:23 +0200 Subject: [PATCH 15/31] extract bitrise --- lib/datadog/ci/ext/environment.rb | 31 ------- lib/datadog/ci/ext/environment/extractor.rb | 4 +- .../ci/ext/environment/providers/bitrise.rb | 80 +++++++++++++++++++ .../ci/ext/environment/providers/bitrise.rbs | 42 ++++++++++ 4 files changed, 125 insertions(+), 32 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/bitrise.rb create mode 100644 sig/datadog/ci/ext/environment/providers/bitrise.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 0017f832..ee7bca6c 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -25,7 +25,6 @@ module Environment TAG_CI_ENV_VARS = "_dd.ci.env_vars" PROVIDERS = [ - ["BITRISE_BUILD_SLUG", :extract_bitrise], ["CF_BUILD_ID", :extract_codefresh] ].freeze @@ -76,36 +75,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_bitrise(env) - commit = ( - env["BITRISE_GIT_COMMIT"] || env["GIT_CLONE_COMMIT_HASH"] - ) - branch = ( - env["BITRISEIO_GIT_BRANCH_DEST"] || env["BITRISE_GIT_BRANCH"] - ) - commiter_email = ( - env["GIT_CLONE_COMMIT_COMMITER_EMAIL"] || env["GIT_CLONE_COMMIT_COMMITER_NAME"] - ) - - { - TAG_PROVIDER_NAME => "bitrise", - TAG_PIPELINE_ID => env["BITRISE_BUILD_SLUG"], - TAG_PIPELINE_NAME => env["BITRISE_TRIGGERED_WORKFLOW_ID"], - TAG_PIPELINE_NUMBER => env["BITRISE_BUILD_NUMBER"], - TAG_PIPELINE_URL => env["BITRISE_BUILD_URL"], - TAG_WORKSPACE_PATH => env["BITRISE_SOURCE_DIR"], - Git::TAG_REPOSITORY_URL => env["GIT_REPOSITORY_URL"], - Git::TAG_COMMIT_SHA => commit, - Git::TAG_BRANCH => branch, - Git::TAG_TAG => env["BITRISE_GIT_TAG"], - Git::TAG_COMMIT_MESSAGE => env["BITRISE_GIT_MESSAGE"], - Git::TAG_COMMIT_AUTHOR_NAME => env["GIT_CLONE_COMMIT_AUTHOR_NAME"], - Git::TAG_COMMIT_AUTHOR_EMAIL => env["GIT_CLONE_COMMIT_AUTHOR_EMAIL"], - Git::TAG_COMMIT_COMMITTER_NAME => env["GIT_CLONE_COMMIT_COMMITER_NAME"], - Git::TAG_COMMIT_COMMITTER_EMAIL => commiter_email - } - end - def extract_codefresh(env) branch, tag = branch_or_tag(env["CF_BRANCH"]) diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 03648026..8cf05459 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -23,6 +23,7 @@ class Extractor require_relative "providers/jenkins" require_relative "providers/teamcity" require_relative "providers/travis" + require_relative "providers/bitrise" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], @@ -35,7 +36,8 @@ class Extractor ["GITLAB_CI", Providers::Gitlab], ["JENKINS_URL", Providers::Jenkins], ["TEAMCITY_VERSION", Providers::Teamcity], - ["TRAVIS", Providers::Travis] + ["TRAVIS", Providers::Travis], + ["BITRISE_BUILD_SLUG", Providers::Bitrise] ] def self.for_environment(env) diff --git a/lib/datadog/ci/ext/environment/providers/bitrise.rb b/lib/datadog/ci/ext/environment/providers/bitrise.rb new file mode 100644 index 00000000..5bdba80f --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/bitrise.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Bitrise: https://bitrise.io/ + # Environment variables docs: https://devcenter.bitrise.io/en/references/available-environment-variables.html + class Bitrise < Extractor + private + + # overridden methods + def provider_name + "bitrise" + end + + def pipeline_id + env["BITRISE_BUILD_SLUG"] + end + + def pipeline_name + env["BITRISE_TRIGGERED_WORKFLOW_ID"] + end + + def pipeline_number + env["BITRISE_BUILD_NUMBER"] + end + + def pipeline_url + env["BITRISE_BUILD_URL"] + end + + def workspace_path + env["BITRISE_SOURCE_DIR"] + end + + def git_repository_url + env["GIT_REPOSITORY_URL"] + end + + def git_commit_sha + env["BITRISE_GIT_COMMIT"] || env["GIT_CLONE_COMMIT_HASH"] + end + + def git_branch + env["BITRISEIO_GIT_BRANCH_DEST"] || env["BITRISE_GIT_BRANCH"] + end + + def git_tag + env["BITRISE_GIT_TAG"] + end + + def git_commit_message + env["BITRISE_GIT_MESSAGE"] + end + + def git_commit_author_name + env["GIT_CLONE_COMMIT_AUTHOR_NAME"] + end + + def git_commit_author_email + env["GIT_CLONE_COMMIT_AUTHOR_EMAIL"] + end + + def git_commit_committer_name + env["GIT_CLONE_COMMIT_COMMITER_NAME"] + end + + def git_commit_committer_email + env["GIT_CLONE_COMMIT_COMMITER_EMAIL"] || env["GIT_CLONE_COMMIT_COMMITER_NAME"] + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/bitrise.rbs b/sig/datadog/ci/ext/environment/providers/bitrise.rbs new file mode 100644 index 00000000..0e718107 --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/bitrise.rbs @@ -0,0 +1,42 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Bitrise < Extractor + private + def provider_name: () -> "bitrise" + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_number: () -> String? + + def pipeline_url: () -> String? + + def workspace_path: () -> String? + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_message: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_committer_name: () -> String? + + def git_commit_committer_email: () -> String? + end + end + end + end + end +end From c7a2845c10eb29a65a2687e54786eaab75313648 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 13:27:39 +0200 Subject: [PATCH 16/31] extract codefresh --- lib/datadog/ci/ext/environment.rb | 24 +------ lib/datadog/ci/ext/environment/extractor.rb | 11 +++- .../ci/ext/environment/providers/codefresh.rb | 65 +++++++++++++++++++ sig/datadog/ci/ext/environment/extractor.rbs | 2 + .../ext/environment/providers/codefresh.rbs | 30 +++++++++ 5 files changed, 106 insertions(+), 26 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers/codefresh.rb create mode 100644 sig/datadog/ci/ext/environment/providers/codefresh.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index ee7bca6c..391d7a27 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -24,16 +24,11 @@ module Environment TAG_NODE_NAME = "ci.node.name" TAG_CI_ENV_VARS = "_dd.ci.env_vars" - PROVIDERS = [ - ["CF_BUILD_ID", :extract_codefresh] - ].freeze - module_function def tags(env) # Extract metadata from CI provider environment variables - _, extractor = PROVIDERS.find { |provider_env_var, _| env.key?(provider_env_var) } - tags = extractor ? public_send(extractor, env).reject { |_, v| v.nil? || v.strip.empty? } : Environment::Extractor.for_environment(env).tags + tags = Environment::Extractor.for_environment(env).tags # If user defined metadata is defined, overwrite tags.merge!(extract_user_defined_git(env)) @@ -75,23 +70,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_codefresh(env) - branch, tag = branch_or_tag(env["CF_BRANCH"]) - - { - TAG_PROVIDER_NAME => "codefresh", - TAG_PIPELINE_ID => env["CF_BUILD_ID"], - TAG_PIPELINE_NAME => env["CF_PIPELINE_NAME"], - TAG_PIPELINE_URL => env["CF_BUILD_URL"], - TAG_JOB_NAME => env["CF_STEP_NAME"], - Git::TAG_BRANCH => branch, - Git::TAG_TAG => tag, - TAG_CI_ENV_VARS => { - "CF_BUILD_ID" => env["CF_BUILD_ID"] - }.to_json - } - end - def extract_user_defined_git(env) { Git::TAG_REPOSITORY_URL => env[Git::ENV_REPOSITORY_URL], diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 8cf05459..4ae87489 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -15,29 +15,31 @@ class Extractor require_relative "providers/appveyor" require_relative "providers/azure" require_relative "providers/bitbucket" + require_relative "providers/bitrise" require_relative "providers/buddy" require_relative "providers/buildkite" require_relative "providers/circleci" + require_relative "providers/codefresh" require_relative "providers/github_actions" require_relative "providers/gitlab" require_relative "providers/jenkins" require_relative "providers/teamcity" require_relative "providers/travis" - require_relative "providers/bitrise" PROVIDERS = [ ["APPVEYOR", Providers::Appveyor], ["TF_BUILD", Providers::Azure], ["BITBUCKET_COMMIT", Providers::Bitbucket], + ["BITRISE_BUILD_SLUG", Providers::Bitrise], ["BUDDY", Providers::Buddy], ["BUILDKITE", Providers::Buildkite], ["CIRCLECI", Providers::Circleci], + ["CF_BUILD_ID", Providers::Codefresh], ["GITHUB_SHA", Providers::GithubActions], ["GITLAB_CI", Providers::Gitlab], ["JENKINS_URL", Providers::Jenkins], ["TEAMCITY_VERSION", Providers::Teamcity], - ["TRAVIS", Providers::Travis], - ["BITRISE_BUILD_SLUG", Providers::Bitrise] + ["TRAVIS", Providers::Travis] ] def self.for_environment(env) @@ -135,6 +137,9 @@ def git_repository_url def git_tag end + def git_branch_or_tag + end + def git_commit_author_date end diff --git a/lib/datadog/ci/ext/environment/providers/codefresh.rb b/lib/datadog/ci/ext/environment/providers/codefresh.rb new file mode 100644 index 00000000..0f08ab81 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/codefresh.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require_relative "../extractor" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Codefresh: https://codefresh.io/ + # Environment variables docs: https://codefresh.io/docs/docs/pipelines/variables/#export-variables-to-all-steps-with-cf_export + class Codefresh < Extractor + private + + # overridden methods + def provider_name + "codefresh" + end + + def job_name + env["CF_STEP_NAME"] + end + + def pipeline_id + env["CF_BUILD_ID"] + end + + def pipeline_name + env["CF_PIPELINE_NAME"] + end + + def pipeline_url + env["CF_BUILD_URL"] + end + + def git_branch + return @branch if defined?(@branch) + + set_branch_and_tag + @branch + end + + def git_tag + return @tag if defined?(@tag) + + set_branch_and_tag + @tag + end + + def ci_env_vars + { + "CF_BUILD_ID" => env["CF_BUILD_ID"] + }.to_json + end + + # codefresh-specific methods + def set_branch_and_tag + @branch, @tag = branch_or_tag(env["CF_BRANCH"]) + end + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index b79fd1c2..9a48dd5a 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -48,6 +48,8 @@ module Datadog def git_tag: () -> nil + def git_branch_or_tag: () -> nil + def git_commit_author_date: () -> nil def git_commit_author_email: () -> nil diff --git a/sig/datadog/ci/ext/environment/providers/codefresh.rbs b/sig/datadog/ci/ext/environment/providers/codefresh.rbs new file mode 100644 index 00000000..153c591e --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/codefresh.rbs @@ -0,0 +1,30 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Codefresh < Extractor + private + def provider_name: () -> "codefresh" + + def job_name: () -> String? + + def pipeline_id: () -> String? + + def pipeline_name: () -> String? + + def pipeline_url: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def ci_env_vars: () -> String + + def set_branch_and_tag: () -> [String?, String?] + end + end + end + end + end +end From d2a10350a7c4390228527091e4dbf05569b5af2e Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 13:33:17 +0200 Subject: [PATCH 17/31] pull up branch or tag logic for extractors --- lib/datadog/ci/ext/environment/extractor.rb | 11 ++++++- .../ci/ext/environment/providers/azure.rb | 20 ++----------- .../ci/ext/environment/providers/codefresh.rb | 19 ++---------- .../environment/providers/github_actions.rb | 30 +++---------------- .../ci/ext/environment/providers/jenkins.rb | 20 ++----------- sig/datadog/ci/ext/environment/extractor.rbs | 2 +- .../ci/ext/environment/providers/azure.rbs | 6 +--- .../ext/environment/providers/codefresh.rbs | 6 +--- .../environment/providers/github_actions.rbs | 8 +---- .../ci/ext/environment/providers/jenkins.rbs | 6 +--- 10 files changed, 25 insertions(+), 103 deletions(-) diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 4ae87489..8b92e486 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -129,12 +129,20 @@ def ci_env_vars end def git_branch + return @branch if defined?(@branch) + + set_branch_and_tag + @branch end def git_repository_url end def git_tag + return @tag if defined?(@tag) + + set_branch_and_tag + @tag end def git_branch_or_tag @@ -164,7 +172,8 @@ def git_commit_message def git_commit_sha end - def branch_or_tag(branch_or_tag_string) + def set_branch_and_tag + branch_or_tag_string = git_branch_or_tag @branch = @tag = nil if branch_or_tag_string && branch_or_tag_string.include?("tags/") @tag = branch_or_tag_string diff --git a/lib/datadog/ci/ext/environment/providers/azure.rb b/lib/datadog/ci/ext/environment/providers/azure.rb index 38c83d9c..126f7619 100644 --- a/lib/datadog/ci/ext/environment/providers/azure.rb +++ b/lib/datadog/ci/ext/environment/providers/azure.rb @@ -61,18 +61,8 @@ def git_commit_sha env["SYSTEM_PULLREQUEST_SOURCECOMMITID"] || env["BUILD_SOURCEVERSION"] end - def git_branch - return @branch if defined?(@branch) - - set_branch_and_tag - @branch - end - - def git_tag - return @tag if defined?(@tag) - - set_branch_and_tag - @tag + def git_branch_or_tag + env["SYSTEM_PULLREQUEST_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCHNAME"] end def git_commit_author_name @@ -112,12 +102,6 @@ def team_project_id def url_defined? !(build_id && team_foundation_server_uri && team_project_id).nil? end - - def set_branch_and_tag - @branch, @tag = branch_or_tag( - env["SYSTEM_PULLREQUEST_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCH"] || env["BUILD_SOURCEBRANCHNAME"] - ) - end end end end diff --git a/lib/datadog/ci/ext/environment/providers/codefresh.rb b/lib/datadog/ci/ext/environment/providers/codefresh.rb index 0f08ab81..a48ce061 100644 --- a/lib/datadog/ci/ext/environment/providers/codefresh.rb +++ b/lib/datadog/ci/ext/environment/providers/codefresh.rb @@ -33,18 +33,8 @@ def pipeline_url env["CF_BUILD_URL"] end - def git_branch - return @branch if defined?(@branch) - - set_branch_and_tag - @branch - end - - def git_tag - return @tag if defined?(@tag) - - set_branch_and_tag - @tag + def git_branch_or_tag + env["CF_BRANCH"] end def ci_env_vars @@ -52,11 +42,6 @@ def ci_env_vars "CF_BUILD_ID" => env["CF_BUILD_ID"] }.to_json end - - # codefresh-specific methods - def set_branch_and_tag - @branch, @tag = branch_or_tag(env["CF_BRANCH"]) - end end end end diff --git a/lib/datadog/ci/ext/environment/providers/github_actions.rb b/lib/datadog/ci/ext/environment/providers/github_actions.rb index 730f4635..6bd30562 100644 --- a/lib/datadog/ci/ext/environment/providers/github_actions.rb +++ b/lib/datadog/ci/ext/environment/providers/github_actions.rb @@ -55,18 +55,10 @@ def git_commit_sha env["GITHUB_SHA"] end - def git_branch - return @branch if defined?(@branch) - - set_branch_and_tag - @branch - end - - def git_tag - return @tag if defined?(@tag) - - set_branch_and_tag - @tag + def git_branch_or_tag + ref = env["GITHUB_HEAD_REF"] + ref = env["GITHUB_REF"] if ref.nil? || ref.empty? + ref end def ci_env_vars @@ -77,20 +69,6 @@ def ci_env_vars "GITHUB_RUN_ATTEMPT" => env["GITHUB_RUN_ATTEMPT"] }.reject { |_, v| v.nil? }.to_json end - - # github-specific methods - - def ref - return @ref if defined?(@ref) - - @ref = env["GITHUB_HEAD_REF"] - @ref = env["GITHUB_REF"] if @ref.nil? || @ref.empty? - @ref - end - - def set_branch_and_tag - @branch, @tag = branch_or_tag(ref) - end end end end diff --git a/lib/datadog/ci/ext/environment/providers/jenkins.rb b/lib/datadog/ci/ext/environment/providers/jenkins.rb index 856014ff..f6f65dad 100644 --- a/lib/datadog/ci/ext/environment/providers/jenkins.rb +++ b/lib/datadog/ci/ext/environment/providers/jenkins.rb @@ -57,18 +57,8 @@ def git_commit_sha env["GIT_COMMIT"] end - def git_branch - return @branch if defined?(@branch) - - set_branch_and_tag - @branch - end - - def git_tag - return @tag if defined?(@tag) - - set_branch_and_tag - @tag + def git_branch_or_tag + env["GIT_BRANCH"] end def ci_env_vars @@ -76,12 +66,6 @@ def ci_env_vars "DD_CUSTOM_TRACE_ID" => env["DD_CUSTOM_TRACE_ID"] }.to_json end - - # jenkins-specific methods - - def set_branch_and_tag - @branch, @tag = branch_or_tag(env["GIT_BRANCH"]) - end end end end diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index 9a48dd5a..fbb2991c 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -66,7 +66,7 @@ module Datadog def git_commit_sha: () -> nil - def branch_or_tag: (String? branch_or_tag_string) -> [String?, String?] + def set_branch_and_tag: () -> [String?, String?] def normalize_ref: (String? name) -> String? diff --git a/sig/datadog/ci/ext/environment/providers/azure.rbs b/sig/datadog/ci/ext/environment/providers/azure.rbs index 3b89b88a..847b1d73 100644 --- a/sig/datadog/ci/ext/environment/providers/azure.rbs +++ b/sig/datadog/ci/ext/environment/providers/azure.rbs @@ -31,9 +31,7 @@ module Datadog def git_commit_sha: () -> String? - def git_branch: () -> String? - - def git_tag: () -> String? + def git_branch_or_tag: () -> String? def git_commit_author_name: () -> String? @@ -50,8 +48,6 @@ module Datadog def team_project_id: () -> String? def url_defined?: () -> bool - - def set_branch_and_tag: () -> [String?, String?] end end end diff --git a/sig/datadog/ci/ext/environment/providers/codefresh.rbs b/sig/datadog/ci/ext/environment/providers/codefresh.rbs index 153c591e..d690632b 100644 --- a/sig/datadog/ci/ext/environment/providers/codefresh.rbs +++ b/sig/datadog/ci/ext/environment/providers/codefresh.rbs @@ -15,13 +15,9 @@ module Datadog def pipeline_url: () -> String? - def git_branch: () -> String? - - def git_tag: () -> String? + def git_branch_or_tag: () -> String? def ci_env_vars: () -> String - - def set_branch_and_tag: () -> [String?, String?] end end end diff --git a/sig/datadog/ci/ext/environment/providers/github_actions.rbs b/sig/datadog/ci/ext/environment/providers/github_actions.rbs index 4303a27a..2e0b3094 100644 --- a/sig/datadog/ci/ext/environment/providers/github_actions.rbs +++ b/sig/datadog/ci/ext/environment/providers/github_actions.rbs @@ -27,15 +27,9 @@ module Datadog def git_commit_sha: () -> String? - def git_branch: () -> String? - - def git_tag: () -> String? + def git_branch_or_tag: () -> String? def ci_env_vars: () -> String? - - def ref: () -> String - - def set_branch_and_tag: () -> [String?, String?] end end end diff --git a/sig/datadog/ci/ext/environment/providers/jenkins.rbs b/sig/datadog/ci/ext/environment/providers/jenkins.rbs index 605605e3..2451f224 100644 --- a/sig/datadog/ci/ext/environment/providers/jenkins.rbs +++ b/sig/datadog/ci/ext/environment/providers/jenkins.rbs @@ -25,13 +25,9 @@ module Datadog def git_commit_sha: () -> String? - def git_branch: () -> String? - - def git_tag: () -> String? + def git_branch_or_tag: () -> String? def ci_env_vars: () -> String? - - def set_branch_and_tag: () -> [String?, String?] end end end From f3be0865557a3bc675986102d9328ecfa2702b25 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 13:40:16 +0200 Subject: [PATCH 18/31] extract user defined tags extractor --- lib/datadog/ci/ext/environment.rb | 21 ++----- .../ci/ext/environment/user_defined_tags.rb | 60 +++++++++++++++++++ sig/datadog/ci/ext/environment/extractor.rbs | 48 +++++++-------- .../ci/ext/environment/user_defined_tags.rbs | 31 ++++++++++ 4 files changed, 119 insertions(+), 41 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/user_defined_tags.rb create mode 100644 sig/datadog/ci/ext/environment/user_defined_tags.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 391d7a27..c0ec3911 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -5,6 +5,7 @@ require_relative "git" require_relative "environment/extractor" +require_relative "environment/user_defined_tags" module Datadog module CI @@ -31,7 +32,9 @@ def tags(env) tags = Environment::Extractor.for_environment(env).tags # If user defined metadata is defined, overwrite - tags.merge!(extract_user_defined_git(env)) + tags.merge!( + UserDefinedTags.new(env).tags + ) # Normalize Git references if !tags[Git::TAG_BRANCH].nil? && tags[Git::TAG_BRANCH].include?("tags/") @@ -70,22 +73,6 @@ def filter_sensitive_info(url) end # CI providers - def extract_user_defined_git(env) - { - Git::TAG_REPOSITORY_URL => env[Git::ENV_REPOSITORY_URL], - Git::TAG_COMMIT_SHA => env[Git::ENV_COMMIT_SHA], - Git::TAG_BRANCH => env[Git::ENV_BRANCH], - Git::TAG_TAG => env[Git::ENV_TAG], - Git::TAG_COMMIT_MESSAGE => env[Git::ENV_COMMIT_MESSAGE], - Git::TAG_COMMIT_AUTHOR_NAME => env[Git::ENV_COMMIT_AUTHOR_NAME], - Git::TAG_COMMIT_AUTHOR_EMAIL => env[Git::ENV_COMMIT_AUTHOR_EMAIL], - Git::TAG_COMMIT_AUTHOR_DATE => env[Git::ENV_COMMIT_AUTHOR_DATE], - Git::TAG_COMMIT_COMMITTER_NAME => env[Git::ENV_COMMIT_COMMITTER_NAME], - Git::TAG_COMMIT_COMMITTER_EMAIL => env[Git::ENV_COMMIT_COMMITTER_EMAIL], - Git::TAG_COMMIT_COMMITTER_DATE => env[Git::ENV_COMMIT_COMMITTER_DATE] - }.reject { |_, v| v.nil? || v.strip.empty? } - end - def git_commit_users # Get committer and author information in one command. output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'") diff --git a/lib/datadog/ci/ext/environment/user_defined_tags.rb b/lib/datadog/ci/ext/environment/user_defined_tags.rb new file mode 100644 index 00000000..0792c69d --- /dev/null +++ b/lib/datadog/ci/ext/environment/user_defined_tags.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require_relative "extractor" +require_relative "../git" + +module Datadog + module CI + module Ext + module Environment + # Parses user defined git data from the environment variables + # User documentation: https://docs.datadoghq.com/continuous_integration/troubleshooting/#data-appears-in-test-runs-but-not-tests + class UserDefinedTags < Extractor + def git_repository_url + env[Git::ENV_REPOSITORY_URL] + end + + def git_commit_sha + env[Git::ENV_COMMIT_SHA] + end + + def git_branch + env[Git::ENV_BRANCH] + end + + def git_tag + env[Git::ENV_TAG] + end + + def git_commit_message + env[Git::ENV_COMMIT_MESSAGE] + end + + def git_commit_author_name + env[Git::ENV_COMMIT_AUTHOR_NAME] + end + + def git_commit_author_email + env[Git::ENV_COMMIT_AUTHOR_EMAIL] + end + + def git_commit_author_date + env[Git::ENV_COMMIT_AUTHOR_DATE] + end + + def git_commit_committer_name + env[Git::ENV_COMMIT_COMMITTER_NAME] + end + + def git_commit_committer_email + env[Git::ENV_COMMIT_COMMITTER_EMAIL] + end + + def git_commit_committer_date + env[Git::ENV_COMMIT_COMMITTER_DATE] + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index fbb2991c..dd91a156 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -18,53 +18,53 @@ module Datadog attr_reader env: untyped - def job_name: () -> nil + def job_name: () -> String? - def job_url: () -> nil + def job_url: () -> String? - def pipeline_id: () -> nil + def pipeline_id: () -> String? - def pipeline_name: () -> nil + def pipeline_name: () -> String? - def pipeline_number: () -> nil + def pipeline_number: () -> String? - def pipeline_url: () -> nil + def pipeline_url: () -> String? - def provider_name: () -> nil + def provider_name: () -> String? - def stage_name: () -> nil + def stage_name: () -> String? - def workspace_path: () -> nil + def workspace_path: () -> String? - def node_labels: () -> nil + def node_labels: () -> String? - def node_name: () -> nil + def node_name: () -> String? - def ci_env_vars: () -> nil + def ci_env_vars: () -> String? - def git_branch: () -> nil + def git_branch: () -> String? - def git_repository_url: () -> nil + def git_repository_url: () -> String? - def git_tag: () -> nil + def git_tag: () -> String? - def git_branch_or_tag: () -> nil + def git_branch_or_tag: () -> String? - def git_commit_author_date: () -> nil + def git_commit_author_date: () -> String? - def git_commit_author_email: () -> nil + def git_commit_author_email: () -> String? - def git_commit_author_name: () -> nil + def git_commit_author_name: () -> String? - def git_commit_committer_date: () -> nil + def git_commit_committer_date: () -> String? - def git_commit_committer_email: () -> nil + def git_commit_committer_email: () -> String? - def git_commit_committer_name: () -> nil + def git_commit_committer_name: () -> String? - def git_commit_message: () -> nil + def git_commit_message: () -> String? - def git_commit_sha: () -> nil + def git_commit_sha: () -> String? def set_branch_and_tag: () -> [String?, String?] diff --git a/sig/datadog/ci/ext/environment/user_defined_tags.rbs b/sig/datadog/ci/ext/environment/user_defined_tags.rbs new file mode 100644 index 00000000..ed2a2bf1 --- /dev/null +++ b/sig/datadog/ci/ext/environment/user_defined_tags.rbs @@ -0,0 +1,31 @@ +module Datadog + module CI + module Ext + module Environment + class UserDefinedTags < Extractor + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_message: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_author_date: () -> String? + + def git_commit_committer_name: () -> String? + + def git_commit_committer_email: () -> String? + + def git_commit_committer_date: () -> String? + end + end + end + end +end From fd3ed195dc11fc965ed640c382b3cd3072f27f8b Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 14:07:06 +0200 Subject: [PATCH 19/31] Extract local git extractor and move normalization into extractor --- lib/datadog/ci/ext/environment.rb | 165 +----------------- lib/datadog/ci/ext/environment/extractor.rb | 41 ++++- lib/datadog/ci/ext/environment/local_git.rb | 143 +++++++++++++++ .../ci/ext/environment/providers/azure.rb | 2 + .../ci/ext/environment/providers/buildkite.rb | 2 + .../ci/ext/environment/providers/circleci.rb | 2 + .../ci/ext/environment/providers/codefresh.rb | 2 + .../environment/providers/github_actions.rb | 2 + .../ci/ext/environment/providers/jenkins.rb | 2 + .../ci/ext/environment/user_defined_tags.rb | 2 + sig/datadog/ci/ext/environment/extractor.rbs | 4 + sig/datadog/ci/ext/environment/local_git.rbs | 41 +++++ 12 files changed, 244 insertions(+), 164 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/local_git.rb create mode 100644 sig/datadog/ci/ext/environment/local_git.rbs diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index c0ec3911..b7f57a4f 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -1,11 +1,9 @@ # frozen_string_literal: true -require "open3" -require "json" - require_relative "git" require_relative "environment/extractor" require_relative "environment/user_defined_tags" +require_relative "environment/local_git" module Datadog module CI @@ -36,168 +34,13 @@ def tags(env) UserDefinedTags.new(env).tags ) - # Normalize Git references - if !tags[Git::TAG_BRANCH].nil? && tags[Git::TAG_BRANCH].include?("tags/") - tags[Git::TAG_TAG] = tags[Git::TAG_BRANCH] - tags.delete(Git::TAG_BRANCH) - end - tags[Git::TAG_TAG] = normalize_ref(tags[Git::TAG_TAG]) - tags[Git::TAG_BRANCH] = normalize_ref(tags[Git::TAG_BRANCH]) - tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info( - tags[Git::TAG_REPOSITORY_URL] - ) - - # Expand ~ - workspace_path = tags[TAG_WORKSPACE_PATH] - if !workspace_path.nil? && (workspace_path == "~" || workspace_path.start_with?("~/")) - tags[TAG_WORKSPACE_PATH] = File.expand_path(workspace_path) - end - # Fill out tags from local git as fallback - extract_local_git.each do |key, value| + local_git_tags = LocalGit.new(env).tags + local_git_tags.each do |key, value| tags[key] ||= value end - tags.reject { |_, v| v.nil? } - end - - def normalize_ref(name) - refs = %r{^refs/(heads/)?} - origin = %r{^origin/} - tags = %r{^tags/} - name.gsub(refs, "").gsub(origin, "").gsub(tags, "") unless name.nil? - end - - def filter_sensitive_info(url) - url.gsub(%r{(https?://)[^/]*@}, '\1') unless url.nil? - end - - # CI providers - def git_commit_users - # Get committer and author information in one command. - output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'") - return unless output - - fields = output.split("\t").each(&:strip!) - - { - author_name: fields[0], - author_email: fields[1], - # Because we can't get a reliable UTC time from all recent versions of git - # We have to rely on converting the date to UTC ourselves. - author_date: Time.at(fields[2].to_i).utc.to_datetime.iso8601, - committer_name: fields[3], - committer_email: fields[4], - # Because we can't get a reliable UTC time from all recent versions of git - # We have to rely on converting the date to UTC ourselves. - committer_date: Time.at(fields[5].to_i).utc.to_datetime.iso8601 - } - rescue => e - Datadog.logger.debug( - "Unable to read git commit users: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end - - def git_repository_url - exec_git_command("git ls-remote --get-url") - rescue => e - Datadog.logger.debug( - "Unable to read git repository url: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end - - def git_commit_message - exec_git_command("git show -s --format=%s") - rescue => e - Datadog.logger.debug( - "Unable to read git commit message: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end - - def git_branch - exec_git_command("git rev-parse --abbrev-ref HEAD") - rescue => e - Datadog.logger.debug( - "Unable to read git branch: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end - - def git_commit_sha - exec_git_command("git rev-parse HEAD") - rescue => e - Datadog.logger.debug( - "Unable to read git commit SHA: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end - - def git_tag - exec_git_command("git tag --points-at HEAD") - rescue => e - Datadog.logger.debug( - "Unable to read git tag: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end - - def git_base_directory - exec_git_command("git rev-parse --show-toplevel") - rescue => e - Datadog.logger.debug( - "Unable to read git base directory: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end - - def exec_git_command(cmd) - out, status = Open3.capture2e(cmd) - - raise "Failed to run git command #{cmd}: #{out}" unless status.success? - - out.strip! # There's always a "\n" at the end of the command output - - return nil if out.empty? - - out - end - - def extract_local_git - env = { - TAG_WORKSPACE_PATH => git_base_directory, - Git::TAG_REPOSITORY_URL => git_repository_url, - Git::TAG_COMMIT_SHA => git_commit_sha, - Git::TAG_BRANCH => git_branch, - Git::TAG_TAG => git_tag, - Git::TAG_COMMIT_MESSAGE => git_commit_message - } - - if (commit_users = git_commit_users) - env.merge!( - Git::TAG_COMMIT_AUTHOR_NAME => commit_users[:author_name], - Git::TAG_COMMIT_AUTHOR_EMAIL => commit_users[:author_email], - Git::TAG_COMMIT_AUTHOR_DATE => commit_users[:author_date], - Git::TAG_COMMIT_COMMITTER_NAME => commit_users[:committer_name], - Git::TAG_COMMIT_COMMITTER_EMAIL => commit_users[:committer_email], - Git::TAG_COMMIT_COMMITTER_DATE => commit_users[:committer_date] - ) - end - - env - end - - def branch_or_tag(branch_or_tag) - branch = tag = nil - if branch_or_tag && branch_or_tag.include?("tags/") - tag = branch_or_tag - else - branch = branch_or_tag - end - - [branch, tag] + tags end end end diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 8b92e486..4bb5ef70 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -54,7 +54,7 @@ def initialize(env) end def tags - { + tags = { Environment::TAG_JOB_NAME => job_name, Environment::TAG_JOB_URL => job_url, Environment::TAG_PIPELINE_ID => pipeline_id, @@ -86,6 +86,13 @@ def tags # @type var v: untyped v.nil? || v.strip.empty? end + + # Normalize Git references and filter sensitive data + normalize_git!(tags) + # Expand ~ + expand_workspace!(tags) + + tags end private @@ -172,6 +179,30 @@ def git_commit_message def git_commit_sha end + def normalize_git!(tags) + if !tags[Git::TAG_BRANCH].nil? && tags[Git::TAG_BRANCH].include?("tags/") + tags[Git::TAG_TAG] = tags[Git::TAG_BRANCH] + tags.delete(Git::TAG_BRANCH) + end + + tags[Git::TAG_TAG] = normalize_ref(tags[Git::TAG_TAG]) if tags[Git::TAG_TAG] + tags[Git::TAG_BRANCH] = normalize_ref(tags[Git::TAG_BRANCH]) if tags[Git::TAG_BRANCH] + + if tags[Git::TAG_REPOSITORY_URL] + tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info( + tags[Git::TAG_REPOSITORY_URL] + ) + end + end + + def expand_workspace!(tags) + workspace_path = tags[TAG_WORKSPACE_PATH] + + if !workspace_path.nil? && (workspace_path == "~" || workspace_path.start_with?("~/")) + tags[TAG_WORKSPACE_PATH] = File.expand_path(workspace_path) + end + end + def set_branch_and_tag branch_or_tag_string = git_branch_or_tag @branch = @tag = nil @@ -185,14 +216,18 @@ def set_branch_and_tag end def normalize_ref(name) + return nil if name.nil? + refs = %r{^refs/(heads/)?} origin = %r{^origin/} tags = %r{^tags/} - name.gsub(refs, "").gsub(origin, "").gsub(tags, "") unless name.nil? + name.gsub(refs, "").gsub(origin, "").gsub(tags, "") end def filter_sensitive_info(url) - url.gsub(%r{(https?://)[^/]*@}, '\1') unless url.nil? + return nil if url.nil? + + url.gsub(%r{(https?://)[^/]*@}, '\1') end end end diff --git a/lib/datadog/ci/ext/environment/local_git.rb b/lib/datadog/ci/ext/environment/local_git.rb new file mode 100644 index 00000000..1fab41f0 --- /dev/null +++ b/lib/datadog/ci/ext/environment/local_git.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +require "open3" + +require_relative "extractor" +require_relative "../git" + +module Datadog + module CI + module Ext + module Environment + # As a fallback we try to fetch git information from the local git repository + class LocalGit < Extractor + private + + def git_repository_url + exec_git_command("git ls-remote --get-url") + rescue => e + Datadog.logger.debug( + "Unable to read git repository url: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end + + def git_commit_sha + exec_git_command("git rev-parse HEAD") + rescue => e + Datadog.logger.debug( + "Unable to read git commit SHA: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end + + def git_branch + exec_git_command("git rev-parse --abbrev-ref HEAD") + rescue => e + Datadog.logger.debug( + "Unable to read git branch: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end + + def git_tag + exec_git_command("git tag --points-at HEAD") + rescue => e + Datadog.logger.debug( + "Unable to read git tag: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end + + def git_commit_message + exec_git_command("git show -s --format=%s") + rescue => e + Datadog.logger.debug( + "Unable to read git commit message: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end + + def git_commit_author_name + git_commit_users[:author_name] + end + + def git_commit_author_email + git_commit_users[:author_email] + end + + def git_commit_author_date + git_commit_users[:author_date] + end + + def git_commit_committer_name + git_commit_users[:committer_name] + end + + def git_commit_committer_email + git_commit_users[:committer_email] + end + + def git_commit_committer_date + git_commit_users[:committer_date] + end + + def workspace_path + exec_git_command("git rev-parse --show-toplevel") + rescue => e + Datadog.logger.debug( + "Unable to read git base directory: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end + + # local git specific methods + def exec_git_command(cmd) + out, status = Open3.capture2e(cmd) + + raise "Failed to run git command #{cmd}: #{out}" unless status.success? + + out.strip! # There's always a "\n" at the end of the command output + + return nil if out.empty? + + out + end + + def git_commit_users + return @commit_users if defined?(@commit_users) + + # Get committer and author information in one command. + output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'") + unless output + Datadog.logger.debug( + "Unable to read git commit users: git command output is nil" + ) + return @commit_users = {} + end + + fields = output.split("\t").each(&:strip!) + + @commit_users = { + author_name: fields[0], + author_email: fields[1], + # Because we can't get a reliable UTC time from all recent versions of git + # We have to rely on converting the date to UTC ourselves. + author_date: Time.at(fields[2].to_i).utc.to_datetime.iso8601, + committer_name: fields[3], + committer_email: fields[4], + # Because we can't get a reliable UTC time from all recent versions of git + # We have to rely on converting the date to UTC ourselves. + committer_date: Time.at(fields[5].to_i).utc.to_datetime.iso8601 + } + rescue => e + Datadog.logger.debug( + "Unable to read git commit users: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + @commit_users = {} + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/providers/azure.rb b/lib/datadog/ci/ext/environment/providers/azure.rb index 126f7619..903a4625 100644 --- a/lib/datadog/ci/ext/environment/providers/azure.rb +++ b/lib/datadog/ci/ext/environment/providers/azure.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "json" + require_relative "../extractor" module Datadog diff --git a/lib/datadog/ci/ext/environment/providers/buildkite.rb b/lib/datadog/ci/ext/environment/providers/buildkite.rb index a871d357..6273a32b 100644 --- a/lib/datadog/ci/ext/environment/providers/buildkite.rb +++ b/lib/datadog/ci/ext/environment/providers/buildkite.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "json" + require_relative "../extractor" module Datadog diff --git a/lib/datadog/ci/ext/environment/providers/circleci.rb b/lib/datadog/ci/ext/environment/providers/circleci.rb index 71488e75..e8d06746 100644 --- a/lib/datadog/ci/ext/environment/providers/circleci.rb +++ b/lib/datadog/ci/ext/environment/providers/circleci.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "json" + require_relative "../extractor" module Datadog diff --git a/lib/datadog/ci/ext/environment/providers/codefresh.rb b/lib/datadog/ci/ext/environment/providers/codefresh.rb index a48ce061..5e29dc6a 100644 --- a/lib/datadog/ci/ext/environment/providers/codefresh.rb +++ b/lib/datadog/ci/ext/environment/providers/codefresh.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "json" + require_relative "../extractor" module Datadog diff --git a/lib/datadog/ci/ext/environment/providers/github_actions.rb b/lib/datadog/ci/ext/environment/providers/github_actions.rb index 6bd30562..18be6437 100644 --- a/lib/datadog/ci/ext/environment/providers/github_actions.rb +++ b/lib/datadog/ci/ext/environment/providers/github_actions.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "json" + require_relative "../extractor" module Datadog diff --git a/lib/datadog/ci/ext/environment/providers/jenkins.rb b/lib/datadog/ci/ext/environment/providers/jenkins.rb index f6f65dad..28ce887e 100644 --- a/lib/datadog/ci/ext/environment/providers/jenkins.rb +++ b/lib/datadog/ci/ext/environment/providers/jenkins.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "json" + require_relative "../extractor" module Datadog diff --git a/lib/datadog/ci/ext/environment/user_defined_tags.rb b/lib/datadog/ci/ext/environment/user_defined_tags.rb index 0792c69d..0f3e14d9 100644 --- a/lib/datadog/ci/ext/environment/user_defined_tags.rb +++ b/lib/datadog/ci/ext/environment/user_defined_tags.rb @@ -10,6 +10,8 @@ module Environment # Parses user defined git data from the environment variables # User documentation: https://docs.datadoghq.com/continuous_integration/troubleshooting/#data-appears-in-test-runs-but-not-tests class UserDefinedTags < Extractor + private + def git_repository_url env[Git::ENV_REPOSITORY_URL] end diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index dd91a156..cb71c65a 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -68,6 +68,10 @@ module Datadog def set_branch_and_tag: () -> [String?, String?] + def normalize_git!: (Hash[String, untyped] tags) -> void + + def expand_workspace!: (Hash[String, untyped] tags) -> void + def normalize_ref: (String? name) -> String? def filter_sensitive_info: (String? url) -> String? diff --git a/sig/datadog/ci/ext/environment/local_git.rbs b/sig/datadog/ci/ext/environment/local_git.rbs new file mode 100644 index 00000000..36bfc205 --- /dev/null +++ b/sig/datadog/ci/ext/environment/local_git.rbs @@ -0,0 +1,41 @@ +module Datadog + module CI + module Ext + module Environment + class LocalGit < Extractor + private + + @commit_users: Hash[Symbol, String?] + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_message: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_author_date: () -> String? + + def git_commit_committer_name: () -> String? + + def git_commit_committer_email: () -> String? + + def git_commit_committer_date: () -> String? + + def workspace_path: () -> String? + + def exec_git_command: (String cmd) -> String? + + def git_commit_users: () -> Hash[Symbol, String?] + end + end + end + end +end From 57c5809cd9f53b326861fa23381c4586d2722e4e Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 14:16:24 +0200 Subject: [PATCH 20/31] validate git tags --- lib/datadog/ci/ext/environment.rb | 36 ++++++ lib/datadog/ci/ext/git.rb | 2 +- sig/datadog/ci/ext/environment.rbs | 56 +------- sig/datadog/ci/ext/git.rbs | 2 +- spec/datadog/ci/ext/environment_spec.rb | 165 +++++++++++++++++++----- 5 files changed, 174 insertions(+), 87 deletions(-) diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index b7f57a4f..3b2c2114 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -23,6 +23,8 @@ module Environment TAG_NODE_NAME = "ci.node.name" TAG_CI_ENV_VARS = "_dd.ci.env_vars" + HEX_NUMBER_REGEXP = /[0-9a-f]{40}/i.freeze + module_function def tags(env) @@ -40,8 +42,42 @@ def tags(env) tags[key] ||= value end + ensure_post_conditions(tags) + tags end + + def ensure_post_conditions(tags) + validate_repository_url(tags[Git::TAG_REPOSITORY_URL]) + validate_git_sha(tags[Git::TAG_COMMIT_SHA]) + end + + def validate_repository_url(repo_url) + return if !repo_url.nil? && !repo_url.empty? + + Datadog.logger.error("DD_GIT_REPOSITORY_URL is not set or empty; no repo URL was automatically extracted") + end + + def validate_git_sha(git_sha) + message = "DD_GIT_COMMIT_SHA must be a full-length git SHA." + + if git_sha.nil? || git_sha.empty? + message += " No value was set and no SHA was automatically extracted." + Datadog.logger.error(message) + return + end + + if git_sha.length < Git::SHA_LENGTH + message += " Expected SHA length #{Git::SHA_LENGTH}, was #{git_sha.length}." + Datadog.logger.error(message) + return + end + + unless HEX_NUMBER_REGEXP =~ git_sha + message += " Expected SHA to be a valid HEX number, got #{git_sha}." + Datadog.logger.error(message) + end + end end end end diff --git a/lib/datadog/ci/ext/git.rb b/lib/datadog/ci/ext/git.rb index 5bd87946..a8f9d6f5 100644 --- a/lib/datadog/ci/ext/git.rb +++ b/lib/datadog/ci/ext/git.rb @@ -5,7 +5,7 @@ module CI module Ext # Defines constants for Git tags module Git - GIT_SHA_LENGTH = 40 + SHA_LENGTH = 40 TAG_BRANCH = "git.branch" TAG_REPOSITORY_URL = "git.repository_url" diff --git a/sig/datadog/ci/ext/environment.rbs b/sig/datadog/ci/ext/environment.rbs index d6b0dc1f..73f8b132 100644 --- a/sig/datadog/ci/ext/environment.rbs +++ b/sig/datadog/ci/ext/environment.rbs @@ -27,63 +27,17 @@ module Datadog TAG_CI_ENV_VARS: String + HEX_NUMBER_REGEXP: Regexp + PROVIDERS: ::Array[Array[String | Symbol]] def self?.tags: (untyped env) -> Hash[String, String] - def self?.normalize_ref: (untyped name) -> untyped - - def self?.filter_sensitive_info: (untyped url) -> (String | nil) - - def self?.extract_appveyor: (untyped env) -> ::Hash[String, String?] - - def self?.extract_azure_pipelines: (untyped env) -> ::Hash[String, String?] - - def self?.extract_bitbucket: (untyped env) -> ::Hash[String, String?] - - def self?.extract_buddy: (untyped env) -> ::Hash[String, String?] - - def self?.extract_buildkite: (untyped env) -> Hash[String, String?] - - def self?.extract_circle_ci: (untyped env) -> ::Hash[String, String?] - - def self?.extract_github_actions: (untyped env) -> ::Hash[String, String?] - - def self?.extract_gitlab: (untyped env) -> ::Hash[String, String?] - - def self?.extract_jenkins: (untyped env) -> ::Hash[String, String?] - - def self?.extract_teamcity: (untyped env) -> ::Hash[String, String?] - - def self?.extract_travis: (untyped env) -> ::Hash[String, String?] - - def self?.extract_bitrise: (untyped env) -> ::Hash[String, String?] - - def self?.extract_codefresh: (untyped env) -> ::Hash[String, String?] - - def self?.extract_user_defined_git: (untyped env) -> Hash[String, String?] - - def self?.git_commit_users: () -> untyped - - def self?.git_repository_url: () -> untyped - - def self?.git_commit_message: () -> untyped - - def self?.git_branch: () -> untyped - - def self?.git_commit_sha: () -> untyped - - def self?.git_tag: () -> untyped - - def self?.git_base_directory: () -> untyped - - def self?.exec_git_command: (untyped cmd) -> (nil | untyped) - - def self?.extract_local_git: () -> untyped + def self?.ensure_post_conditions: (Hash[String, String] tags) -> void - def self?.branch_or_tag: (untyped branch_or_tag) -> ::Array[untyped] + def self?.validate_repository_url: (String? repo_url) -> void - def self?.extract_name_email: (untyped name_and_email) -> (::Array[untyped] | ::Array[nil | untyped]) + def self?.validate_git_sha: (String? git_sha) -> void end end end diff --git a/sig/datadog/ci/ext/git.rbs b/sig/datadog/ci/ext/git.rbs index 3424c185..ce436a7b 100644 --- a/sig/datadog/ci/ext/git.rbs +++ b/sig/datadog/ci/ext/git.rbs @@ -2,7 +2,7 @@ module Datadog module CI module Ext module Git - GIT_SHA_LENGTH: 40 + SHA_LENGTH: 40 TAG_BRANCH: "git.branch" diff --git a/spec/datadog/ci/ext/environment_spec.rb b/spec/datadog/ci/ext/environment_spec.rb index ba953553..e910a590 100644 --- a/spec/datadog/ci/ext/environment_spec.rb +++ b/spec/datadog/ci/ext/environment_spec.rb @@ -3,6 +3,13 @@ RSpec.describe ::Datadog::CI::Ext::Environment do FIXTURE_DIR = "#{File.dirname(__FILE__)}/fixtures/" # rubocop:disable all + let(:logger) { instance_double(Datadog::Core::Logger) } + before do + allow(Datadog).to receive(:logger).and_return(logger) + allow(logger).to receive(:debug) + allow(logger).to receive(:error) + end + describe ".tags" do subject(:extracted_tags) do ClimateControl.modify(environment_variables) { described_class.tags(env) } @@ -107,49 +114,139 @@ include_context "without git installed" it "does not fail" do - allow(Datadog.logger).to receive(:debug) - is_expected.to eq({}) - expect(Datadog.logger).to have_received(:debug).with(/No such file or directory - git/).at_least(1).time + expect(logger).to have_received(:debug).with(/No such file or directory - git/).at_least(1).time end end context "user provided metadata" do - include_context "with git fixture", "gitdir_with_commit" - let(:env) do - { - "DD_GIT_REPOSITORY_URL" => "https://datadoghq.com/git/user-provided.git", - "DD_GIT_COMMIT_SHA" => "9322ca1d57975b49b8c00b449d21b06660ce8b5c", - "DD_GIT_BRANCH" => "my-branch", - "DD_GIT_TAG" => "my-tag", - "DD_GIT_COMMIT_MESSAGE" => "provided message", - "DD_GIT_COMMIT_AUTHOR_NAME" => "user", - "DD_GIT_COMMIT_AUTHOR_EMAIL" => "user@provided.com", - "DD_GIT_COMMIT_AUTHOR_DATE" => "2021-06-18T18:35:10+00:00", - "DD_GIT_COMMIT_COMMITTER_NAME" => "user committer", - "DD_GIT_COMMIT_COMMITTER_EMAIL" => "user-committer@provided.com", - "DD_GIT_COMMIT_COMMITTER_DATE" => "2021-06-19T18:35:10+00:00" - } - end + context "when required values are present" do + include_context "with git fixture", "gitdir_with_commit" - it "returns user provided metadata" do - is_expected.to eq( + let(:env) do { - "ci.workspace_path" => "#{Dir.pwd}/spec/datadog/ci/ext/fixtures/git", - "git.branch" => env["DD_GIT_BRANCH"], - "git.tag" => env["DD_GIT_TAG"], - "git.commit.author.date" => env["DD_GIT_COMMIT_AUTHOR_DATE"], - "git.commit.author.email" => env["DD_GIT_COMMIT_AUTHOR_EMAIL"], - "git.commit.author.name" => env["DD_GIT_COMMIT_AUTHOR_NAME"], - "git.commit.committer.date" => env["DD_GIT_COMMIT_COMMITTER_DATE"], - "git.commit.committer.email" => env["DD_GIT_COMMIT_COMMITTER_EMAIL"], - "git.commit.committer.name" => env["DD_GIT_COMMIT_COMMITTER_NAME"], - "git.commit.message" => env["DD_GIT_COMMIT_MESSAGE"], - "git.commit.sha" => env["DD_GIT_COMMIT_SHA"], - "git.repository_url" => env["DD_GIT_REPOSITORY_URL"] + "DD_GIT_REPOSITORY_URL" => "https://datadoghq.com/git/user-provided.git", + "DD_GIT_COMMIT_SHA" => "9322CA1d57975b49b8c00b449d21b06660ce8b5c", + "DD_GIT_BRANCH" => "my-branch", + "DD_GIT_TAG" => "my-tag", + "DD_GIT_COMMIT_MESSAGE" => "provided message", + "DD_GIT_COMMIT_AUTHOR_NAME" => "user", + "DD_GIT_COMMIT_AUTHOR_EMAIL" => "user@provided.com", + "DD_GIT_COMMIT_AUTHOR_DATE" => "2021-06-18T18:35:10+00:00", + "DD_GIT_COMMIT_COMMITTER_NAME" => "user committer", + "DD_GIT_COMMIT_COMMITTER_EMAIL" => "user-committer@provided.com", + "DD_GIT_COMMIT_COMMITTER_DATE" => "2021-06-19T18:35:10+00:00" } - ) + end + + it "returns user provided metadata" do + is_expected.to eq( + { + "ci.workspace_path" => "#{Dir.pwd}/spec/datadog/ci/ext/fixtures/git", + "git.branch" => env["DD_GIT_BRANCH"], + "git.tag" => env["DD_GIT_TAG"], + "git.commit.author.date" => env["DD_GIT_COMMIT_AUTHOR_DATE"], + "git.commit.author.email" => env["DD_GIT_COMMIT_AUTHOR_EMAIL"], + "git.commit.author.name" => env["DD_GIT_COMMIT_AUTHOR_NAME"], + "git.commit.committer.date" => env["DD_GIT_COMMIT_COMMITTER_DATE"], + "git.commit.committer.email" => env["DD_GIT_COMMIT_COMMITTER_EMAIL"], + "git.commit.committer.name" => env["DD_GIT_COMMIT_COMMITTER_NAME"], + "git.commit.message" => env["DD_GIT_COMMIT_MESSAGE"], + "git.commit.sha" => env["DD_GIT_COMMIT_SHA"], + "git.repository_url" => env["DD_GIT_REPOSITORY_URL"] + } + ) + end + end + + context "with no git information extracted" do + include_context "without git installed" + + context "when DD_GIT_REPOSITORY_URL is missing" do + let(:env) do + { + "DD_GIT_COMMIT_SHA" => "9322ca1d57975b49b8c00b449d21b06660ce8b5c" + } + end + + it "logs an error" do + is_expected.to eq( + { + "git.commit.sha" => env["DD_GIT_COMMIT_SHA"] + } + ) + + expect(logger).to have_received(:error).with( + "DD_GIT_REPOSITORY_URL is not set or empty; no repo URL was automatically extracted" + ) + end + end + + context "when DD_GIT_COMMIT_SHA is missing" do + let(:env) do + { + "DD_GIT_REPOSITORY_URL" => "https://datadoghq.com/git/user-provided.git" + } + end + + it "logs an error" do + is_expected.to eq( + { + "git.repository_url" => env["DD_GIT_REPOSITORY_URL"] + } + ) + + expect(logger).to have_received(:error).with( + "DD_GIT_COMMIT_SHA must be a full-length git SHA. No value was set and no SHA was automatically extracted." + ) + end + end + + context "when DD_GIT_COMMIT_SHA has invalid length" do + let(:env) do + { + "DD_GIT_COMMIT_SHA" => "9322ca1d57975b49b8c00b449d21b06660ce8b5", + "DD_GIT_REPOSITORY_URL" => "https://datadoghq.com/git/user-provided.git" + } + end + + it "logs an error" do + is_expected.to eq( + { + "git.commit.sha" => env["DD_GIT_COMMIT_SHA"], + "git.repository_url" => env["DD_GIT_REPOSITORY_URL"] + } + ) + + expect(logger).to have_received(:error).with( + "DD_GIT_COMMIT_SHA must be a full-length git SHA. Expected SHA length 40, was 39." + ) + end + end + + context "when DD_GIT_COMMIT_SHA is not a valid hex number" do + let(:env) do + { + "DD_GIT_COMMIT_SHA" => "9322ca1d57975by9b8c00b449d21b06660ce8b5c", + "DD_GIT_REPOSITORY_URL" => "https://datadoghq.com/git/user-provided.git" + } + end + + it "logs an error" do + is_expected.to eq( + { + "git.commit.sha" => env["DD_GIT_COMMIT_SHA"], + "git.repository_url" => env["DD_GIT_REPOSITORY_URL"] + } + ) + + expect(logger).to have_received(:error).with( + "DD_GIT_COMMIT_SHA must be a full-length git SHA. " \ + "Expected SHA to be a valid HEX number, got 9322ca1d57975by9b8c00b449d21b06660ce8b5c." + ) + end + end end end end From e3e0900949af6b3c099c5500be26d6c2a5a72a75 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 16:25:13 +0200 Subject: [PATCH 21/31] add @tags class var and remove some nil checks --- lib/datadog/ci/ext/environment/extractor.rb | 54 +++++++++++--------- sig/datadog/ci/ext/environment/extractor.rbs | 7 ++- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 4bb5ef70..354093fb 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -54,7 +54,9 @@ def initialize(env) end def tags - tags = { + return @tags if defined?(@tags) + + @tags = { Environment::TAG_JOB_NAME => job_name, Environment::TAG_JOB_URL => job_url, Environment::TAG_PIPELINE_ID => pipeline_id, @@ -79,7 +81,15 @@ def tags Git::TAG_COMMIT_COMMITTER_NAME => git_commit_committer_name, Git::TAG_COMMIT_MESSAGE => git_commit_message, Git::TAG_COMMIT_SHA => git_commit_sha - }.reject do |_, v| + } + + # Normalize Git references and filter sensitive data + normalize_git! + # Expand ~ + expand_workspace! + + # remove empty tags + @tags.reject! do |_, v| # setting type of v here to untyped because steep does not # understand `v.nil? || something` @@ -87,12 +97,7 @@ def tags v.nil? || v.strip.empty? end - # Normalize Git references and filter sensitive data - normalize_git!(tags) - # Expand ~ - expand_workspace!(tags) - - tags + @tags end private @@ -179,33 +184,36 @@ def git_commit_message def git_commit_sha end - def normalize_git!(tags) - if !tags[Git::TAG_BRANCH].nil? && tags[Git::TAG_BRANCH].include?("tags/") - tags[Git::TAG_TAG] = tags[Git::TAG_BRANCH] - tags.delete(Git::TAG_BRANCH) + def normalize_git! + branch_ref = @tags[Git::TAG_BRANCH] + if is_git_tag?(branch_ref) + @tags[Git::TAG_TAG] = branch_ref + @tags.delete(Git::TAG_BRANCH) end - tags[Git::TAG_TAG] = normalize_ref(tags[Git::TAG_TAG]) if tags[Git::TAG_TAG] - tags[Git::TAG_BRANCH] = normalize_ref(tags[Git::TAG_BRANCH]) if tags[Git::TAG_BRANCH] - - if tags[Git::TAG_REPOSITORY_URL] - tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info( - tags[Git::TAG_REPOSITORY_URL] - ) - end + @tags[Git::TAG_TAG] = normalize_ref(@tags[Git::TAG_TAG]) + @tags[Git::TAG_BRANCH] = normalize_ref(@tags[Git::TAG_BRANCH]) + @tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info( + @tags[Git::TAG_REPOSITORY_URL] + ) end - def expand_workspace!(tags) - workspace_path = tags[TAG_WORKSPACE_PATH] + def expand_workspace! + workspace_path = @tags[TAG_WORKSPACE_PATH] if !workspace_path.nil? && (workspace_path == "~" || workspace_path.start_with?("~/")) - tags[TAG_WORKSPACE_PATH] = File.expand_path(workspace_path) + @tags[TAG_WORKSPACE_PATH] = File.expand_path(workspace_path) end end + def is_git_tag?(ref) + !ref.nil? && ref.include?("tags/") + end + def set_branch_and_tag branch_or_tag_string = git_branch_or_tag @branch = @tag = nil + if branch_or_tag_string && branch_or_tag_string.include?("tags/") @tag = branch_or_tag_string else diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index cb71c65a..b9a0f256 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -5,6 +5,7 @@ module Datadog class Extractor PROVIDERS: ::Array[[String, singleton(Extractor)]] + @tags: Hash[String, untyped] @branch: String? @tag: String? @@ -68,9 +69,11 @@ module Datadog def set_branch_and_tag: () -> [String?, String?] - def normalize_git!: (Hash[String, untyped] tags) -> void + def normalize_git!: () -> void - def expand_workspace!: (Hash[String, untyped] tags) -> void + def expand_workspace!: () -> void + + def is_git_tag?: (String? ref) -> bool def normalize_ref: (String? name) -> String? From ad72ac67c87441e8d47d4546a6de5a7a0318362b Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Mon, 4 Sep 2023 17:01:48 +0200 Subject: [PATCH 22/31] refactor commit users for local_git extractor --- lib/datadog/ci/ext/environment/local_git.rb | 74 +++++++++++++------- sig/datadog/ci/ext/environment/local_git.rbs | 27 ++++++- 2 files changed, 75 insertions(+), 26 deletions(-) diff --git a/lib/datadog/ci/ext/environment/local_git.rb b/lib/datadog/ci/ext/environment/local_git.rb index 1fab41f0..4b2e7bd3 100644 --- a/lib/datadog/ci/ext/environment/local_git.rb +++ b/lib/datadog/ci/ext/environment/local_git.rb @@ -59,27 +59,27 @@ def git_commit_message end def git_commit_author_name - git_commit_users[:author_name] + author.name end def git_commit_author_email - git_commit_users[:author_email] + author.email end def git_commit_author_date - git_commit_users[:author_date] + author.date end def git_commit_committer_name - git_commit_users[:committer_name] + committer.name end def git_commit_committer_email - git_commit_users[:committer_email] + committer.email end def git_commit_committer_date - git_commit_users[:committer_date] + committer.date end def workspace_path @@ -104,37 +104,63 @@ def exec_git_command(cmd) out end - def git_commit_users - return @commit_users if defined?(@commit_users) + def author + return @author if defined?(@author) + set_git_commit_users + @author + end + + def committer + return @committer if defined?(@committer) + + set_git_commit_users + @committer + end + + def set_git_commit_users # Get committer and author information in one command. output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'") unless output Datadog.logger.debug( "Unable to read git commit users: git command output is nil" ) - return @commit_users = {} + @author = @committer = NilUser.new + return end - fields = output.split("\t").each(&:strip!) - - @commit_users = { - author_name: fields[0], - author_email: fields[1], - # Because we can't get a reliable UTC time from all recent versions of git - # We have to rely on converting the date to UTC ourselves. - author_date: Time.at(fields[2].to_i).utc.to_datetime.iso8601, - committer_name: fields[3], - committer_email: fields[4], - # Because we can't get a reliable UTC time from all recent versions of git - # We have to rely on converting the date to UTC ourselves. - committer_date: Time.at(fields[5].to_i).utc.to_datetime.iso8601 - } + author_name, author_email, author_timestamp, + committer_name, committer_email, committer_timestamp = output.split("\t").each(&:strip!) + + @author = GitUser.new(author_name, author_email, author_timestamp) + @committer = GitUser.new(committer_name, committer_email, committer_timestamp) rescue => e Datadog.logger.debug( "Unable to read git commit users: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" ) - @commit_users = {} + @author = @committer = NilUser.new + end + + class GitUser + attr_reader :name, :email, :timestamp + + def initialize(name, email, timestamp) + @name = name + @email = email + @timestamp = timestamp + end + + def date + return nil if timestamp.nil? + + Time.at(timestamp.to_i).utc.to_datetime.iso8601 + end + end + + class NilUser < GitUser + def initialize + super(nil, nil, nil) + end end end end diff --git a/sig/datadog/ci/ext/environment/local_git.rbs b/sig/datadog/ci/ext/environment/local_git.rbs index 36bfc205..fbc497d8 100644 --- a/sig/datadog/ci/ext/environment/local_git.rbs +++ b/sig/datadog/ci/ext/environment/local_git.rbs @@ -3,9 +3,28 @@ module Datadog module Ext module Environment class LocalGit < Extractor + class GitUser + attr_reader name: String? + attr_reader email: String? + attr_reader timestamp: String? + + @name: String? + @email: String? + @timestamp: String? + + def initialize: (String? name, String? email, String? timestamp) -> void + + def date: () -> String? + end + + class NilUser < GitUser + def initialize: () -> void + end + private - @commit_users: Hash[Symbol, String?] + @author: GitUser + @committer: GitUser def git_repository_url: () -> String? @@ -33,7 +52,11 @@ module Datadog def exec_git_command: (String cmd) -> String? - def git_commit_users: () -> Hash[Symbol, String?] + def author: () -> GitUser + + def committer: () -> GitUser + + def set_git_commit_users: () -> void end end end From 13fa56dd1c5b88407aa17c6a2618213b24e1ab18 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Tue, 5 Sep 2023 12:35:11 +0200 Subject: [PATCH 23/31] providers specs --- .../environment/providers/appveyor_spec.rb | 69 ++++++++++++++++ .../ext/environment/providers/azure_spec.rb | 74 ++++++++++++++++++ .../environment/providers/bitbucket_spec.rb | 52 +++++++++++++ .../ext/environment/providers/bitrise_spec.rb | 46 +++++++++++ .../ext/environment/providers/buddy_spec.rb | 52 +++++++++++++ .../environment/providers/buildkite_spec.rb | 56 +++++++++++++ .../environment/providers/circleci_spec.rb | 49 ++++++++++++ .../environment/providers/codefresh_spec.rb | 38 +++++++++ .../ext/environment/providers/default_spec.rb | 27 +++++++ .../providers/github_actions_spec.rb | 50 ++++++++++++ .../ext/environment/providers/gitlab_spec.rb | 78 +++++++++++++++++++ .../ext/environment/providers/jenkins_spec.rb | 58 ++++++++++++++ .../environment/providers/teamcity_spec.rb | 34 ++++++++ .../ext/environment/providers/travis_spec.rb | 50 ++++++++++++ 14 files changed, 733 insertions(+) create mode 100644 spec/datadog/ci/ext/environment/providers/appveyor_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/azure_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/bitrise_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/buddy_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/buildkite_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/circleci_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/codefresh_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/default_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/github_actions_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/gitlab_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/jenkins_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/teamcity_spec.rb create mode 100644 spec/datadog/ci/ext/environment/providers/travis_spec.rb diff --git a/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb b/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb new file mode 100644 index 00000000..5521196b --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb @@ -0,0 +1,69 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Appveyor do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "APPVEYOR" => "true", + "APPVEYOR_BUILD_FOLDER" => "/foo/bar", + "APPVEYOR_BUILD_ID" => "appveyor-build-id", + "APPVEYOR_BUILD_NUMBER" => "appveyor-pipeline-number", + "APPVEYOR_REPO_BRANCH" => "master", + "APPVEYOR_REPO_COMMIT" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "APPVEYOR_REPO_COMMIT_AUTHOR" => "appveyor-commit-author-name", + "APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL" => "appveyor-commit-author-email@datadoghq.com", + "APPVEYOR_REPO_COMMIT_MESSAGE" => "appveyor-commit-message", + "APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED" => "appveyor-commit-message-extended", + "APPVEYOR_REPO_NAME" => "appveyor-repo-name", + "APPVEYOR_REPO_PROVIDER" => "github" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "ci.job.url" => "https://ci.appveyor.com/project/appveyor-repo-name/builds/appveyor-build-id", + "ci.pipeline.id" => "appveyor-build-id", + "ci.pipeline.name" => "appveyor-repo-name", + "ci.pipeline.number" => "appveyor-pipeline-number", + "ci.pipeline.url" => "https://ci.appveyor.com/project/appveyor-repo-name/builds/appveyor-build-id", + "ci.provider.name" => "appveyor", + "ci.workspace_path" => "/foo/bar", + "git.branch" => "master", + "git.commit.author.email" => "appveyor-commit-author-email@datadoghq.com", + "git.commit.author.name" => "appveyor-commit-author-name", + "git.commit.message" => "appveyor-commit-message\nappveyor-commit-message-extended", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://github.com/appveyor-repo-name.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + + context "when commit message is not provided" do + let(:env) { super().except("APPVEYOR_REPO_COMMIT_MESSAGE") } + + it "omits git.commit.message" do + is_expected.to eq(expected_tags.except("git.commit.message")) + end + end + + context "when extended commit message is not provided" do + let(:env) { super().except("APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED") } + + it "does not append extended commit message" do + is_expected.to eq(expected_tags.merge({"git.commit.message" => "appveyor-commit-message"})) + end + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/azure_spec.rb b/spec/datadog/ci/ext/environment/providers/azure_spec.rb new file mode 100644 index 00000000..357a4f00 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/azure_spec.rb @@ -0,0 +1,74 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Azure do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BUILD_BUILDID" => "azure-pipelines-build-id", + "BUILD_DEFINITIONNAME" => "azure-pipelines-name", + "BUILD_REPOSITORY_URI" => "https://azure-pipelines-server-uri.com/build.git", + "BUILD_REQUESTEDFOREMAIL" => "azure-pipelines-commit-author-email@datadoghq.com", + "BUILD_REQUESTEDFORID" => "azure-pipelines-commit-author", + "BUILD_SOURCEBRANCH" => "master", + "BUILD_SOURCESDIRECTORY" => "/foo/bar", + "BUILD_SOURCEVERSION" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "BUILD_SOURCEVERSIONMESSAGE" => "azure-pipelines-commit-message", + "SYSTEM_JOBID" => "azure-pipelines-job-id", + "SYSTEM_TASKINSTANCEID" => "azure-pipelines-task-id", + "SYSTEM_TEAMFOUNDATIONSERVERURI" => "https://azure-pipelines-server-uri.com/", + "SYSTEM_TEAMPROJECTID" => "azure-pipelines-project-id", + "SYSTEM_STAGEDISPLAYNAME" => "azure-stage", + "TF_BUILD" => "True", + "HOME" => "/not-my-home", + "USERPROFILE" => "/not-my-home" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "_dd.ci.env_vars" => "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":\"azure-pipelines-build-id\",\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}", + "ci.job.url" => "https://azure-pipelines-server-uri.com/azure-pipelines-project-id/_build/results?buildId=azure-pipelines-build-id&view=logs&j=azure-pipelines-job-id&t=azure-pipelines-task-id", + "ci.pipeline.id" => "azure-pipelines-build-id", + "ci.pipeline.name" => "azure-pipelines-name", + "ci.pipeline.number" => "azure-pipelines-build-id", + "ci.pipeline.url" => "https://azure-pipelines-server-uri.com/azure-pipelines-project-id/_build/results?buildId=azure-pipelines-build-id", + "ci.provider.name" => "azurepipelines", + "ci.stage.name" => "azure-stage", + "ci.workspace_path" => "/foo/bar", + "git.branch" => "master", + "git.commit.author.email" => "azure-pipelines-commit-author-email@datadoghq.com", + "git.commit.author.name" => "azure-pipelines-commit-author", + "git.commit.message" => "azure-pipelines-commit-message", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://azure-pipelines-server-uri.com/build.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + + context "when pipeline URL cannot be defined" do + let(:env) do + super().except("BUILD_BUILDID") + end + + it "omits URLs" do + is_expected.to eq( + expected_tags.merge({ + "_dd.ci.env_vars" => "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":null,\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}", + }).except("ci.pipeline.id", "ci.pipeline.number", "ci.pipeline.url", "ci.job.url") + ) + end + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb b/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb new file mode 100644 index 00000000..e1f4a2ee --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb @@ -0,0 +1,52 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Bitbucket do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BITBUCKET_BRANCH" => "master", + "BITBUCKET_BUILD_NUMBER" => "bitbucket-build-num", + "BITBUCKET_CLONE_DIR" => "/foo/bar", + "BITBUCKET_COMMIT" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "BITBUCKET_GIT_HTTP_ORIGIN" => "https://bitbucket-repo-url.com/repo.git", + "BITBUCKET_PIPELINE_UUID" => "{bitbucket-uuid}", + "BITBUCKET_REPO_FULL_NAME" => "bitbucket-repo" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "ci.job.url" => "https://bitbucket.org/bitbucket-repo/addon/pipelines/home#!/results/bitbucket-build-num", + "ci.pipeline.id" => "bitbucket-uuid", + "ci.pipeline.name" => "bitbucket-repo", + "ci.pipeline.number" => "bitbucket-build-num", + "ci.pipeline.url" => "https://bitbucket.org/bitbucket-repo/addon/pipelines/home#!/results/bitbucket-build-num", + "ci.provider.name" => "bitbucket", + "ci.workspace_path" => "/foo/bar", + "git.branch" => "master", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://bitbucket-repo-url.com/repo.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + + context "when no BITBUCKET_PIPELINE_UUID provided" do + let(:env) { super().except("BITBUCKET_PIPELINE_UUID") } + it "omits pipeline_id" do + is_expected.to eq(expected_tags.except("ci.pipeline.id")) + end + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/bitrise_spec.rb b/spec/datadog/ci/ext/environment/providers/bitrise_spec.rb new file mode 100644 index 00000000..d4e8fb35 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/bitrise_spec.rb @@ -0,0 +1,46 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Bitrise do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BITRISE_BUILD_NUMBER" => "bitrise-pipeline-number", + "BITRISE_BUILD_SLUG" => "bitrise-pipeline-id", + "BITRISE_BUILD_URL" => "https://bitrise-build-url.com//", + "BITRISE_GIT_COMMIT" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "BITRISE_GIT_MESSAGE" => "bitrise-git-commit-message", + "BITRISE_SOURCE_DIR" => "/foo/bar", + "BITRISE_TRIGGERED_WORKFLOW_ID" => "bitrise-pipeline-name", + "GIT_CLONE_COMMIT_HASH" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "GIT_REPOSITORY_URL" => "https://bitrise-build-url.com/repo.git" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "ci.pipeline.id" => "bitrise-pipeline-id", + "ci.pipeline.name" => "bitrise-pipeline-name", + "ci.pipeline.number" => "bitrise-pipeline-number", + "ci.pipeline.url" => "https://bitrise-build-url.com//", + "ci.provider.name" => "bitrise", + "ci.workspace_path" => "/foo/bar", + "git.commit.message" => "bitrise-git-commit-message", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://bitrise-build-url.com/repo.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/buddy_spec.rb b/spec/datadog/ci/ext/environment/providers/buddy_spec.rb new file mode 100644 index 00000000..55674be9 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/buddy_spec.rb @@ -0,0 +1,52 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Buddy do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BUDDY" => "true", + "BUDDY_EXECUTION_BRANCH" => "master", + "BUDDY_EXECUTION_ID" => "buddy-execution-id", + "BUDDY_EXECUTION_REVISION" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL" => "mikebenson@buddy.works", + "BUDDY_EXECUTION_REVISION_COMMITTER_NAME" => "Mike Benson", + "BUDDY_EXECUTION_REVISION_MESSAGE" => "Create buddy.yml", + "BUDDY_EXECUTION_TAG" => "v1.0", + "BUDDY_EXECUTION_URL" => "https://app.buddy.works/myworkspace/my-project/pipelines/pipeline/456/execution/5d9dc42c422f5a268b389d08", + "BUDDY_PIPELINE_ID" => "456", + "BUDDY_PIPELINE_NAME" => "Deploy to Production", + "BUDDY_SCM_URL" => "https://github.com/buddyworks/my-project.git" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "ci.pipeline.id" => "456/buddy-execution-id", + "ci.pipeline.name" => "Deploy to Production", + "ci.pipeline.number" => "buddy-execution-id", + "ci.pipeline.url" => "https://app.buddy.works/myworkspace/my-project/pipelines/pipeline/456/execution/5d9dc42c422f5a268b389d08", + "ci.provider.name" => "buddy", + "git.branch" => "master", + "git.commit.committer.email" => "mikebenson@buddy.works", + "git.commit.committer.name" => "Mike Benson", + "git.commit.message" => "Create buddy.yml", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://github.com/buddyworks/my-project.git", + "git.tag" => "v1.0" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/buildkite_spec.rb b/spec/datadog/ci/ext/environment/providers/buildkite_spec.rb new file mode 100644 index 00000000..799cd36d --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/buildkite_spec.rb @@ -0,0 +1,56 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Buildkite do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BUILDKITE" => "true", + "BUILDKITE_BRANCH" => "master", + "BUILDKITE_BUILD_AUTHOR" => "buildkite-git-commit-author-name", + "BUILDKITE_BUILD_AUTHOR_EMAIL" => "buildkite-git-commit-author-email@datadoghq.com", + "BUILDKITE_BUILD_CHECKOUT_PATH" => "/foo/bar", + "BUILDKITE_BUILD_ID" => "buildkite-pipeline-id", + "BUILDKITE_BUILD_NUMBER" => "buildkite-pipeline-number", + "BUILDKITE_BUILD_URL" => "https://buildkite-build-url.com", + "BUILDKITE_COMMIT" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "BUILDKITE_JOB_ID" => "buildkite-job-id", + "BUILDKITE_MESSAGE" => "buildkite-git-commit-message", + "BUILDKITE_PIPELINE_SLUG" => "buildkite-pipeline-name", + "BUILDKITE_REPO" => "http://hostname.com/repo.git", + "BUILDKITE_TAG" => "" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "_dd.ci.env_vars" => "{\"BUILDKITE_BUILD_ID\":\"buildkite-pipeline-id\",\"BUILDKITE_JOB_ID\":\"buildkite-job-id\"}", + "ci.job.url" => "https://buildkite-build-url.com#buildkite-job-id", + "ci.pipeline.id" => "buildkite-pipeline-id", + "ci.pipeline.name" => "buildkite-pipeline-name", + "ci.pipeline.number" => "buildkite-pipeline-number", + "ci.pipeline.url" => "https://buildkite-build-url.com", + "ci.provider.name" => "buildkite", + "ci.workspace_path" => "/foo/bar", + "git.branch" => "master", + "git.commit.author.email" => "buildkite-git-commit-author-email@datadoghq.com", + "git.commit.author.name" => "buildkite-git-commit-author-name", + "git.commit.message" => "buildkite-git-commit-message", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "http://hostname.com/repo.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/circleci_spec.rb b/spec/datadog/ci/ext/environment/providers/circleci_spec.rb new file mode 100644 index 00000000..e0b08b13 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/circleci_spec.rb @@ -0,0 +1,49 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Circleci do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "CIRCLECI" => "circleCI", + "CIRCLE_BRANCH" => "origin/master", + "CIRCLE_BUILD_NUM" => "circleci-pipeline-number", + "CIRCLE_BUILD_URL" => "https://circleci-build-url.com/", + "CIRCLE_JOB" => "circleci-job-name", + "CIRCLE_PROJECT_REPONAME" => "circleci-pipeline-name", + "CIRCLE_REPOSITORY_URL" => "https://circleci-build-url.com/repo.git", + "CIRCLE_SHA1" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "CIRCLE_WORKFLOW_ID" => "circleci-pipeline-id", + "CIRCLE_WORKING_DIRECTORY" => "/foo/bar" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "_dd.ci.env_vars" => "{\"CIRCLE_WORKFLOW_ID\":\"circleci-pipeline-id\",\"CIRCLE_BUILD_NUM\":\"circleci-pipeline-number\"}", + "ci.job.name" => "circleci-job-name", + "ci.job.url" => "https://circleci-build-url.com/", + "ci.pipeline.id" => "circleci-pipeline-id", + "ci.pipeline.name" => "circleci-pipeline-name", + "ci.pipeline.url" => "https://app.circleci.com/pipelines/workflows/circleci-pipeline-id", + "ci.provider.name" => "circleci", + "ci.workspace_path" => "/foo/bar", + "git.branch" => "master", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://circleci-build-url.com/repo.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/codefresh_spec.rb b/spec/datadog/ci/ext/environment/providers/codefresh_spec.rb new file mode 100644 index 00000000..5285bb59 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/codefresh_spec.rb @@ -0,0 +1,38 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Codefresh do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "CF_BUILD_ID" => "6410367cee516146a4c4c66e", + "CF_BUILD_URL" => "https://g.codefresh.io/build/6410367cee516146a4c4c66e", + "CF_PIPELINE_NAME" => "My simple project/Example Java Project Pipeline", + "CF_STEP_NAME" => "mah-job-name" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "_dd.ci.env_vars" => "{\"CF_BUILD_ID\":\"6410367cee516146a4c4c66e\"}", + "ci.job.name" => "mah-job-name", + "ci.pipeline.id" => "6410367cee516146a4c4c66e", + "ci.pipeline.name" => "My simple project/Example Java Project Pipeline", + "ci.pipeline.url" => "https://g.codefresh.io/build/6410367cee516146a4c4c66e", + "ci.provider.name" => "codefresh" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/default_spec.rb b/spec/datadog/ci/ext/environment/providers/default_spec.rb new file mode 100644 index 00000000..b71a2ba0 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/default_spec.rb @@ -0,0 +1,27 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Default do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BUILD_URL" => "https://build.io/build/34432432", + "PIPELINE_NAME" => "My simple project" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) { {} } + + it "always returns empty hash" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/github_actions_spec.rb b/spec/datadog/ci/ext/environment/providers/github_actions_spec.rb new file mode 100644 index 00000000..cd37388b --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/github_actions_spec.rb @@ -0,0 +1,50 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::GithubActions do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "GITHUB_ACTION" => "run", + "GITHUB_JOB" => "github-job-name", + "GITHUB_REF" => "master", + "GITHUB_REPOSITORY" => "ghactions-repo", + "GITHUB_RUN_ID" => "ghactions-pipeline-id", + "GITHUB_RUN_NUMBER" => "ghactions-pipeline-number", + "GITHUB_SERVER_URL" => "https://ghenterprise.com", + "GITHUB_SHA" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "GITHUB_WORKFLOW" => "ghactions-pipeline-name", + "GITHUB_WORKSPACE" => "/foo/bar" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "_dd.ci.env_vars" => "{\"GITHUB_SERVER_URL\":\"https://ghenterprise.com\",\"GITHUB_REPOSITORY\":\"ghactions-repo\",\"GITHUB_RUN_ID\":\"ghactions-pipeline-id\"}", + "ci.job.name" => "github-job-name", + "ci.job.url" => "https://ghenterprise.com/ghactions-repo/commit/b9f0fb3fdbb94c9d24b2c75b49663122a529e123/checks", + "ci.pipeline.id" => "ghactions-pipeline-id", + "ci.pipeline.name" => "ghactions-pipeline-name", + "ci.pipeline.number" => "ghactions-pipeline-number", + "ci.pipeline.url" => "https://ghenterprise.com/ghactions-repo/actions/runs/ghactions-pipeline-id", + "ci.provider.name" => "github", + "ci.workspace_path" => "/foo/bar", + "git.branch" => "master", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://ghenterprise.com/ghactions-repo.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb b/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb new file mode 100644 index 00000000..9b22edb5 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb @@ -0,0 +1,78 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Gitlab do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "CI_COMMIT_AUTHOR" => "John Doe ", + "CI_COMMIT_MESSAGE" => "gitlab-git-commit-message", + "CI_COMMIT_REF_NAME" => "origin/master", + "CI_COMMIT_SHA" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "CI_COMMIT_TIMESTAMP" => "2021-07-21T11:43:07-04:00", + "CI_JOB_ID" => "gitlab-job-id", + "CI_JOB_NAME" => "gitlab-job-name", + "CI_JOB_STAGE" => "gitlab-stage-name", + "CI_JOB_URL" => "https://gitlab.com/job", + "CI_PIPELINE_ID" => "gitlab-pipeline-id", + "CI_PIPELINE_IID" => "gitlab-pipeline-number", + "CI_PIPELINE_URL" => "https://foo/repo/-/pipelines/1234", + "CI_PROJECT_DIR" => "foo/bar", + "CI_PROJECT_PATH" => "gitlab-pipeline-name", + "CI_PROJECT_URL" => "https://gitlab.com/repo", + "CI_REPOSITORY_URL" => "https://gitlab.com/repo/myrepo.git", + "GITLAB_CI" => "gitlab" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "_dd.ci.env_vars" => "{\"CI_PROJECT_URL\":\"https://gitlab.com/repo\",\"CI_PIPELINE_ID\":\"gitlab-pipeline-id\",\"CI_JOB_ID\":\"gitlab-job-id\"}", + "ci.job.name" => "gitlab-job-name", + "ci.job.url" => "https://gitlab.com/job", + "ci.pipeline.id" => "gitlab-pipeline-id", + "ci.pipeline.name" => "gitlab-pipeline-name", + "ci.pipeline.number" => "gitlab-pipeline-number", + "ci.pipeline.url" => "https://foo/repo/-/pipelines/1234", + "ci.provider.name" => "gitlab", + "ci.stage.name" => "gitlab-stage-name", + "ci.workspace_path" => "foo/bar", + "git.branch" => "master", + "git.commit.author.date" => "2021-07-21T11:43:07-04:00", + "git.commit.author.email" => "john@doe.com", + "git.commit.author.name" => "John Doe", + "git.commit.message" => "gitlab-git-commit-message", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://gitlab.com/repo/myrepo.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + + context "when CI_COMMIT_AUTHOR is malformed" do + context "no < symbol" do + let(:env) do + super().merge({"CI_COMMIT_AUTHOR" => "John Doe john@doe.com>"}) + end + + it "puts CI_COMMIT_AUTHOR under git.commit.author.email" do + is_expected.to eq( + expected_tags.except("git.commit.author.name").merge( + {"git.commit.author.email" => "John Doe john@doe.com>"} + ) + ) + end + end + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb b/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb new file mode 100644 index 00000000..464b03c5 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb @@ -0,0 +1,58 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Jenkins do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BUILD_NUMBER" => "jenkins-pipeline-number", + "BUILD_TAG" => "jenkins-pipeline-id", + "BUILD_URL" => "https://jenkins.com/pipeline", + "DD_CUSTOM_TRACE_ID" => "jenkins-custom-trace-id", + "GIT_BRANCH" => "origin/master", + "GIT_COMMIT" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "GIT_URL_1" => "https://jenkins.com/repo/sample.git", + "GIT_URL_2" => "https://jenkins.com/repo/otherSample.git", + "JENKINS_URL" => "jenkins", + "JOB_NAME" => "jobName/KEY1=VALUE1,KEY2=VALUE2/master", + "JOB_URL" => "https://jenkins.com/job" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "_dd.ci.env_vars" => "{\"DD_CUSTOM_TRACE_ID\":\"jenkins-custom-trace-id\"}", + "ci.pipeline.id" => "jenkins-pipeline-id", + "ci.pipeline.name" => "jobName", + "ci.pipeline.number" => "jenkins-pipeline-number", + "ci.pipeline.url" => "https://jenkins.com/pipeline", + "ci.provider.name" => "jenkins", + "git.branch" => "master", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://jenkins.com/repo/sample.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + + context "no git branch info" do + let(:env) do + super().except("GIT_BRANCH") + end + + it "does not remove branch name from job name" do + is_expected.to eq(expected_tags.except("git.branch").merge({"ci.pipeline.name" => "jobName/master"})) + end + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/teamcity_spec.rb b/spec/datadog/ci/ext/environment/providers/teamcity_spec.rb new file mode 100644 index 00000000..d9c23af4 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/teamcity_spec.rb @@ -0,0 +1,34 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Teamcity do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "BUILD_URL" => "https://teamcity.com/repo", + "TEAMCITY_BUILDCONF_NAME" => "Test 1", + "TEAMCITY_VERSION" => "2022.10 (build 116751)" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "ci.job.name" => "Test 1", + "ci.job.url" => "https://teamcity.com/repo", + "ci.provider.name" => "teamcity" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/travis_spec.rb b/spec/datadog/ci/ext/environment/providers/travis_spec.rb new file mode 100644 index 00000000..a86a9011 --- /dev/null +++ b/spec/datadog/ci/ext/environment/providers/travis_spec.rb @@ -0,0 +1,50 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Travis do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "TRAVIS" => "travisCI", + "TRAVIS_BRANCH" => "origin/tags/0.1.0", + "TRAVIS_BUILD_DIR" => "/foo/bar", + "TRAVIS_BUILD_ID" => "travis-pipeline-id", + "TRAVIS_BUILD_NUMBER" => "travis-pipeline-number", + "TRAVIS_BUILD_WEB_URL" => "https://travisci.com/pipeline", + "TRAVIS_COMMIT" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "TRAVIS_COMMIT_MESSAGE" => "travis-commit-message", + "TRAVIS_JOB_WEB_URL" => "https://travisci.com/job", + "TRAVIS_REPO_SLUG" => "user/repo", + "TRAVIS_TAG" => "origin/tags/0.1.0" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "ci.job.url" => "https://travisci.com/job", + "ci.pipeline.id" => "travis-pipeline-id", + "ci.pipeline.name" => "user/repo", + "ci.pipeline.number" => "travis-pipeline-number", + "ci.pipeline.url" => "https://travisci.com/pipeline", + "ci.provider.name" => "travisci", + "ci.workspace_path" => "/foo/bar", + "git.commit.message" => "travis-commit-message", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "https://github.com/user/repo.git", + "git.tag" => "0.1.0" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end From fe7573d20775e68864c104db71db7343ec64dbbd Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Tue, 5 Sep 2023 12:35:29 +0200 Subject: [PATCH 24/31] fix lint --- spec/datadog/ci/ext/environment/providers/azure_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/datadog/ci/ext/environment/providers/azure_spec.rb b/spec/datadog/ci/ext/environment/providers/azure_spec.rb index 357a4f00..93b30eed 100644 --- a/spec/datadog/ci/ext/environment/providers/azure_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/azure_spec.rb @@ -64,7 +64,7 @@ it "omits URLs" do is_expected.to eq( expected_tags.merge({ - "_dd.ci.env_vars" => "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":null,\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}", + "_dd.ci.env_vars" => "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":null,\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}" }).except("ci.pipeline.id", "ci.pipeline.number", "ci.pipeline.url", "ci.job.url") ) end From 0b57a4cb4d6bdf76089dc4fd0df1bd4003c23dba Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Tue, 5 Sep 2023 13:25:15 +0200 Subject: [PATCH 25/31] move fixtures to support, add specs for LocalGit and UserDefinedTags --- .../ci/ext/environment/local_git_spec.rb | 56 ++++++++++++++++++ .../ext/environment/user_defined_tags_spec.rb | 48 +++++++++++++++ spec/datadog/ci/ext/environment_spec.rb | 20 ++----- spec/spec_helper.rb | 1 + .../ext => support}/fixtures/ci/appveyor.json | 0 .../fixtures/ci/azurepipelines.json | 0 .../fixtures/ci/bitbucket.json | 0 .../ext => support}/fixtures/ci/bitrise.json | 0 .../ci/ext => support}/fixtures/ci/buddy.json | 0 .../fixtures/ci/buildkite.json | 0 .../ext => support}/fixtures/ci/circleci.json | 0 .../fixtures/ci/codefresh.json | 0 .../ext => support}/fixtures/ci/github.json | 0 .../ext => support}/fixtures/ci/gitlab.json | 0 .../ext => support}/fixtures/ci/jenkins.json | 0 .../ext => support}/fixtures/ci/teamcity.json | 0 .../ext => support}/fixtures/ci/travisci.json | 0 .../fixtures/ci/usersupplied.json | 0 .../fixtures/git/gitdir_empty/HEAD | 0 .../fixtures/git/gitdir_empty/config | 0 .../fixtures/git/gitdir_empty/objects/.keep | 0 .../fixtures/git/gitdir_empty/refs/.keep | 0 .../fixtures/git/gitdir_with_commit/HEAD | 0 .../fixtures/git/gitdir_with_commit/config | 0 .../fixtures/git/gitdir_with_commit/index | Bin .../fixtures/git/gitdir_with_commit/logs/HEAD | 0 .../gitdir_with_commit/logs/refs/heads/master | 0 .../3e/84e4841fc8f3c76e54fb1becaa8863a2cede30 | Bin .../4b/825dc642cb6eb9a060e54bf8d69288fbee4904 | Bin .../93/22ca1d57975b49b8c00b449d21b06660ce8b5b | Bin .../git/gitdir_with_commit/refs/heads/master | 0 .../git/gitdir_with_commit/refs/tags/v1.2.3 | 0 spec/support/git_helpers.rb | 11 ++++ 33 files changed, 120 insertions(+), 16 deletions(-) create mode 100644 spec/datadog/ci/ext/environment/local_git_spec.rb create mode 100644 spec/datadog/ci/ext/environment/user_defined_tags_spec.rb rename spec/{datadog/ci/ext => support}/fixtures/ci/appveyor.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/azurepipelines.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/bitbucket.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/bitrise.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/buddy.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/buildkite.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/circleci.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/codefresh.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/github.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/gitlab.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/jenkins.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/teamcity.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/travisci.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/ci/usersupplied.json (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_empty/HEAD (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_empty/config (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_empty/objects/.keep (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_empty/refs/.keep (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/HEAD (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/config (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/index (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/logs/HEAD (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/logs/refs/heads/master (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/objects/3e/84e4841fc8f3c76e54fb1becaa8863a2cede30 (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/objects/93/22ca1d57975b49b8c00b449d21b06660ce8b5b (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/refs/heads/master (100%) rename spec/{datadog/ci/ext => support}/fixtures/git/gitdir_with_commit/refs/tags/v1.2.3 (100%) create mode 100644 spec/support/git_helpers.rb diff --git a/spec/datadog/ci/ext/environment/local_git_spec.rb b/spec/datadog/ci/ext/environment/local_git_spec.rb new file mode 100644 index 00000000..007a9772 --- /dev/null +++ b/spec/datadog/ci/ext/environment/local_git_spec.rb @@ -0,0 +1,56 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::LocalGit do + let(:env) { {} } + let(:environment_variables) { {} } + + describe "#tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + context "example git repository" do + include_context "with git fixture", "gitdir_with_commit" + + let(:expected_tags) do + { + "ci.workspace_path" => "#{Dir.pwd}/spec/support/fixtures/git", + "git.branch" => "master", + "git.commit.author.date" => "2011-02-16T13:00:00+00:00", + "git.commit.author.email" => "bot@friendly.test", + "git.commit.author.name" => "Friendly bot", + "git.commit.committer.date" => "2021-06-17T18:35:10+00:00", + "git.commit.committer.email" => "marco.costa@datadoghq.com", + "git.commit.committer.name" => "Marco Costa", + "git.commit.message" => "First commit!", + "git.commit.sha" => "9322ca1d57975b49b8c00b449d21b06660ce8b5b", + "git.repository_url" => "https://datadoghq.com/git/test.git" + } + end + + it "matches expected tags" do + is_expected.to eq(expected_tags) + end + end + end + + describe "#committer" do + include_context "with git fixture", "gitdir_with_commit" + + subject(:committer_email) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags["git.commit.committer.email"] } + end + + it "returns committer from the latest commit in the repository" do + is_expected.to eq("marco.costa@datadoghq.com") + end + + context "when git show -s returns nothing" do + before do + allow(Open3).to receive(:capture2e).and_return(["", double(success?: true)]) + end + + it "returns nil and does not fail" do + is_expected.to be_nil + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/user_defined_tags_spec.rb b/spec/datadog/ci/ext/environment/user_defined_tags_spec.rb new file mode 100644 index 00000000..d852b7ae --- /dev/null +++ b/spec/datadog/ci/ext/environment/user_defined_tags_spec.rb @@ -0,0 +1,48 @@ +RSpec.describe ::Datadog::CI::Ext::Environment::UserDefinedTags do + describe ".tags" do + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) { described_class.new(env).tags } + end + + let(:env) { {} } + let(:environment_variables) { {} } + + context "example fixture" do + let(:env) do + { + "DD_GIT_BRANCH" => "usersupplied-branch", + "DD_GIT_COMMIT_AUTHOR_DATE" => "usersupplied-authordate", + "DD_GIT_COMMIT_AUTHOR_EMAIL" => "usersupplied-authoremail", + "DD_GIT_COMMIT_AUTHOR_NAME" => "usersupplied-authorname", + "DD_GIT_COMMIT_COMMITTER_DATE" => "usersupplied-comitterdate", + "DD_GIT_COMMIT_COMMITTER_EMAIL" => "usersupplied-comitteremail", + "DD_GIT_COMMIT_COMMITTER_NAME" => "usersupplied-comittername", + "DD_GIT_COMMIT_MESSAGE" => "usersupplied-message", + "DD_GIT_COMMIT_SHA" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "DD_GIT_REPOSITORY_URL" => "git@github.com:DataDog/userrepo.git" + } + end + # Modify HOME so that '~' expansion matches CI home directory. + let(:environment_variables) { super().merge("HOME" => env["HOME"]) } + + let(:expected_tags) do + { + "git.branch" => "usersupplied-branch", + "git.commit.author.date" => "usersupplied-authordate", + "git.commit.author.email" => "usersupplied-authoremail", + "git.commit.author.name" => "usersupplied-authorname", + "git.commit.committer.date" => "usersupplied-comitterdate", + "git.commit.committer.email" => "usersupplied-comitteremail", + "git.commit.committer.name" => "usersupplied-comittername", + "git.commit.message" => "usersupplied-message", + "git.commit.sha" => "b9f0fb3fdbb94c9d24b2c75b49663122a529e123", + "git.repository_url" => "git@github.com:DataDog/userrepo.git" + } + end + + it "matches CI tags" do + is_expected.to eq(expected_tags) + end + end + end +end diff --git a/spec/datadog/ci/ext/environment_spec.rb b/spec/datadog/ci/ext/environment_spec.rb index e910a590..15b280e7 100644 --- a/spec/datadog/ci/ext/environment_spec.rb +++ b/spec/datadog/ci/ext/environment_spec.rb @@ -1,8 +1,6 @@ require "json" RSpec.describe ::Datadog::CI::Ext::Environment do - FIXTURE_DIR = "#{File.dirname(__FILE__)}/fixtures/" # rubocop:disable all - let(:logger) { instance_double(Datadog::Core::Logger) } before do allow(Datadog).to receive(:logger).and_return(logger) @@ -18,16 +16,6 @@ let(:env) { {} } let(:environment_variables) { {} } - shared_context "with git fixture" do |git_fixture| - let(:environment_variables) do - super().merge("GIT_DIR" => "#{FIXTURE_DIR}/git/#{git_fixture}", "GIT_WORK_TREE" => "#{FIXTURE_DIR}/git/") - end - end - - shared_context "without git installed" do - before { allow(Open3).to receive(:capture2e).and_raise(Errno::ENOENT, "No such file or directory - git") } - end - Dir.glob("#{FIXTURE_DIR}/ci/*.json").sort.each do |filename| # Parse each CI provider file File.open(filename) do |f| @@ -46,7 +34,7 @@ is_expected .to eq( { - "ci.workspace_path" => "#{Dir.pwd}/spec/datadog/ci/ext/fixtures/git", + "ci.workspace_path" => "#{Dir.pwd}/spec/support/fixtures/git", "git.branch" => "master", "git.commit.author.date" => "2011-02-16T13:00:00+00:00", "git.commit.author.email" => "bot@friendly.test", @@ -79,7 +67,7 @@ context "with a newly created git repository" do include_context "with git fixture", "gitdir_empty" it "matches tags" do - is_expected.to eq("ci.workspace_path" => "#{Dir.pwd}/spec/datadog/ci/ext/fixtures/git") + is_expected.to eq("ci.workspace_path" => "#{Dir.pwd}/spec/support/fixtures/git") end end @@ -87,7 +75,7 @@ include_context "with git fixture", "gitdir_with_commit" it "matches tags" do is_expected.to eq( - "ci.workspace_path" => "#{Dir.pwd}/spec/datadog/ci/ext/fixtures/git", + "ci.workspace_path" => "#{Dir.pwd}/spec/support/fixtures/git", "git.branch" => "master", "git.commit.author.date" => "2011-02-16T13:00:00+00:00", "git.commit.author.email" => "bot@friendly.test", @@ -143,7 +131,7 @@ it "returns user provided metadata" do is_expected.to eq( { - "ci.workspace_path" => "#{Dir.pwd}/spec/datadog/ci/ext/fixtures/git", + "ci.workspace_path" => "#{Dir.pwd}/spec/support/fixtures/git", "git.branch" => env["DD_GIT_BRANCH"], "git.tag" => env["DD_GIT_TAG"], "git.commit.author.date" => env["DD_GIT_COMMIT_AUTHOR_DATE"], diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9670bf67..3a0d1b4c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,6 +14,7 @@ require_relative "support/span_helpers" require_relative "support/test_helpers" require_relative "support/platform_helpers" +require_relative "support/git_helpers" require "rspec/collection_matchers" require "climate_control" diff --git a/spec/datadog/ci/ext/fixtures/ci/appveyor.json b/spec/support/fixtures/ci/appveyor.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/appveyor.json rename to spec/support/fixtures/ci/appveyor.json diff --git a/spec/datadog/ci/ext/fixtures/ci/azurepipelines.json b/spec/support/fixtures/ci/azurepipelines.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/azurepipelines.json rename to spec/support/fixtures/ci/azurepipelines.json diff --git a/spec/datadog/ci/ext/fixtures/ci/bitbucket.json b/spec/support/fixtures/ci/bitbucket.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/bitbucket.json rename to spec/support/fixtures/ci/bitbucket.json diff --git a/spec/datadog/ci/ext/fixtures/ci/bitrise.json b/spec/support/fixtures/ci/bitrise.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/bitrise.json rename to spec/support/fixtures/ci/bitrise.json diff --git a/spec/datadog/ci/ext/fixtures/ci/buddy.json b/spec/support/fixtures/ci/buddy.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/buddy.json rename to spec/support/fixtures/ci/buddy.json diff --git a/spec/datadog/ci/ext/fixtures/ci/buildkite.json b/spec/support/fixtures/ci/buildkite.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/buildkite.json rename to spec/support/fixtures/ci/buildkite.json diff --git a/spec/datadog/ci/ext/fixtures/ci/circleci.json b/spec/support/fixtures/ci/circleci.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/circleci.json rename to spec/support/fixtures/ci/circleci.json diff --git a/spec/datadog/ci/ext/fixtures/ci/codefresh.json b/spec/support/fixtures/ci/codefresh.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/codefresh.json rename to spec/support/fixtures/ci/codefresh.json diff --git a/spec/datadog/ci/ext/fixtures/ci/github.json b/spec/support/fixtures/ci/github.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/github.json rename to spec/support/fixtures/ci/github.json diff --git a/spec/datadog/ci/ext/fixtures/ci/gitlab.json b/spec/support/fixtures/ci/gitlab.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/gitlab.json rename to spec/support/fixtures/ci/gitlab.json diff --git a/spec/datadog/ci/ext/fixtures/ci/jenkins.json b/spec/support/fixtures/ci/jenkins.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/jenkins.json rename to spec/support/fixtures/ci/jenkins.json diff --git a/spec/datadog/ci/ext/fixtures/ci/teamcity.json b/spec/support/fixtures/ci/teamcity.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/teamcity.json rename to spec/support/fixtures/ci/teamcity.json diff --git a/spec/datadog/ci/ext/fixtures/ci/travisci.json b/spec/support/fixtures/ci/travisci.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/travisci.json rename to spec/support/fixtures/ci/travisci.json diff --git a/spec/datadog/ci/ext/fixtures/ci/usersupplied.json b/spec/support/fixtures/ci/usersupplied.json similarity index 100% rename from spec/datadog/ci/ext/fixtures/ci/usersupplied.json rename to spec/support/fixtures/ci/usersupplied.json diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_empty/HEAD b/spec/support/fixtures/git/gitdir_empty/HEAD similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_empty/HEAD rename to spec/support/fixtures/git/gitdir_empty/HEAD diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_empty/config b/spec/support/fixtures/git/gitdir_empty/config similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_empty/config rename to spec/support/fixtures/git/gitdir_empty/config diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_empty/objects/.keep b/spec/support/fixtures/git/gitdir_empty/objects/.keep similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_empty/objects/.keep rename to spec/support/fixtures/git/gitdir_empty/objects/.keep diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_empty/refs/.keep b/spec/support/fixtures/git/gitdir_empty/refs/.keep similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_empty/refs/.keep rename to spec/support/fixtures/git/gitdir_empty/refs/.keep diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/HEAD b/spec/support/fixtures/git/gitdir_with_commit/HEAD similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/HEAD rename to spec/support/fixtures/git/gitdir_with_commit/HEAD diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/config b/spec/support/fixtures/git/gitdir_with_commit/config similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/config rename to spec/support/fixtures/git/gitdir_with_commit/config diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/index b/spec/support/fixtures/git/gitdir_with_commit/index similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/index rename to spec/support/fixtures/git/gitdir_with_commit/index diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/logs/HEAD b/spec/support/fixtures/git/gitdir_with_commit/logs/HEAD similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/logs/HEAD rename to spec/support/fixtures/git/gitdir_with_commit/logs/HEAD diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/logs/refs/heads/master b/spec/support/fixtures/git/gitdir_with_commit/logs/refs/heads/master similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/logs/refs/heads/master rename to spec/support/fixtures/git/gitdir_with_commit/logs/refs/heads/master diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/objects/3e/84e4841fc8f3c76e54fb1becaa8863a2cede30 b/spec/support/fixtures/git/gitdir_with_commit/objects/3e/84e4841fc8f3c76e54fb1becaa8863a2cede30 similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/objects/3e/84e4841fc8f3c76e54fb1becaa8863a2cede30 rename to spec/support/fixtures/git/gitdir_with_commit/objects/3e/84e4841fc8f3c76e54fb1becaa8863a2cede30 diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/spec/support/fixtures/git/gitdir_with_commit/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 rename to spec/support/fixtures/git/gitdir_with_commit/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/objects/93/22ca1d57975b49b8c00b449d21b06660ce8b5b b/spec/support/fixtures/git/gitdir_with_commit/objects/93/22ca1d57975b49b8c00b449d21b06660ce8b5b similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/objects/93/22ca1d57975b49b8c00b449d21b06660ce8b5b rename to spec/support/fixtures/git/gitdir_with_commit/objects/93/22ca1d57975b49b8c00b449d21b06660ce8b5b diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/refs/heads/master b/spec/support/fixtures/git/gitdir_with_commit/refs/heads/master similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/refs/heads/master rename to spec/support/fixtures/git/gitdir_with_commit/refs/heads/master diff --git a/spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/refs/tags/v1.2.3 b/spec/support/fixtures/git/gitdir_with_commit/refs/tags/v1.2.3 similarity index 100% rename from spec/datadog/ci/ext/fixtures/git/gitdir_with_commit/refs/tags/v1.2.3 rename to spec/support/fixtures/git/gitdir_with_commit/refs/tags/v1.2.3 diff --git a/spec/support/git_helpers.rb b/spec/support/git_helpers.rb new file mode 100644 index 00000000..70579e9d --- /dev/null +++ b/spec/support/git_helpers.rb @@ -0,0 +1,11 @@ +FIXTURE_DIR = "#{File.dirname(__FILE__)}/fixtures/" # rubocop:disable all + +shared_context "with git fixture" do |git_fixture| + let(:environment_variables) do + super().merge("GIT_DIR" => "#{FIXTURE_DIR}/git/#{git_fixture}", "GIT_WORK_TREE" => "#{FIXTURE_DIR}/git/") + end +end + +shared_context "without git installed" do + before { allow(Open3).to receive(:capture2e).and_raise(Errno::ENOENT, "No such file or directory - git") } +end From ba4bbbab6d6b038798ab135ad0974edf17091f9d Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Tue, 5 Sep 2023 13:35:45 +0200 Subject: [PATCH 26/31] ruby 2.7 does not have Hash#except --- .../environment/providers/appveyor_spec.rb | 20 +++++++++++++++--- .../ext/environment/providers/azure_spec.rb | 21 +++++++++++++------ .../environment/providers/bitbucket_spec.rb | 15 +++++++++++-- .../ext/environment/providers/gitlab_spec.rb | 12 ++++++----- .../ext/environment/providers/jenkins_spec.rb | 12 +++++++++-- 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb b/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb index 5521196b..207a3d23 100644 --- a/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb @@ -50,15 +50,29 @@ end context "when commit message is not provided" do - let(:env) { super().except("APPVEYOR_REPO_COMMIT_MESSAGE") } + let(:env) do + hash = super() + hash.delete("APPVEYOR_REPO_COMMIT_MESSAGE") + hash + end + + let(:expected_tags) do + hash = super() + hash.delete("git.commit.message") + hash + end it "omits git.commit.message" do - is_expected.to eq(expected_tags.except("git.commit.message")) + is_expected.to eq(expected_tags) end end context "when extended commit message is not provided" do - let(:env) { super().except("APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED") } + let(:env) do + hash = super() + hash.delete("APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED") + hash + end it "does not append extended commit message" do is_expected.to eq(expected_tags.merge({"git.commit.message" => "appveyor-commit-message"})) diff --git a/spec/datadog/ci/ext/environment/providers/azure_spec.rb b/spec/datadog/ci/ext/environment/providers/azure_spec.rb index 93b30eed..a2134f3d 100644 --- a/spec/datadog/ci/ext/environment/providers/azure_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/azure_spec.rb @@ -58,15 +58,24 @@ context "when pipeline URL cannot be defined" do let(:env) do - super().except("BUILD_BUILDID") + hash = super() + hash.delete("BUILD_BUILDID") + hash + end + + let(:expected_tags) do + hash = super() + hash.merge!({ + "_dd.ci.env_vars" => "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":null,\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}" + }) + ["ci.pipeline.id", "ci.pipeline.number", "ci.pipeline.url", "ci.job.url"].each do |key| + hash.delete(key) + end + hash end it "omits URLs" do - is_expected.to eq( - expected_tags.merge({ - "_dd.ci.env_vars" => "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":null,\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}" - }).except("ci.pipeline.id", "ci.pipeline.number", "ci.pipeline.url", "ci.job.url") - ) + is_expected.to eq(expected_tags) end end end diff --git a/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb b/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb index e1f4a2ee..7f1b8e6a 100644 --- a/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb @@ -42,9 +42,20 @@ end context "when no BITBUCKET_PIPELINE_UUID provided" do - let(:env) { super().except("BITBUCKET_PIPELINE_UUID") } + let(:env) do + hash = super() + hash.delete("BITBUCKET_PIPELINE_UUID") + hash + end + + let(:expected_tags) do + hash = super() + hash.delete("ci.pipeline.id") + hash + end + it "omits pipeline_id" do - is_expected.to eq(expected_tags.except("ci.pipeline.id")) + is_expected.to eq(expected_tags) end end end diff --git a/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb b/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb index 9b22edb5..bbccdb16 100644 --- a/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb @@ -64,12 +64,14 @@ super().merge({"CI_COMMIT_AUTHOR" => "John Doe john@doe.com>"}) end + let(:expected_tags) do + hash = super() + hash.delete("git.commit.author.name") + hash.merge({"git.commit.author.email" => "John Doe john@doe.com>"}) + end + it "puts CI_COMMIT_AUTHOR under git.commit.author.email" do - is_expected.to eq( - expected_tags.except("git.commit.author.name").merge( - {"git.commit.author.email" => "John Doe john@doe.com>"} - ) - ) + is_expected.to eq(expected_tags) end end end diff --git a/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb b/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb index 464b03c5..e4776c71 100644 --- a/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb @@ -46,11 +46,19 @@ context "no git branch info" do let(:env) do - super().except("GIT_BRANCH") + hash = super() + hash.delete("GIT_BRANCH") + hash + end + + let(:expected_tags) do + hash = super() + hash.delete("git.branch") + hash.merge({"ci.pipeline.name" => "jobName/master"}) end it "does not remove branch name from job name" do - is_expected.to eq(expected_tags.except("git.branch").merge({"ci.pipeline.name" => "jobName/master"})) + is_expected.to eq(expected_tags) end end end From 99b2e08e476499bb5ec80adb07668e326f7cce6c Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Tue, 5 Sep 2023 13:40:17 +0200 Subject: [PATCH 27/31] fix lint --- spec/datadog/ci/ext/environment/providers/azure_spec.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spec/datadog/ci/ext/environment/providers/azure_spec.rb b/spec/datadog/ci/ext/environment/providers/azure_spec.rb index a2134f3d..85f9544f 100644 --- a/spec/datadog/ci/ext/environment/providers/azure_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/azure_spec.rb @@ -65,9 +65,7 @@ let(:expected_tags) do hash = super() - hash.merge!({ - "_dd.ci.env_vars" => "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":null,\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}" - }) + hash["_dd.ci.env_vars"] = "{\"SYSTEM_TEAMPROJECTID\":\"azure-pipelines-project-id\",\"BUILD_BUILDID\":null,\"SYSTEM_JOBID\":\"azure-pipelines-job-id\"}" ["ci.pipeline.id", "ci.pipeline.number", "ci.pipeline.url", "ci.job.url"].each do |key| hash.delete(key) end From d94a26aeef90cb7244ce9a12fea3b4975053c8cc Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Wed, 6 Sep 2023 09:41:46 +0200 Subject: [PATCH 28/31] show alternative code organization around provider and extractor --- lib/datadog/ci/ext/environment.rb | 8 +- lib/datadog/ci/ext/environment/extractor.rb | 185 +++--------------- lib/datadog/ci/ext/environment/providers.rb | 49 +++++ .../ci/ext/environment/providers/appveyor.rb | 4 +- .../ci/ext/environment/providers/azure.rb | 4 +- .../ci/ext/environment/providers/base.rb | 110 +++++++++++ .../ci/ext/environment/providers/bitbucket.rb | 4 +- .../ci/ext/environment/providers/bitrise.rb | 4 +- .../ci/ext/environment/providers/buddy.rb | 4 +- .../ci/ext/environment/providers/buildkite.rb | 4 +- .../ci/ext/environment/providers/circleci.rb | 4 +- .../ci/ext/environment/providers/codefresh.rb | 4 +- .../ci/ext/environment/providers/default.rb | 4 +- .../environment/providers/github_actions.rb | 4 +- .../ci/ext/environment/providers/gitlab.rb | 4 +- .../ci/ext/environment/providers/jenkins.rb | 4 +- .../environment/{ => providers}/local_git.rb | 6 +- .../ci/ext/environment/providers/teamcity.rb | 4 +- .../ci/ext/environment/providers/travis.rb | 4 +- .../providers/user_defined_tags.rb | 64 ++++++ .../ci/ext/environment/user_defined_tags.rb | 62 ------ 21 files changed, 284 insertions(+), 256 deletions(-) create mode 100644 lib/datadog/ci/ext/environment/providers.rb create mode 100644 lib/datadog/ci/ext/environment/providers/base.rb rename lib/datadog/ci/ext/environment/{ => providers}/local_git.rb (98%) create mode 100644 lib/datadog/ci/ext/environment/providers/user_defined_tags.rb delete mode 100644 lib/datadog/ci/ext/environment/user_defined_tags.rb diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 3b2c2114..7fca12bc 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -2,8 +2,6 @@ require_relative "git" require_relative "environment/extractor" -require_relative "environment/user_defined_tags" -require_relative "environment/local_git" module Datadog module CI @@ -29,15 +27,15 @@ module Environment def tags(env) # Extract metadata from CI provider environment variables - tags = Environment::Extractor.for_environment(env).tags + tags = Environment::Extractor.new(env).tags # If user defined metadata is defined, overwrite tags.merge!( - UserDefinedTags.new(env).tags + Environment::Extractor.new(env, provider: Providers::UserDefinedTags).tags ) # Fill out tags from local git as fallback - local_git_tags = LocalGit.new(env).tags + local_git_tags = Environment::Extractor.new(env, provider: Providers::LocalGit).tags local_git_tags.each do |key, value| tags[key] ||= value end diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 354093fb..31ce2001 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -2,6 +2,7 @@ require_relative "../environment" require_relative "../git" +require_relative "providers" module Datadog module CI @@ -11,76 +12,39 @@ module Environment # Extractor is responsible for detecting where pipeline is being executed based on environment vars # and return the specific extractor that is able to return environment- and git-specific tags class Extractor - require_relative "providers/default" - require_relative "providers/appveyor" - require_relative "providers/azure" - require_relative "providers/bitbucket" - require_relative "providers/bitrise" - require_relative "providers/buddy" - require_relative "providers/buildkite" - require_relative "providers/circleci" - require_relative "providers/codefresh" - require_relative "providers/github_actions" - require_relative "providers/gitlab" - require_relative "providers/jenkins" - require_relative "providers/teamcity" - require_relative "providers/travis" - - PROVIDERS = [ - ["APPVEYOR", Providers::Appveyor], - ["TF_BUILD", Providers::Azure], - ["BITBUCKET_COMMIT", Providers::Bitbucket], - ["BITRISE_BUILD_SLUG", Providers::Bitrise], - ["BUDDY", Providers::Buddy], - ["BUILDKITE", Providers::Buildkite], - ["CIRCLECI", Providers::Circleci], - ["CF_BUILD_ID", Providers::Codefresh], - ["GITHUB_SHA", Providers::GithubActions], - ["GITLAB_CI", Providers::Gitlab], - ["JENKINS_URL", Providers::Jenkins], - ["TEAMCITY_VERSION", Providers::Teamcity], - ["TRAVIS", Providers::Travis] - ] - - def self.for_environment(env) - _, extractor_klass = PROVIDERS.find { |provider_env_var, _| env.key?(provider_env_var) } - extractor_klass = Providers::Default if extractor_klass.nil? - - extractor_klass.new(env) - end - - def initialize(env) + def initialize(env, provider: nil) @env = env + @provider = provider || Providers.for_environment(env) end def tags return @tags if defined?(@tags) @tags = { - Environment::TAG_JOB_NAME => job_name, - Environment::TAG_JOB_URL => job_url, - Environment::TAG_PIPELINE_ID => pipeline_id, - Environment::TAG_PIPELINE_NAME => pipeline_name, - Environment::TAG_PIPELINE_NUMBER => pipeline_number, - Environment::TAG_PIPELINE_URL => pipeline_url, - Environment::TAG_PROVIDER_NAME => provider_name, - Environment::TAG_STAGE_NAME => stage_name, - Environment::TAG_WORKSPACE_PATH => workspace_path, - Environment::TAG_NODE_LABELS => node_labels, - Environment::TAG_NODE_NAME => node_name, - Environment::TAG_CI_ENV_VARS => ci_env_vars, - - Git::TAG_BRANCH => git_branch, - Git::TAG_REPOSITORY_URL => git_repository_url, - Git::TAG_TAG => git_tag, - Git::TAG_COMMIT_AUTHOR_DATE => git_commit_author_date, - Git::TAG_COMMIT_AUTHOR_EMAIL => git_commit_author_email, - Git::TAG_COMMIT_AUTHOR_NAME => git_commit_author_name, - Git::TAG_COMMIT_COMMITTER_DATE => git_commit_committer_date, - Git::TAG_COMMIT_COMMITTER_EMAIL => git_commit_committer_email, - Git::TAG_COMMIT_COMMITTER_NAME => git_commit_committer_name, - Git::TAG_COMMIT_MESSAGE => git_commit_message, - Git::TAG_COMMIT_SHA => git_commit_sha + Environment::TAG_JOB_NAME => @provider.job_name, + Environment::TAG_JOB_URL => @provider.job_url, + Environment::TAG_PIPELINE_ID => @provider.pipeline_id, + Environment::TAG_PIPELINE_NAME => @provider.pipeline_name, + Environment::TAG_PIPELINE_NUMBER => @provider.pipeline_number, + Environment::TAG_PIPELINE_URL => @provider.pipeline_url, + Environment::TAG_PROVIDER_NAME => @provider.provider_name, + Environment::TAG_STAGE_NAME => @provider.stage_name, + Environment::TAG_WORKSPACE_PATH => @provider.workspace_path, + Environment::TAG_NODE_LABELS => @provider.node_labels, + Environment::TAG_NODE_NAME => @provider.node_name, + Environment::TAG_CI_ENV_VARS => @provider.ci_env_vars, + + Git::TAG_BRANCH => @provider.git_branch, + Git::TAG_REPOSITORY_URL => @provider.git_repository_url, + Git::TAG_TAG => @provider.git_tag, + Git::TAG_COMMIT_AUTHOR_DATE => @provider.git_commit_author_date, + Git::TAG_COMMIT_AUTHOR_EMAIL => @provider.git_commit_author_email, + Git::TAG_COMMIT_AUTHOR_NAME => @provider.git_commit_author_name, + Git::TAG_COMMIT_COMMITTER_DATE => @provider.git_commit_committer_date, + Git::TAG_COMMIT_COMMITTER_EMAIL => @provider.git_commit_committer_email, + Git::TAG_COMMIT_COMMITTER_NAME => @provider.git_commit_committer_name, + Git::TAG_COMMIT_MESSAGE => @provider.git_commit_message, + Git::TAG_COMMIT_SHA => @provider.git_commit_sha } # Normalize Git references and filter sensitive data @@ -102,88 +66,6 @@ def tags private - attr_reader :env - - def job_name - end - - def job_url - end - - def pipeline_id - end - - def pipeline_name - end - - def pipeline_number - end - - def pipeline_url - end - - def provider_name - end - - def stage_name - end - - def workspace_path - end - - def node_labels - end - - def node_name - end - - def ci_env_vars - end - - def git_branch - return @branch if defined?(@branch) - - set_branch_and_tag - @branch - end - - def git_repository_url - end - - def git_tag - return @tag if defined?(@tag) - - set_branch_and_tag - @tag - end - - def git_branch_or_tag - end - - def git_commit_author_date - end - - def git_commit_author_email - end - - def git_commit_author_name - end - - def git_commit_committer_date - end - - def git_commit_committer_email - end - - def git_commit_committer_name - end - - def git_commit_message - end - - def git_commit_sha - end - def normalize_git! branch_ref = @tags[Git::TAG_BRANCH] if is_git_tag?(branch_ref) @@ -210,19 +92,6 @@ def is_git_tag?(ref) !ref.nil? && ref.include?("tags/") end - def set_branch_and_tag - branch_or_tag_string = git_branch_or_tag - @branch = @tag = nil - - if branch_or_tag_string && branch_or_tag_string.include?("tags/") - @tag = branch_or_tag_string - else - @branch = branch_or_tag_string - end - - [@branch, @tag] - end - def normalize_ref(name) return nil if name.nil? diff --git a/lib/datadog/ci/ext/environment/providers.rb b/lib/datadog/ci/ext/environment/providers.rb new file mode 100644 index 00000000..16ffe0d7 --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require_relative "providers/default" +require_relative "providers/appveyor" +require_relative "providers/azure" +require_relative "providers/bitbucket" +require_relative "providers/bitrise" +require_relative "providers/buddy" +require_relative "providers/buildkite" +require_relative "providers/circleci" +require_relative "providers/codefresh" +require_relative "providers/github_actions" +require_relative "providers/gitlab" +require_relative "providers/jenkins" +require_relative "providers/teamcity" +require_relative "providers/travis" + +module Datadog + module CI + module Ext + module Environment + module Providers + PROVIDERS = [ + ["APPVEYOR", Providers::Appveyor], + ["TF_BUILD", Providers::Azure], + ["BITBUCKET_COMMIT", Providers::Bitbucket], + ["BITRISE_BUILD_SLUG", Providers::Bitrise], + ["BUDDY", Providers::Buddy], + ["BUILDKITE", Providers::Buildkite], + ["CIRCLECI", Providers::Circleci], + ["CF_BUILD_ID", Providers::Codefresh], + ["GITHUB_SHA", Providers::GithubActions], + ["GITLAB_CI", Providers::Gitlab], + ["JENKINS_URL", Providers::Jenkins], + ["TEAMCITY_VERSION", Providers::Teamcity], + ["TRAVIS", Providers::Travis] + ] + + def self.for_environment(env) + _, provider_klass = PROVIDERS.find { |provider_env_var, _| env.key?(provider_env_var) } + provider_klass = Providers::Default if provider_klass.nil? + + provider_klass.new(env) + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/providers/appveyor.rb b/lib/datadog/ci/ext/environment/providers/appveyor.rb index 26ea0aca..c7cca337 100644 --- a/lib/datadog/ci/ext/environment/providers/appveyor.rb +++ b/lib/datadog/ci/ext/environment/providers/appveyor.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -9,7 +9,7 @@ module Environment module Providers # Appveyor: https://www.appveyor.com/ # Environment variables docs: https://www.appveyor.com/docs/environment-variables/ - class Appveyor < Extractor + class Appveyor < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/azure.rb b/lib/datadog/ci/ext/environment/providers/azure.rb index 903a4625..da570cb6 100644 --- a/lib/datadog/ci/ext/environment/providers/azure.rb +++ b/lib/datadog/ci/ext/environment/providers/azure.rb @@ -2,7 +2,7 @@ require "json" -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -11,7 +11,7 @@ module Environment module Providers # Azure Pipelines: https://azure.microsoft.com/en-us/products/devops/pipelines # Environment variables docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml - class Azure < Extractor + class Azure < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/base.rb b/lib/datadog/ci/ext/environment/providers/base.rb new file mode 100644 index 00000000..2c6e3eab --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/base.rb @@ -0,0 +1,110 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Base + attr_reader :env + + def initialize(env) + @env = env + end + + def job_name + end + + def job_url + end + + def pipeline_id + end + + def pipeline_name + end + + def pipeline_number + end + + def pipeline_url + end + + def provider_name + end + + def stage_name + end + + def workspace_path + end + + def node_labels + end + + def node_name + end + + def ci_env_vars + end + + def git_branch + return @branch if defined?(@branch) + + set_branch_and_tag + @branch + end + + def git_repository_url + end + + def git_tag + return @tag if defined?(@tag) + + set_branch_and_tag + @tag + end + + def git_branch_or_tag + end + + def git_commit_author_date + end + + def git_commit_author_email + end + + def git_commit_author_name + end + + def git_commit_committer_date + end + + def git_commit_committer_email + end + + def git_commit_committer_name + end + + def git_commit_message + end + + def git_commit_sha + end + + def set_branch_and_tag + branch_or_tag_string = git_branch_or_tag + @branch = @tag = nil + + if branch_or_tag_string && branch_or_tag_string.include?("tags/") + @tag = branch_or_tag_string + else + @branch = branch_or_tag_string + end + + [@branch, @tag] + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/providers/bitbucket.rb b/lib/datadog/ci/ext/environment/providers/bitbucket.rb index e6bc4fb7..e8350c73 100644 --- a/lib/datadog/ci/ext/environment/providers/bitbucket.rb +++ b/lib/datadog/ci/ext/environment/providers/bitbucket.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -9,7 +9,7 @@ module Environment module Providers # Bitbucket Pipelines: https://bitbucket.org/product/features/pipelines # Environment variables docs: https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ - class Bitbucket < Extractor + class Bitbucket < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/bitrise.rb b/lib/datadog/ci/ext/environment/providers/bitrise.rb index 5bdba80f..bffdf499 100644 --- a/lib/datadog/ci/ext/environment/providers/bitrise.rb +++ b/lib/datadog/ci/ext/environment/providers/bitrise.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -9,7 +9,7 @@ module Environment module Providers # Bitrise: https://bitrise.io/ # Environment variables docs: https://devcenter.bitrise.io/en/references/available-environment-variables.html - class Bitrise < Extractor + class Bitrise < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/buddy.rb b/lib/datadog/ci/ext/environment/providers/buddy.rb index f2518a57..59a370de 100644 --- a/lib/datadog/ci/ext/environment/providers/buddy.rb +++ b/lib/datadog/ci/ext/environment/providers/buddy.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -9,7 +9,7 @@ module Environment module Providers # Buddy: https://buddy.works/ # Environment variables docs: https://buddy.works/docs/pipelines/environment-variables - class Buddy < Extractor + class Buddy < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/buildkite.rb b/lib/datadog/ci/ext/environment/providers/buildkite.rb index 6273a32b..6e6b9e93 100644 --- a/lib/datadog/ci/ext/environment/providers/buildkite.rb +++ b/lib/datadog/ci/ext/environment/providers/buildkite.rb @@ -2,7 +2,7 @@ require "json" -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -11,7 +11,7 @@ module Environment module Providers # Buildkite: https://buildkite.com/ # Environment variables docs: https://buildkite.com/docs/pipelines/environment-variables - class Buildkite < Extractor + class Buildkite < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/circleci.rb b/lib/datadog/ci/ext/environment/providers/circleci.rb index e8d06746..21471251 100644 --- a/lib/datadog/ci/ext/environment/providers/circleci.rb +++ b/lib/datadog/ci/ext/environment/providers/circleci.rb @@ -2,7 +2,7 @@ require "json" -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -11,7 +11,7 @@ module Environment module Providers # Circle CI: https://circleci.com/ # Environment variables docs: https://circleci.com/docs/variables/#built-in-environment-variables - class Circleci < Extractor + class Circleci < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/codefresh.rb b/lib/datadog/ci/ext/environment/providers/codefresh.rb index 5e29dc6a..8391756d 100644 --- a/lib/datadog/ci/ext/environment/providers/codefresh.rb +++ b/lib/datadog/ci/ext/environment/providers/codefresh.rb @@ -2,7 +2,7 @@ require "json" -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -11,7 +11,7 @@ module Environment module Providers # Codefresh: https://codefresh.io/ # Environment variables docs: https://codefresh.io/docs/docs/pipelines/variables/#export-variables-to-all-steps-with-cf_export - class Codefresh < Extractor + class Codefresh < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/default.rb b/lib/datadog/ci/ext/environment/providers/default.rb index 53864611..67b98312 100644 --- a/lib/datadog/ci/ext/environment/providers/default.rb +++ b/lib/datadog/ci/ext/environment/providers/default.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -8,7 +8,7 @@ module Ext module Environment module Providers # TODO - class Default < Extractor + class Default < Base def tags {} end diff --git a/lib/datadog/ci/ext/environment/providers/github_actions.rb b/lib/datadog/ci/ext/environment/providers/github_actions.rb index 18be6437..978ac1fe 100644 --- a/lib/datadog/ci/ext/environment/providers/github_actions.rb +++ b/lib/datadog/ci/ext/environment/providers/github_actions.rb @@ -2,7 +2,7 @@ require "json" -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -11,7 +11,7 @@ module Environment module Providers # Github Actions: https://github.com/features/actions # Environment variables docs: https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables - class GithubActions < Extractor + class GithubActions < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/gitlab.rb b/lib/datadog/ci/ext/environment/providers/gitlab.rb index bad709cb..677a9f68 100644 --- a/lib/datadog/ci/ext/environment/providers/gitlab.rb +++ b/lib/datadog/ci/ext/environment/providers/gitlab.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -9,7 +9,7 @@ module Environment module Providers # Gitlab CI: https://docs.gitlab.com/ee/ci/ # Environment variables docs: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html - class Gitlab < Extractor + class Gitlab < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/jenkins.rb b/lib/datadog/ci/ext/environment/providers/jenkins.rb index 28ce887e..4e7a7cc6 100644 --- a/lib/datadog/ci/ext/environment/providers/jenkins.rb +++ b/lib/datadog/ci/ext/environment/providers/jenkins.rb @@ -2,7 +2,7 @@ require "json" -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -11,7 +11,7 @@ module Environment module Providers # Jenkins: https://www.jenkins.io/ # Environment variables docs: https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables - class Jenkins < Extractor + class Jenkins < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/local_git.rb b/lib/datadog/ci/ext/environment/providers/local_git.rb similarity index 98% rename from lib/datadog/ci/ext/environment/local_git.rb rename to lib/datadog/ci/ext/environment/providers/local_git.rb index 4b2e7bd3..3064783d 100644 --- a/lib/datadog/ci/ext/environment/local_git.rb +++ b/lib/datadog/ci/ext/environment/providers/local_git.rb @@ -2,15 +2,15 @@ require "open3" -require_relative "extractor" -require_relative "../git" +require_relative "base" +require_relative "../../git" module Datadog module CI module Ext module Environment # As a fallback we try to fetch git information from the local git repository - class LocalGit < Extractor + class LocalGit < Base private def git_repository_url diff --git a/lib/datadog/ci/ext/environment/providers/teamcity.rb b/lib/datadog/ci/ext/environment/providers/teamcity.rb index 80143942..9dd28cd0 100644 --- a/lib/datadog/ci/ext/environment/providers/teamcity.rb +++ b/lib/datadog/ci/ext/environment/providers/teamcity.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -9,7 +9,7 @@ module Environment module Providers # Teamcity: https://www.jetbrains.com/teamcity/ # Environment variables docs: https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html - class Teamcity < Extractor + class Teamcity < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/travis.rb b/lib/datadog/ci/ext/environment/providers/travis.rb index 4196e215..521b80b4 100644 --- a/lib/datadog/ci/ext/environment/providers/travis.rb +++ b/lib/datadog/ci/ext/environment/providers/travis.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../extractor" +require_relative "base" module Datadog module CI @@ -9,7 +9,7 @@ module Environment module Providers # Travis CI: https://www.travis-ci.com/ # Environment variables docs: https://docs.travis-ci.com/user/environment-variables#default-environment-variables - class Travis < Extractor + class Travis < Base private # overridden methods diff --git a/lib/datadog/ci/ext/environment/providers/user_defined_tags.rb b/lib/datadog/ci/ext/environment/providers/user_defined_tags.rb new file mode 100644 index 00000000..414a050c --- /dev/null +++ b/lib/datadog/ci/ext/environment/providers/user_defined_tags.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require_relative "base" +require_relative "../../git" + +module Datadog + module CI + module Ext + module Environment + module Providers + # Parses user defined git data from the environment variables + # User documentation: https://docs.datadoghq.com/continuous_integration/troubleshooting/#data-appears-in-test-runs-but-not-tests + class UserDefinedTags < Base + private + + def git_repository_url + env[Git::ENV_REPOSITORY_URL] + end + + def git_commit_sha + env[Git::ENV_COMMIT_SHA] + end + + def git_branch + env[Git::ENV_BRANCH] + end + + def git_tag + env[Git::ENV_TAG] + end + + def git_commit_message + env[Git::ENV_COMMIT_MESSAGE] + end + + def git_commit_author_name + env[Git::ENV_COMMIT_AUTHOR_NAME] + end + + def git_commit_author_email + env[Git::ENV_COMMIT_AUTHOR_EMAIL] + end + + def git_commit_author_date + env[Git::ENV_COMMIT_AUTHOR_DATE] + end + + def git_commit_committer_name + env[Git::ENV_COMMIT_COMMITTER_NAME] + end + + def git_commit_committer_email + env[Git::ENV_COMMIT_COMMITTER_EMAIL] + end + + def git_commit_committer_date + env[Git::ENV_COMMIT_COMMITTER_DATE] + end + end + end + end + end + end +end diff --git a/lib/datadog/ci/ext/environment/user_defined_tags.rb b/lib/datadog/ci/ext/environment/user_defined_tags.rb deleted file mode 100644 index 0f3e14d9..00000000 --- a/lib/datadog/ci/ext/environment/user_defined_tags.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require_relative "extractor" -require_relative "../git" - -module Datadog - module CI - module Ext - module Environment - # Parses user defined git data from the environment variables - # User documentation: https://docs.datadoghq.com/continuous_integration/troubleshooting/#data-appears-in-test-runs-but-not-tests - class UserDefinedTags < Extractor - private - - def git_repository_url - env[Git::ENV_REPOSITORY_URL] - end - - def git_commit_sha - env[Git::ENV_COMMIT_SHA] - end - - def git_branch - env[Git::ENV_BRANCH] - end - - def git_tag - env[Git::ENV_TAG] - end - - def git_commit_message - env[Git::ENV_COMMIT_MESSAGE] - end - - def git_commit_author_name - env[Git::ENV_COMMIT_AUTHOR_NAME] - end - - def git_commit_author_email - env[Git::ENV_COMMIT_AUTHOR_EMAIL] - end - - def git_commit_author_date - env[Git::ENV_COMMIT_AUTHOR_DATE] - end - - def git_commit_committer_name - env[Git::ENV_COMMIT_COMMITTER_NAME] - end - - def git_commit_committer_email - env[Git::ENV_COMMIT_COMMITTER_EMAIL] - end - - def git_commit_committer_date - env[Git::ENV_COMMIT_COMMITTER_DATE] - end - end - end - end - end -end From 7066de30a3cbdae26b21e18ea840ce1700f7811b Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Wed, 6 Sep 2023 12:57:15 +0200 Subject: [PATCH 29/31] fixing tests, extracting git utility to Utils::Git module, fix signatures --- lib/datadog/ci/ext/environment.rb | 6 +- lib/datadog/ci/ext/environment/extractor.rb | 20 +- lib/datadog/ci/ext/environment/providers.rb | 4 +- .../ci/ext/environment/providers/appveyor.rb | 5 +- .../ci/ext/environment/providers/azure.rb | 5 +- .../ci/ext/environment/providers/base.rb | 3 + .../ci/ext/environment/providers/bitbucket.rb | 4 +- .../ci/ext/environment/providers/bitrise.rb | 3 - .../ci/ext/environment/providers/buddy.rb | 3 - .../ci/ext/environment/providers/buildkite.rb | 3 - .../ci/ext/environment/providers/circleci.rb | 3 - .../ci/ext/environment/providers/codefresh.rb | 3 - .../ci/ext/environment/providers/default.rb | 20 -- .../environment/providers/github_actions.rb | 3 - .../ci/ext/environment/providers/gitlab.rb | 5 +- .../ci/ext/environment/providers/jenkins.rb | 6 +- .../ci/ext/environment/providers/local_git.rb | 241 +++++++++--------- .../ci/ext/environment/providers/teamcity.rb | 3 - .../ci/ext/environment/providers/travis.rb | 3 - .../providers/user_defined_tags.rb | 4 +- lib/datadog/ci/utils/git.rb | 22 ++ sig/datadog/ci/ext/environment/extractor.rbs | 64 +---- sig/datadog/ci/ext/environment/local_git.rbs | 64 ----- .../{providers/default.rbs => providers.rbs} | 6 +- .../ci/ext/environment/providers/appveyor.rbs | 6 +- .../ci/ext/environment/providers/azure.rbs | 6 +- .../ci/ext/environment/providers/base.rbs | 69 +++++ .../ext/environment/providers/bitbucket.rbs | 5 +- .../ci/ext/environment/providers/bitrise.rbs | 3 +- .../ci/ext/environment/providers/buddy.rbs | 1 - .../ext/environment/providers/buildkite.rbs | 1 - .../ci/ext/environment/providers/circleci.rbs | 1 - .../ext/environment/providers/codefresh.rbs | 1 - .../environment/providers/github_actions.rbs | 1 - .../ci/ext/environment/providers/gitlab.rbs | 4 +- .../ci/ext/environment/providers/jenkins.rbs | 3 +- .../ext/environment/providers/local_git.rbs | 66 +++++ .../ci/ext/environment/providers/teamcity.rbs | 1 - .../ci/ext/environment/providers/travis.rbs | 1 - .../providers/user_defined_tags.rbs | 33 +++ .../ci/ext/environment/user_defined_tags.rbs | 31 --- sig/datadog/ci/utils/git.rbs | 11 + .../environment/providers/appveyor_spec.rb | 7 +- .../ext/environment/providers/azure_spec.rb | 7 +- .../{default_spec.rb => base_spec.rb} | 9 +- .../environment/providers/bitbucket_spec.rb | 7 +- .../ext/environment/providers/bitrise_spec.rb | 7 +- .../ext/environment/providers/buddy_spec.rb | 7 +- .../environment/providers/buildkite_spec.rb | 7 +- .../environment/providers/circleci_spec.rb | 7 +- .../environment/providers/codefresh_spec.rb | 7 +- .../providers/github_actions_spec.rb | 7 +- .../ext/environment/providers/gitlab_spec.rb | 7 +- .../ext/environment/providers/jenkins_spec.rb | 7 +- .../{ => providers}/local_git_spec.rb | 8 +- .../environment/providers/teamcity_spec.rb | 7 +- .../ext/environment/providers/travis_spec.rb | 7 +- .../{ => providers}/user_defined_tags_spec.rb | 9 +- spec/spec_helper.rb | 1 + spec/support/provider_test_helpers.rb | 14 + 60 files changed, 396 insertions(+), 483 deletions(-) delete mode 100644 lib/datadog/ci/ext/environment/providers/default.rb create mode 100644 lib/datadog/ci/utils/git.rb delete mode 100644 sig/datadog/ci/ext/environment/local_git.rbs rename sig/datadog/ci/ext/environment/{providers/default.rbs => providers.rbs} (50%) create mode 100644 sig/datadog/ci/ext/environment/providers/base.rbs create mode 100644 sig/datadog/ci/ext/environment/providers/local_git.rbs create mode 100644 sig/datadog/ci/ext/environment/providers/user_defined_tags.rbs delete mode 100644 sig/datadog/ci/ext/environment/user_defined_tags.rbs create mode 100644 sig/datadog/ci/utils/git.rbs rename spec/datadog/ci/ext/environment/providers/{default_spec.rb => base_spec.rb} (66%) rename spec/datadog/ci/ext/environment/{ => providers}/local_git_spec.rb (87%) rename spec/datadog/ci/ext/environment/{ => providers}/user_defined_tags_spec.rb (87%) create mode 100644 spec/support/provider_test_helpers.rb diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 7fca12bc..4d1bd32e 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -2,6 +2,8 @@ require_relative "git" require_relative "environment/extractor" +require_relative "environment/providers/local_git" +require_relative "environment/providers/user_defined_tags" module Datadog module CI @@ -31,11 +33,11 @@ def tags(env) # If user defined metadata is defined, overwrite tags.merge!( - Environment::Extractor.new(env, provider: Providers::UserDefinedTags).tags + Environment::Extractor.new(env, provider: Providers::UserDefinedTags.new(env)).tags ) # Fill out tags from local git as fallback - local_git_tags = Environment::Extractor.new(env, provider: Providers::LocalGit).tags + local_git_tags = Environment::Extractor.new(env, provider: Providers::LocalGit.new(env)).tags local_git_tags.each do |key, value| tags[key] ||= value end diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index 31ce2001..d3b55cf6 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -2,6 +2,7 @@ require_relative "../environment" require_relative "../git" +require_relative "../../utils/git" require_relative "providers" module Datadog @@ -68,13 +69,13 @@ def tags def normalize_git! branch_ref = @tags[Git::TAG_BRANCH] - if is_git_tag?(branch_ref) + if Datadog::CI::Utils::Git.is_git_tag?(branch_ref) @tags[Git::TAG_TAG] = branch_ref @tags.delete(Git::TAG_BRANCH) end - @tags[Git::TAG_TAG] = normalize_ref(@tags[Git::TAG_TAG]) - @tags[Git::TAG_BRANCH] = normalize_ref(@tags[Git::TAG_BRANCH]) + @tags[Git::TAG_TAG] = Datadog::CI::Utils::Git.normalize_ref(@tags[Git::TAG_TAG]) + @tags[Git::TAG_BRANCH] = Datadog::CI::Utils::Git.normalize_ref(@tags[Git::TAG_BRANCH]) @tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info( @tags[Git::TAG_REPOSITORY_URL] ) @@ -88,19 +89,6 @@ def expand_workspace! end end - def is_git_tag?(ref) - !ref.nil? && ref.include?("tags/") - end - - def normalize_ref(name) - return nil if name.nil? - - refs = %r{^refs/(heads/)?} - origin = %r{^origin/} - tags = %r{^tags/} - name.gsub(refs, "").gsub(origin, "").gsub(tags, "") - end - def filter_sensitive_info(url) return nil if url.nil? diff --git a/lib/datadog/ci/ext/environment/providers.rb b/lib/datadog/ci/ext/environment/providers.rb index 16ffe0d7..0e854dd0 100644 --- a/lib/datadog/ci/ext/environment/providers.rb +++ b/lib/datadog/ci/ext/environment/providers.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "providers/default" +require_relative "providers/base" require_relative "providers/appveyor" require_relative "providers/azure" require_relative "providers/bitbucket" @@ -38,7 +38,7 @@ module Providers def self.for_environment(env) _, provider_klass = PROVIDERS.find { |provider_env_var, _| env.key?(provider_env_var) } - provider_klass = Providers::Default if provider_klass.nil? + provider_klass = Providers::Base if provider_klass.nil? provider_klass.new(env) end diff --git a/lib/datadog/ci/ext/environment/providers/appveyor.rb b/lib/datadog/ci/ext/environment/providers/appveyor.rb index c7cca337..09c7881f 100644 --- a/lib/datadog/ci/ext/environment/providers/appveyor.rb +++ b/lib/datadog/ci/ext/environment/providers/appveyor.rb @@ -10,9 +10,6 @@ module Providers # Appveyor: https://www.appveyor.com/ # Environment variables docs: https://www.appveyor.com/docs/environment-variables/ class Appveyor < Base - private - - # overridden methods def provider_name "appveyor" end @@ -82,7 +79,7 @@ def git_commit_message commit_message end - # appveyor-specific methods + private def github_repo_provider? return @github_repo_provider if defined?(@github_repo_provider) diff --git a/lib/datadog/ci/ext/environment/providers/azure.rb b/lib/datadog/ci/ext/environment/providers/azure.rb index da570cb6..f80ab243 100644 --- a/lib/datadog/ci/ext/environment/providers/azure.rb +++ b/lib/datadog/ci/ext/environment/providers/azure.rb @@ -12,9 +12,6 @@ module Providers # Azure Pipelines: https://azure.microsoft.com/en-us/products/devops/pipelines # Environment variables docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml class Azure < Base - private - - # overridden methods def provider_name "azurepipelines" end @@ -87,7 +84,7 @@ def ci_env_vars }.to_json end - # azure-specific methods + private def build_id env["BUILD_BUILDID"] diff --git a/lib/datadog/ci/ext/environment/providers/base.rb b/lib/datadog/ci/ext/environment/providers/base.rb index 2c6e3eab..77d1682c 100644 --- a/lib/datadog/ci/ext/environment/providers/base.rb +++ b/lib/datadog/ci/ext/environment/providers/base.rb @@ -90,10 +90,13 @@ def git_commit_message def git_commit_sha end + private + def set_branch_and_tag branch_or_tag_string = git_branch_or_tag @branch = @tag = nil + # @type var branch_or_tag_string: untyped if branch_or_tag_string && branch_or_tag_string.include?("tags/") @tag = branch_or_tag_string else diff --git a/lib/datadog/ci/ext/environment/providers/bitbucket.rb b/lib/datadog/ci/ext/environment/providers/bitbucket.rb index e8350c73..e5a0bed1 100644 --- a/lib/datadog/ci/ext/environment/providers/bitbucket.rb +++ b/lib/datadog/ci/ext/environment/providers/bitbucket.rb @@ -10,8 +10,6 @@ module Providers # Bitbucket Pipelines: https://bitbucket.org/product/features/pipelines # Environment variables docs: https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/ class Bitbucket < Base - private - # overridden methods def provider_name "bitbucket" @@ -57,7 +55,7 @@ def git_tag env["BITBUCKET_TAG"] end - # bitbucket-specific methods + private def url "https://bitbucket.org/#{env["BITBUCKET_REPO_FULL_NAME"]}/addon/pipelines/home#" \ diff --git a/lib/datadog/ci/ext/environment/providers/bitrise.rb b/lib/datadog/ci/ext/environment/providers/bitrise.rb index bffdf499..6e35d382 100644 --- a/lib/datadog/ci/ext/environment/providers/bitrise.rb +++ b/lib/datadog/ci/ext/environment/providers/bitrise.rb @@ -10,9 +10,6 @@ module Providers # Bitrise: https://bitrise.io/ # Environment variables docs: https://devcenter.bitrise.io/en/references/available-environment-variables.html class Bitrise < Base - private - - # overridden methods def provider_name "bitrise" end diff --git a/lib/datadog/ci/ext/environment/providers/buddy.rb b/lib/datadog/ci/ext/environment/providers/buddy.rb index 59a370de..91d7332d 100644 --- a/lib/datadog/ci/ext/environment/providers/buddy.rb +++ b/lib/datadog/ci/ext/environment/providers/buddy.rb @@ -10,9 +10,6 @@ module Providers # Buddy: https://buddy.works/ # Environment variables docs: https://buddy.works/docs/pipelines/environment-variables class Buddy < Base - private - - # overridden methods def provider_name "buddy" end diff --git a/lib/datadog/ci/ext/environment/providers/buildkite.rb b/lib/datadog/ci/ext/environment/providers/buildkite.rb index 6e6b9e93..4fa1bbfe 100644 --- a/lib/datadog/ci/ext/environment/providers/buildkite.rb +++ b/lib/datadog/ci/ext/environment/providers/buildkite.rb @@ -12,9 +12,6 @@ module Providers # Buildkite: https://buildkite.com/ # Environment variables docs: https://buildkite.com/docs/pipelines/environment-variables class Buildkite < Base - private - - # overridden methods def provider_name "buildkite" end diff --git a/lib/datadog/ci/ext/environment/providers/circleci.rb b/lib/datadog/ci/ext/environment/providers/circleci.rb index 21471251..fd65e656 100644 --- a/lib/datadog/ci/ext/environment/providers/circleci.rb +++ b/lib/datadog/ci/ext/environment/providers/circleci.rb @@ -12,9 +12,6 @@ module Providers # Circle CI: https://circleci.com/ # Environment variables docs: https://circleci.com/docs/variables/#built-in-environment-variables class Circleci < Base - private - - # overridden methods def provider_name "circleci" end diff --git a/lib/datadog/ci/ext/environment/providers/codefresh.rb b/lib/datadog/ci/ext/environment/providers/codefresh.rb index 8391756d..2dd5ffea 100644 --- a/lib/datadog/ci/ext/environment/providers/codefresh.rb +++ b/lib/datadog/ci/ext/environment/providers/codefresh.rb @@ -12,9 +12,6 @@ module Providers # Codefresh: https://codefresh.io/ # Environment variables docs: https://codefresh.io/docs/docs/pipelines/variables/#export-variables-to-all-steps-with-cf_export class Codefresh < Base - private - - # overridden methods def provider_name "codefresh" end diff --git a/lib/datadog/ci/ext/environment/providers/default.rb b/lib/datadog/ci/ext/environment/providers/default.rb deleted file mode 100644 index 67b98312..00000000 --- a/lib/datadog/ci/ext/environment/providers/default.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require_relative "base" - -module Datadog - module CI - module Ext - module Environment - module Providers - # TODO - class Default < Base - def tags - {} - end - end - end - end - end - end -end diff --git a/lib/datadog/ci/ext/environment/providers/github_actions.rb b/lib/datadog/ci/ext/environment/providers/github_actions.rb index 978ac1fe..f5fe7861 100644 --- a/lib/datadog/ci/ext/environment/providers/github_actions.rb +++ b/lib/datadog/ci/ext/environment/providers/github_actions.rb @@ -12,9 +12,6 @@ module Providers # Github Actions: https://github.com/features/actions # Environment variables docs: https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables class GithubActions < Base - private - - # overridden methods def provider_name "github" end diff --git a/lib/datadog/ci/ext/environment/providers/gitlab.rb b/lib/datadog/ci/ext/environment/providers/gitlab.rb index 677a9f68..28ea27ba 100644 --- a/lib/datadog/ci/ext/environment/providers/gitlab.rb +++ b/lib/datadog/ci/ext/environment/providers/gitlab.rb @@ -10,9 +10,6 @@ module Providers # Gitlab CI: https://docs.gitlab.com/ee/ci/ # Environment variables docs: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html class Gitlab < Base - private - - # overridden methods def provider_name "gitlab" end @@ -99,7 +96,7 @@ def ci_env_vars }.to_json end - # gitlab-specific methods + private def extract_name_email return @name_email_tuple if defined?(@name_email_tuple) diff --git a/lib/datadog/ci/ext/environment/providers/jenkins.rb b/lib/datadog/ci/ext/environment/providers/jenkins.rb index 4e7a7cc6..f60918c3 100644 --- a/lib/datadog/ci/ext/environment/providers/jenkins.rb +++ b/lib/datadog/ci/ext/environment/providers/jenkins.rb @@ -3,6 +3,7 @@ require "json" require_relative "base" +require_relative "../../../utils/git" module Datadog module CI @@ -12,9 +13,6 @@ module Providers # Jenkins: https://www.jenkins.io/ # Environment variables docs: https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables class Jenkins < Base - private - - # overridden methods def provider_name "jenkins" end @@ -25,7 +23,7 @@ def pipeline_id def pipeline_name if (name = env["JOB_NAME"]) - name = name.gsub("/#{normalize_ref(git_branch)}", "") if git_branch + name = name.gsub("/#{Datadog::CI::Utils::Git.normalize_ref(git_branch)}", "") if git_branch name = name.split("/").reject { |v| v.nil? || v.include?("=") }.join("/") end name diff --git a/lib/datadog/ci/ext/environment/providers/local_git.rb b/lib/datadog/ci/ext/environment/providers/local_git.rb index 3064783d..ed56b590 100644 --- a/lib/datadog/ci/ext/environment/providers/local_git.rb +++ b/lib/datadog/ci/ext/environment/providers/local_git.rb @@ -9,157 +9,158 @@ module Datadog module CI module Ext module Environment - # As a fallback we try to fetch git information from the local git repository - class LocalGit < Base - private - - def git_repository_url - exec_git_command("git ls-remote --get-url") - rescue => e - Datadog.logger.debug( - "Unable to read git repository url: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end + module Providers + # As a fallback we try to fetch git information from the local git repository + class LocalGit < Base + def git_repository_url + exec_git_command("git ls-remote --get-url") + rescue => e + Datadog.logger.debug( + "Unable to read git repository url: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end - def git_commit_sha - exec_git_command("git rev-parse HEAD") - rescue => e - Datadog.logger.debug( - "Unable to read git commit SHA: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end + def git_commit_sha + exec_git_command("git rev-parse HEAD") + rescue => e + Datadog.logger.debug( + "Unable to read git commit SHA: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end - def git_branch - exec_git_command("git rev-parse --abbrev-ref HEAD") - rescue => e - Datadog.logger.debug( - "Unable to read git branch: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end + def git_branch + exec_git_command("git rev-parse --abbrev-ref HEAD") + rescue => e + Datadog.logger.debug( + "Unable to read git branch: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end - def git_tag - exec_git_command("git tag --points-at HEAD") - rescue => e - Datadog.logger.debug( - "Unable to read git tag: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end + def git_tag + exec_git_command("git tag --points-at HEAD") + rescue => e + Datadog.logger.debug( + "Unable to read git tag: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end - def git_commit_message - exec_git_command("git show -s --format=%s") - rescue => e - Datadog.logger.debug( - "Unable to read git commit message: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end + def git_commit_message + exec_git_command("git show -s --format=%s") + rescue => e + Datadog.logger.debug( + "Unable to read git commit message: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end - def git_commit_author_name - author.name - end + def git_commit_author_name + author.name + end - def git_commit_author_email - author.email - end + def git_commit_author_email + author.email + end - def git_commit_author_date - author.date - end + def git_commit_author_date + author.date + end - def git_commit_committer_name - committer.name - end + def git_commit_committer_name + committer.name + end - def git_commit_committer_email - committer.email - end + def git_commit_committer_email + committer.email + end - def git_commit_committer_date - committer.date - end + def git_commit_committer_date + committer.date + end - def workspace_path - exec_git_command("git rev-parse --show-toplevel") - rescue => e - Datadog.logger.debug( - "Unable to read git base directory: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - nil - end + def workspace_path + exec_git_command("git rev-parse --show-toplevel") + rescue => e + Datadog.logger.debug( + "Unable to read git base directory: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" + ) + nil + end - # local git specific methods - def exec_git_command(cmd) - out, status = Open3.capture2e(cmd) + private - raise "Failed to run git command #{cmd}: #{out}" unless status.success? + def exec_git_command(cmd) + out, status = Open3.capture2e(cmd) - out.strip! # There's always a "\n" at the end of the command output + raise "Failed to run git command #{cmd}: #{out}" unless status.success? - return nil if out.empty? + out.strip! # There's always a "\n" at the end of the command output - out - end + return nil if out.empty? - def author - return @author if defined?(@author) + out + end - set_git_commit_users - @author - end + def author + return @author if defined?(@author) - def committer - return @committer if defined?(@committer) + set_git_commit_users + @author + end - set_git_commit_users - @committer - end + def committer + return @committer if defined?(@committer) + + set_git_commit_users + @committer + end - def set_git_commit_users - # Get committer and author information in one command. - output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'") - unless output + def set_git_commit_users + # Get committer and author information in one command. + output = exec_git_command("git show -s --format='%an\t%ae\t%at\t%cn\t%ce\t%ct'") + unless output + Datadog.logger.debug( + "Unable to read git commit users: git command output is nil" + ) + @author = @committer = NilUser.new + return + end + + author_name, author_email, author_timestamp, + committer_name, committer_email, committer_timestamp = output.split("\t").each(&:strip!) + + @author = GitUser.new(author_name, author_email, author_timestamp) + @committer = GitUser.new(committer_name, committer_email, committer_timestamp) + rescue => e Datadog.logger.debug( - "Unable to read git commit users: git command output is nil" + "Unable to read git commit users: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" ) @author = @committer = NilUser.new - return end - author_name, author_email, author_timestamp, - committer_name, committer_email, committer_timestamp = output.split("\t").each(&:strip!) - - @author = GitUser.new(author_name, author_email, author_timestamp) - @committer = GitUser.new(committer_name, committer_email, committer_timestamp) - rescue => e - Datadog.logger.debug( - "Unable to read git commit users: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}" - ) - @author = @committer = NilUser.new - end - - class GitUser - attr_reader :name, :email, :timestamp + class GitUser + attr_reader :name, :email, :timestamp - def initialize(name, email, timestamp) - @name = name - @email = email - @timestamp = timestamp - end + def initialize(name, email, timestamp) + @name = name + @email = email + @timestamp = timestamp + end - def date - return nil if timestamp.nil? + def date + return nil if timestamp.nil? - Time.at(timestamp.to_i).utc.to_datetime.iso8601 + Time.at(timestamp.to_i).utc.to_datetime.iso8601 + end end - end - class NilUser < GitUser - def initialize - super(nil, nil, nil) + class NilUser < GitUser + def initialize + super(nil, nil, nil) + end end end end diff --git a/lib/datadog/ci/ext/environment/providers/teamcity.rb b/lib/datadog/ci/ext/environment/providers/teamcity.rb index 9dd28cd0..f57d17d2 100644 --- a/lib/datadog/ci/ext/environment/providers/teamcity.rb +++ b/lib/datadog/ci/ext/environment/providers/teamcity.rb @@ -10,9 +10,6 @@ module Providers # Teamcity: https://www.jetbrains.com/teamcity/ # Environment variables docs: https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html class Teamcity < Base - private - - # overridden methods def provider_name "teamcity" end diff --git a/lib/datadog/ci/ext/environment/providers/travis.rb b/lib/datadog/ci/ext/environment/providers/travis.rb index 521b80b4..0d175f67 100644 --- a/lib/datadog/ci/ext/environment/providers/travis.rb +++ b/lib/datadog/ci/ext/environment/providers/travis.rb @@ -10,9 +10,6 @@ module Providers # Travis CI: https://www.travis-ci.com/ # Environment variables docs: https://docs.travis-ci.com/user/environment-variables#default-environment-variables class Travis < Base - private - - # overridden methods def provider_name "travisci" end diff --git a/lib/datadog/ci/ext/environment/providers/user_defined_tags.rb b/lib/datadog/ci/ext/environment/providers/user_defined_tags.rb index 414a050c..ce099ddc 100644 --- a/lib/datadog/ci/ext/environment/providers/user_defined_tags.rb +++ b/lib/datadog/ci/ext/environment/providers/user_defined_tags.rb @@ -10,9 +10,7 @@ module Environment module Providers # Parses user defined git data from the environment variables # User documentation: https://docs.datadoghq.com/continuous_integration/troubleshooting/#data-appears-in-test-runs-but-not-tests - class UserDefinedTags < Base - private - + class UserDefinedTags < Base def git_repository_url env[Git::ENV_REPOSITORY_URL] end diff --git a/lib/datadog/ci/utils/git.rb b/lib/datadog/ci/utils/git.rb new file mode 100644 index 00000000..0afe8c7a --- /dev/null +++ b/lib/datadog/ci/utils/git.rb @@ -0,0 +1,22 @@ +module Datadog + module CI + module Utils + module Git + module_function + + def normalize_ref(name) + return nil if name.nil? + + refs = %r{^refs/(heads/)?} + origin = %r{^origin/} + tags = %r{^tags/} + name.gsub(refs, "").gsub(origin, "").gsub(tags, "") + end + + def is_git_tag?(ref) + !ref.nil? && ref.include?("tags/") + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index b9a0f256..1ccf644c 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -3,15 +3,11 @@ module Datadog module Ext module Environment class Extractor - - PROVIDERS: ::Array[[String, singleton(Extractor)]] + @env: Hash[String, String?] + @provider: Providers::Base @tags: Hash[String, untyped] - @branch: String? - @tag: String? - - def self.for_environment: (untyped env) -> Extractor - def initialize: (Hash[String, String] env) -> void + def initialize: (Hash[String, String?] env, ?provider: Providers::Base?) -> void def tags: () -> Hash[String, untyped] @@ -19,64 +15,10 @@ module Datadog attr_reader env: untyped - def job_name: () -> String? - - def job_url: () -> String? - - def pipeline_id: () -> String? - - def pipeline_name: () -> String? - - def pipeline_number: () -> String? - - def pipeline_url: () -> String? - - def provider_name: () -> String? - - def stage_name: () -> String? - - def workspace_path: () -> String? - - def node_labels: () -> String? - - def node_name: () -> String? - - def ci_env_vars: () -> String? - - def git_branch: () -> String? - - def git_repository_url: () -> String? - - def git_tag: () -> String? - - def git_branch_or_tag: () -> String? - - def git_commit_author_date: () -> String? - - def git_commit_author_email: () -> String? - - def git_commit_author_name: () -> String? - - def git_commit_committer_date: () -> String? - - def git_commit_committer_email: () -> String? - - def git_commit_committer_name: () -> String? - - def git_commit_message: () -> String? - - def git_commit_sha: () -> String? - - def set_branch_and_tag: () -> [String?, String?] - def normalize_git!: () -> void def expand_workspace!: () -> void - def is_git_tag?: (String? ref) -> bool - - def normalize_ref: (String? name) -> String? - def filter_sensitive_info: (String? url) -> String? end end diff --git a/sig/datadog/ci/ext/environment/local_git.rbs b/sig/datadog/ci/ext/environment/local_git.rbs deleted file mode 100644 index fbc497d8..00000000 --- a/sig/datadog/ci/ext/environment/local_git.rbs +++ /dev/null @@ -1,64 +0,0 @@ -module Datadog - module CI - module Ext - module Environment - class LocalGit < Extractor - class GitUser - attr_reader name: String? - attr_reader email: String? - attr_reader timestamp: String? - - @name: String? - @email: String? - @timestamp: String? - - def initialize: (String? name, String? email, String? timestamp) -> void - - def date: () -> String? - end - - class NilUser < GitUser - def initialize: () -> void - end - - private - - @author: GitUser - @committer: GitUser - - def git_repository_url: () -> String? - - def git_commit_sha: () -> String? - - def git_branch: () -> String? - - def git_tag: () -> String? - - def git_commit_message: () -> String? - - def git_commit_author_name: () -> String? - - def git_commit_author_email: () -> String? - - def git_commit_author_date: () -> String? - - def git_commit_committer_name: () -> String? - - def git_commit_committer_email: () -> String? - - def git_commit_committer_date: () -> String? - - def workspace_path: () -> String? - - def exec_git_command: (String cmd) -> String? - - def author: () -> GitUser - - def committer: () -> GitUser - - def set_git_commit_users: () -> void - end - end - end - end -end diff --git a/sig/datadog/ci/ext/environment/providers/default.rbs b/sig/datadog/ci/ext/environment/providers.rbs similarity index 50% rename from sig/datadog/ci/ext/environment/providers/default.rbs rename to sig/datadog/ci/ext/environment/providers.rbs index 2b00c8fa..21a7fb5b 100644 --- a/sig/datadog/ci/ext/environment/providers/default.rbs +++ b/sig/datadog/ci/ext/environment/providers.rbs @@ -3,9 +3,9 @@ module Datadog module Ext module Environment module Providers - class Default < Extractor - def tags: () -> ::Hash[String, untyped] - end + PROVIDERS: ::Array[[String, untyped]] + + def self.for_environment: (Hash[String, String?] env) -> Providers::Base end end end diff --git a/sig/datadog/ci/ext/environment/providers/appveyor.rbs b/sig/datadog/ci/ext/environment/providers/appveyor.rbs index 1508c74d..2868d732 100644 --- a/sig/datadog/ci/ext/environment/providers/appveyor.rbs +++ b/sig/datadog/ci/ext/environment/providers/appveyor.rbs @@ -3,9 +3,7 @@ module Datadog module Ext module Environment module Providers - class Appveyor < Extractor - private - + class Appveyor < Base @github_repo_provider: bool @url: String @@ -39,6 +37,8 @@ module Datadog def github_repo_provider?: () -> bool + private + def url: () -> String? end end diff --git a/sig/datadog/ci/ext/environment/providers/azure.rbs b/sig/datadog/ci/ext/environment/providers/azure.rbs index 847b1d73..52daa08c 100644 --- a/sig/datadog/ci/ext/environment/providers/azure.rbs +++ b/sig/datadog/ci/ext/environment/providers/azure.rbs @@ -3,9 +3,7 @@ module Datadog module Ext module Environment module Providers - class Azure < Extractor - private - + class Azure < Base @pipeline_url: String @job_url: String @@ -41,6 +39,8 @@ module Datadog def ci_env_vars: () -> String? + private + def build_id: () -> String? def team_foundation_server_uri: () -> String? diff --git a/sig/datadog/ci/ext/environment/providers/base.rbs b/sig/datadog/ci/ext/environment/providers/base.rbs new file mode 100644 index 00000000..2b46f5f9 --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/base.rbs @@ -0,0 +1,69 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class Base + attr_reader env: Hash[String, String?] + @branch: String? + @tag: String? + + def initialize: (Hash[String, String?] env) -> void + + def job_name: () -> nil + + def job_url: () -> nil + + def pipeline_id: () -> nil + + def pipeline_name: () -> nil + + def pipeline_number: () -> nil + + def pipeline_url: () -> nil + + def provider_name: () -> nil + + def stage_name: () -> nil + + def workspace_path: () -> nil + + def node_labels: () -> nil + + def node_name: () -> nil + + def ci_env_vars: () -> nil + + def git_branch: () -> String? + + def git_repository_url: () -> nil + + def git_tag: () -> String? + + def git_branch_or_tag: () -> nil + + def git_commit_author_date: () -> nil + + def git_commit_author_email: () -> nil + + def git_commit_author_name: () -> nil + + def git_commit_committer_date: () -> nil + + def git_commit_committer_email: () -> nil + + def git_commit_committer_name: () -> nil + + def git_commit_message: () -> nil + + def git_commit_sha: () -> nil + + private + + def set_branch_and_tag: () -> [String?, String?] + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/bitbucket.rbs b/sig/datadog/ci/ext/environment/providers/bitbucket.rbs index 3dbe8af9..72ce9304 100644 --- a/sig/datadog/ci/ext/environment/providers/bitbucket.rbs +++ b/sig/datadog/ci/ext/environment/providers/bitbucket.rbs @@ -3,8 +3,7 @@ module Datadog module Ext module Environment module Providers - class Bitbucket < Extractor - private + class Bitbucket < Base def provider_name: () -> "bitbucket" def pipeline_id: () -> String? @@ -27,6 +26,8 @@ module Datadog def git_tag: () -> String? + private + def url: () -> ::String? end end diff --git a/sig/datadog/ci/ext/environment/providers/bitrise.rbs b/sig/datadog/ci/ext/environment/providers/bitrise.rbs index 0e718107..51c53a8e 100644 --- a/sig/datadog/ci/ext/environment/providers/bitrise.rbs +++ b/sig/datadog/ci/ext/environment/providers/bitrise.rbs @@ -3,8 +3,7 @@ module Datadog module Ext module Environment module Providers - class Bitrise < Extractor - private + class Bitrise < Base def provider_name: () -> "bitrise" def pipeline_id: () -> String? diff --git a/sig/datadog/ci/ext/environment/providers/buddy.rbs b/sig/datadog/ci/ext/environment/providers/buddy.rbs index 07f01a1c..ac34a4bf 100644 --- a/sig/datadog/ci/ext/environment/providers/buddy.rbs +++ b/sig/datadog/ci/ext/environment/providers/buddy.rbs @@ -4,7 +4,6 @@ module Datadog module Environment module Providers class Buddy < Extractor - private def provider_name: () -> "buddy" def pipeline_id: () -> ::String diff --git a/sig/datadog/ci/ext/environment/providers/buildkite.rbs b/sig/datadog/ci/ext/environment/providers/buildkite.rbs index f1f30ba1..f6a58e49 100644 --- a/sig/datadog/ci/ext/environment/providers/buildkite.rbs +++ b/sig/datadog/ci/ext/environment/providers/buildkite.rbs @@ -4,7 +4,6 @@ module Datadog module Environment module Providers class Buildkite < Extractor - private def provider_name: () -> "buildkite" def job_url: () -> ::String diff --git a/sig/datadog/ci/ext/environment/providers/circleci.rbs b/sig/datadog/ci/ext/environment/providers/circleci.rbs index b7c9bbce..6197bca3 100644 --- a/sig/datadog/ci/ext/environment/providers/circleci.rbs +++ b/sig/datadog/ci/ext/environment/providers/circleci.rbs @@ -4,7 +4,6 @@ module Datadog module Environment module Providers class Circleci < Extractor - private def provider_name: () -> "circleci" def job_url: () -> String? diff --git a/sig/datadog/ci/ext/environment/providers/codefresh.rbs b/sig/datadog/ci/ext/environment/providers/codefresh.rbs index d690632b..e1338753 100644 --- a/sig/datadog/ci/ext/environment/providers/codefresh.rbs +++ b/sig/datadog/ci/ext/environment/providers/codefresh.rbs @@ -4,7 +4,6 @@ module Datadog module Environment module Providers class Codefresh < Extractor - private def provider_name: () -> "codefresh" def job_name: () -> String? diff --git a/sig/datadog/ci/ext/environment/providers/github_actions.rbs b/sig/datadog/ci/ext/environment/providers/github_actions.rbs index 2e0b3094..78fc7eba 100644 --- a/sig/datadog/ci/ext/environment/providers/github_actions.rbs +++ b/sig/datadog/ci/ext/environment/providers/github_actions.rbs @@ -4,7 +4,6 @@ module Datadog module Environment module Providers class GithubActions < Extractor - private @ref: String def provider_name: () -> "github" diff --git a/sig/datadog/ci/ext/environment/providers/gitlab.rbs b/sig/datadog/ci/ext/environment/providers/gitlab.rbs index b66bba79..ce24cd03 100644 --- a/sig/datadog/ci/ext/environment/providers/gitlab.rbs +++ b/sig/datadog/ci/ext/environment/providers/gitlab.rbs @@ -4,8 +4,6 @@ module Datadog module Environment module Providers class Gitlab < Extractor - private - @name_email_tuple: [String?, String?] def provider_name: () -> "gitlab" @@ -48,6 +46,8 @@ module Datadog def ci_env_vars: () -> String? + private + def extract_name_email: () -> [String?, String?] end end diff --git a/sig/datadog/ci/ext/environment/providers/jenkins.rbs b/sig/datadog/ci/ext/environment/providers/jenkins.rbs index 2451f224..591e9cbe 100644 --- a/sig/datadog/ci/ext/environment/providers/jenkins.rbs +++ b/sig/datadog/ci/ext/environment/providers/jenkins.rbs @@ -3,8 +3,7 @@ module Datadog module Ext module Environment module Providers - class Jenkins < Extractor - private + class Jenkins < Base def provider_name: () -> "jenkins" def pipeline_id: () -> String? diff --git a/sig/datadog/ci/ext/environment/providers/local_git.rbs b/sig/datadog/ci/ext/environment/providers/local_git.rbs new file mode 100644 index 00000000..7fe6e1eb --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/local_git.rbs @@ -0,0 +1,66 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class LocalGit < Base + class GitUser + attr_reader name: String? + attr_reader email: String? + attr_reader timestamp: String? + + @name: String? + @email: String? + @timestamp: String? + + def initialize: (String? name, String? email, String? timestamp) -> void + + def date: () -> String? + end + + class NilUser < GitUser + def initialize: () -> void + end + + private + + @author: GitUser + @committer: GitUser + + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_message: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_author_date: () -> String? + + def git_commit_committer_name: () -> String? + + def git_commit_committer_email: () -> String? + + def git_commit_committer_date: () -> String? + + def workspace_path: () -> String? + + def exec_git_command: (String cmd) -> String? + + def author: () -> GitUser + + def committer: () -> GitUser + + def set_git_commit_users: () -> void + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/providers/teamcity.rbs b/sig/datadog/ci/ext/environment/providers/teamcity.rbs index 6b4e841f..eca4b33a 100644 --- a/sig/datadog/ci/ext/environment/providers/teamcity.rbs +++ b/sig/datadog/ci/ext/environment/providers/teamcity.rbs @@ -4,7 +4,6 @@ module Datadog module Environment module Providers class Teamcity < Extractor - private def provider_name: () -> "teamcity" def job_name: () -> String? diff --git a/sig/datadog/ci/ext/environment/providers/travis.rbs b/sig/datadog/ci/ext/environment/providers/travis.rbs index 7cfc16ae..03f75504 100644 --- a/sig/datadog/ci/ext/environment/providers/travis.rbs +++ b/sig/datadog/ci/ext/environment/providers/travis.rbs @@ -4,7 +4,6 @@ module Datadog module Environment module Providers class Travis < Extractor - private def provider_name: () -> "travisci" def job_url: () -> String? diff --git a/sig/datadog/ci/ext/environment/providers/user_defined_tags.rbs b/sig/datadog/ci/ext/environment/providers/user_defined_tags.rbs new file mode 100644 index 00000000..5e4745a4 --- /dev/null +++ b/sig/datadog/ci/ext/environment/providers/user_defined_tags.rbs @@ -0,0 +1,33 @@ +module Datadog + module CI + module Ext + module Environment + module Providers + class UserDefinedTags < Base + def git_repository_url: () -> String? + + def git_commit_sha: () -> String? + + def git_branch: () -> String? + + def git_tag: () -> String? + + def git_commit_message: () -> String? + + def git_commit_author_name: () -> String? + + def git_commit_author_email: () -> String? + + def git_commit_author_date: () -> String? + + def git_commit_committer_name: () -> String? + + def git_commit_committer_email: () -> String? + + def git_commit_committer_date: () -> String? + end + end + end + end + end +end diff --git a/sig/datadog/ci/ext/environment/user_defined_tags.rbs b/sig/datadog/ci/ext/environment/user_defined_tags.rbs deleted file mode 100644 index ed2a2bf1..00000000 --- a/sig/datadog/ci/ext/environment/user_defined_tags.rbs +++ /dev/null @@ -1,31 +0,0 @@ -module Datadog - module CI - module Ext - module Environment - class UserDefinedTags < Extractor - def git_repository_url: () -> String? - - def git_commit_sha: () -> String? - - def git_branch: () -> String? - - def git_tag: () -> String? - - def git_commit_message: () -> String? - - def git_commit_author_name: () -> String? - - def git_commit_author_email: () -> String? - - def git_commit_author_date: () -> String? - - def git_commit_committer_name: () -> String? - - def git_commit_committer_email: () -> String? - - def git_commit_committer_date: () -> String? - end - end - end - end -end diff --git a/sig/datadog/ci/utils/git.rbs b/sig/datadog/ci/utils/git.rbs new file mode 100644 index 00000000..d32f93f5 --- /dev/null +++ b/sig/datadog/ci/utils/git.rbs @@ -0,0 +1,11 @@ +module Datadog + module CI + module Utils + module Git + def self?.normalize_ref: (untyped name) -> (nil | untyped) + + def self?.is_git_tag?: (untyped ref) -> untyped + end + end + end +end diff --git a/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb b/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb index 207a3d23..6c0fa412 100644 --- a/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/appveyor_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Appveyor do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/azure_spec.rb b/spec/datadog/ci/ext/environment/providers/azure_spec.rb index 85f9544f..02e75162 100644 --- a/spec/datadog/ci/ext/environment/providers/azure_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/azure_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Azure do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/default_spec.rb b/spec/datadog/ci/ext/environment/providers/base_spec.rb similarity index 66% rename from spec/datadog/ci/ext/environment/providers/default_spec.rb rename to spec/datadog/ci/ext/environment/providers/base_spec.rb index b71a2ba0..3a1b5d6a 100644 --- a/spec/datadog/ci/ext/environment/providers/default_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/base_spec.rb @@ -1,11 +1,6 @@ -RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Default do +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Base do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb b/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb index 7f1b8e6a..70e0e4f7 100644 --- a/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/bitbucket_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Bitbucket do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/bitrise_spec.rb b/spec/datadog/ci/ext/environment/providers/bitrise_spec.rb index d4e8fb35..aed03e21 100644 --- a/spec/datadog/ci/ext/environment/providers/bitrise_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/bitrise_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Bitrise do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/buddy_spec.rb b/spec/datadog/ci/ext/environment/providers/buddy_spec.rb index 55674be9..d731b318 100644 --- a/spec/datadog/ci/ext/environment/providers/buddy_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/buddy_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Buddy do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/buildkite_spec.rb b/spec/datadog/ci/ext/environment/providers/buildkite_spec.rb index 799cd36d..b1bd484b 100644 --- a/spec/datadog/ci/ext/environment/providers/buildkite_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/buildkite_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Buildkite do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/circleci_spec.rb b/spec/datadog/ci/ext/environment/providers/circleci_spec.rb index e0b08b13..8de10e6d 100644 --- a/spec/datadog/ci/ext/environment/providers/circleci_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/circleci_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Circleci do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/codefresh_spec.rb b/spec/datadog/ci/ext/environment/providers/codefresh_spec.rb index 5285bb59..37a1e69a 100644 --- a/spec/datadog/ci/ext/environment/providers/codefresh_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/codefresh_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Codefresh do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/github_actions_spec.rb b/spec/datadog/ci/ext/environment/providers/github_actions_spec.rb index cd37388b..aa0ac8af 100644 --- a/spec/datadog/ci/ext/environment/providers/github_actions_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/github_actions_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::GithubActions do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb b/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb index bbccdb16..7b1a22c9 100644 --- a/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/gitlab_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Gitlab do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb b/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb index e4776c71..3604c267 100644 --- a/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/jenkins_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Jenkins do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/local_git_spec.rb b/spec/datadog/ci/ext/environment/providers/local_git_spec.rb similarity index 87% rename from spec/datadog/ci/ext/environment/local_git_spec.rb rename to spec/datadog/ci/ext/environment/providers/local_git_spec.rb index 007a9772..7fde44ca 100644 --- a/spec/datadog/ci/ext/environment/local_git_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/local_git_spec.rb @@ -1,11 +1,9 @@ -RSpec.describe ::Datadog::CI::Ext::Environment::LocalGit do +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::LocalGit do let(:env) { {} } let(:environment_variables) { {} } describe "#tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end + include_context "extract tags from environment with given provider and use a subject" context "example git repository" do include_context "with git fixture", "gitdir_with_commit" @@ -36,7 +34,7 @@ include_context "with git fixture", "gitdir_with_commit" subject(:committer_email) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags["git.commit.committer.email"] } + ClimateControl.modify(environment_variables) { described_class.new(env).git_commit_committer_email } end it "returns committer from the latest commit in the repository" do diff --git a/spec/datadog/ci/ext/environment/providers/teamcity_spec.rb b/spec/datadog/ci/ext/environment/providers/teamcity_spec.rb index d9c23af4..20308ed7 100644 --- a/spec/datadog/ci/ext/environment/providers/teamcity_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/teamcity_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Teamcity do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/providers/travis_spec.rb b/spec/datadog/ci/ext/environment/providers/travis_spec.rb index a86a9011..b71a13f8 100644 --- a/spec/datadog/ci/ext/environment/providers/travis_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/travis_spec.rb @@ -1,11 +1,6 @@ RSpec.describe ::Datadog::CI::Ext::Environment::Providers::Travis do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/datadog/ci/ext/environment/user_defined_tags_spec.rb b/spec/datadog/ci/ext/environment/providers/user_defined_tags_spec.rb similarity index 87% rename from spec/datadog/ci/ext/environment/user_defined_tags_spec.rb rename to spec/datadog/ci/ext/environment/providers/user_defined_tags_spec.rb index d852b7ae..c7d25efe 100644 --- a/spec/datadog/ci/ext/environment/user_defined_tags_spec.rb +++ b/spec/datadog/ci/ext/environment/providers/user_defined_tags_spec.rb @@ -1,11 +1,6 @@ -RSpec.describe ::Datadog::CI::Ext::Environment::UserDefinedTags do +RSpec.describe ::Datadog::CI::Ext::Environment::Providers::UserDefinedTags do describe ".tags" do - subject(:extracted_tags) do - ClimateControl.modify(environment_variables) { described_class.new(env).tags } - end - - let(:env) { {} } - let(:environment_variables) { {} } + include_context "extract tags from environment with given provider and use a subject" context "example fixture" do let(:env) do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3a0d1b4c..c55d75cd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,6 +15,7 @@ require_relative "support/test_helpers" require_relative "support/platform_helpers" require_relative "support/git_helpers" +require_relative "support/provider_test_helpers" require "rspec/collection_matchers" require "climate_control" diff --git a/spec/support/provider_test_helpers.rb b/spec/support/provider_test_helpers.rb new file mode 100644 index 00000000..ae1a736f --- /dev/null +++ b/spec/support/provider_test_helpers.rb @@ -0,0 +1,14 @@ +shared_context "extract tags from environment with given provider and use a subject" do |git_fixture| + let(:provider) do + described_class.new(env) + end + + subject(:extracted_tags) do + ClimateControl.modify(environment_variables) do + ::Datadog::CI::Ext::Environment::Extractor.new(env, provider: provider).tags + end + end + + let(:env) { {} } + let(:environment_variables) { {} } +end From b6007261d4a2b363368572a9627f50290cc4d6b4 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Wed, 6 Sep 2023 15:45:41 +0200 Subject: [PATCH 30/31] spec for Utils::Git, frozen string literals --- lib/datadog/ci/configuration/components.rb | 2 + lib/datadog/ci/configuration/settings.rb | 2 + .../cucumber/configuration/settings.rb | 2 + lib/datadog/ci/contrib/cucumber/ext.rb | 18 ++++--- lib/datadog/ci/contrib/cucumber/formatter.rb | 2 + .../ci/contrib/cucumber/instrumentation.rb | 2 + .../ci/contrib/cucumber/integration.rb | 2 + lib/datadog/ci/contrib/cucumber/patcher.rb | 2 + .../minitest/configuration/settings.rb | 2 + lib/datadog/ci/contrib/minitest/ext.rb | 2 + lib/datadog/ci/contrib/minitest/hooks.rb | 2 + .../ci/contrib/minitest/integration.rb | 2 + .../contrib/rspec/configuration/settings.rb | 2 + lib/datadog/ci/contrib/rspec/example.rb | 2 + lib/datadog/ci/contrib/rspec/ext.rb | 16 +++--- lib/datadog/ci/contrib/rspec/integration.rb | 2 + lib/datadog/ci/contrib/rspec/patcher.rb | 2 + lib/datadog/ci/ext/app_types.rb | 4 +- .../ci/ext/environment/providers/base.rb | 2 + lib/datadog/ci/ext/settings.rb | 4 +- lib/datadog/ci/ext/test.rb | 38 +++++++------- lib/datadog/ci/extensions.rb | 2 + lib/datadog/ci/flush.rb | 2 + lib/datadog/ci/utils/git.rb | 12 ++--- spec/datadog/ci/utils/git_spec.rb | 49 +++++++++++++++++++ 25 files changed, 136 insertions(+), 41 deletions(-) create mode 100644 spec/datadog/ci/utils/git_spec.rb diff --git a/lib/datadog/ci/configuration/components.rb b/lib/datadog/ci/configuration/components.rb index 9abe9443..aafad49f 100644 --- a/lib/datadog/ci/configuration/components.rb +++ b/lib/datadog/ci/configuration/components.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "../flush" module Datadog diff --git a/lib/datadog/ci/configuration/settings.rb b/lib/datadog/ci/configuration/settings.rb index d75c5a77..fc3c38f9 100644 --- a/lib/datadog/ci/configuration/settings.rb +++ b/lib/datadog/ci/configuration/settings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "../ext/settings" module Datadog diff --git a/lib/datadog/ci/contrib/cucumber/configuration/settings.rb b/lib/datadog/ci/contrib/cucumber/configuration/settings.rb index 9a0e6ccc..713094e6 100644 --- a/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +++ b/lib/datadog/ci/contrib/cucumber/configuration/settings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "../ext" require "datadog/tracing/contrib/configuration/settings" diff --git a/lib/datadog/ci/contrib/cucumber/ext.rb b/lib/datadog/ci/contrib/cucumber/ext.rb index 75fc21b4..4878a445 100644 --- a/lib/datadog/ci/contrib/cucumber/ext.rb +++ b/lib/datadog/ci/contrib/cucumber/ext.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Datadog module CI module Contrib @@ -5,14 +7,14 @@ module Cucumber # Cucumber integration constants # TODO: mark as `@public_api` when GA, to protect from resource and tag name changes. module Ext - APP = "cucumber".freeze - ENV_ENABLED = "DD_TRACE_CUCUMBER_ENABLED".freeze - ENV_OPERATION_NAME = "DD_TRACE_CUCUMBER_OPERATION_NAME".freeze - FRAMEWORK = "cucumber".freeze - OPERATION_NAME = "cucumber.test".freeze - SERVICE_NAME = "cucumber".freeze - STEP_SPAN_TYPE = "step".freeze - TEST_TYPE = "test".freeze + APP = "cucumber" + ENV_ENABLED = "DD_TRACE_CUCUMBER_ENABLED" + ENV_OPERATION_NAME = "DD_TRACE_CUCUMBER_OPERATION_NAME" + FRAMEWORK = "cucumber" + OPERATION_NAME = "cucumber.test" + SERVICE_NAME = "cucumber" + STEP_SPAN_TYPE = "step" + TEST_TYPE = "test" end end end diff --git a/lib/datadog/ci/contrib/cucumber/formatter.rb b/lib/datadog/ci/contrib/cucumber/formatter.rb index 239ae902..150218ac 100644 --- a/lib/datadog/ci/contrib/cucumber/formatter.rb +++ b/lib/datadog/ci/contrib/cucumber/formatter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "../../test" require_relative "../../ext/app_types" require_relative "../../ext/environment" diff --git a/lib/datadog/ci/contrib/cucumber/instrumentation.rb b/lib/datadog/ci/contrib/cucumber/instrumentation.rb index 87688ddf..9e98cc58 100644 --- a/lib/datadog/ci/contrib/cucumber/instrumentation.rb +++ b/lib/datadog/ci/contrib/cucumber/instrumentation.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "formatter" module Datadog diff --git a/lib/datadog/ci/contrib/cucumber/integration.rb b/lib/datadog/ci/contrib/cucumber/integration.rb index 2e9c4b2d..115ba47a 100644 --- a/lib/datadog/ci/contrib/cucumber/integration.rb +++ b/lib/datadog/ci/contrib/cucumber/integration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "configuration/settings" require_relative "patcher" diff --git a/lib/datadog/ci/contrib/cucumber/patcher.rb b/lib/datadog/ci/contrib/cucumber/patcher.rb index 9e1430da..268404bf 100644 --- a/lib/datadog/ci/contrib/cucumber/patcher.rb +++ b/lib/datadog/ci/contrib/cucumber/patcher.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "datadog/tracing/contrib/patcher" require_relative "instrumentation" diff --git a/lib/datadog/ci/contrib/minitest/configuration/settings.rb b/lib/datadog/ci/contrib/minitest/configuration/settings.rb index 1ac6cd54..f412978e 100644 --- a/lib/datadog/ci/contrib/minitest/configuration/settings.rb +++ b/lib/datadog/ci/contrib/minitest/configuration/settings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "../ext" require "datadog/tracing/contrib/configuration/settings" diff --git a/lib/datadog/ci/contrib/minitest/ext.rb b/lib/datadog/ci/contrib/minitest/ext.rb index 0ffaf746..b45ab2a3 100644 --- a/lib/datadog/ci/contrib/minitest/ext.rb +++ b/lib/datadog/ci/contrib/minitest/ext.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Datadog module CI module Contrib diff --git a/lib/datadog/ci/contrib/minitest/hooks.rb b/lib/datadog/ci/contrib/minitest/hooks.rb index d8bba439..0bb61195 100644 --- a/lib/datadog/ci/contrib/minitest/hooks.rb +++ b/lib/datadog/ci/contrib/minitest/hooks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Datadog module CI module Contrib diff --git a/lib/datadog/ci/contrib/minitest/integration.rb b/lib/datadog/ci/contrib/minitest/integration.rb index 4be1ae1c..e918e25e 100644 --- a/lib/datadog/ci/contrib/minitest/integration.rb +++ b/lib/datadog/ci/contrib/minitest/integration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "configuration/settings" require_relative "patcher" diff --git a/lib/datadog/ci/contrib/rspec/configuration/settings.rb b/lib/datadog/ci/contrib/rspec/configuration/settings.rb index 2ece8d0c..c573b9e5 100644 --- a/lib/datadog/ci/contrib/rspec/configuration/settings.rb +++ b/lib/datadog/ci/contrib/rspec/configuration/settings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "../ext" require "datadog/tracing/contrib/configuration/settings" diff --git a/lib/datadog/ci/contrib/rspec/example.rb b/lib/datadog/ci/contrib/rspec/example.rb index 7be45b27..e45e26c6 100644 --- a/lib/datadog/ci/contrib/rspec/example.rb +++ b/lib/datadog/ci/contrib/rspec/example.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "../../test" require_relative "../../ext/app_types" diff --git a/lib/datadog/ci/contrib/rspec/ext.rb b/lib/datadog/ci/contrib/rspec/ext.rb index 65351fac..9ce6ae1a 100644 --- a/lib/datadog/ci/contrib/rspec/ext.rb +++ b/lib/datadog/ci/contrib/rspec/ext.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Datadog module CI module Contrib @@ -5,13 +7,13 @@ module RSpec # RSpec integration constants # TODO: mark as `@public_api` when GA, to protect from resource and tag name changes. module Ext - APP = "rspec".freeze - ENV_ENABLED = "DD_TRACE_RSPEC_ENABLED".freeze - ENV_OPERATION_NAME = "DD_TRACE_RSPEC_OPERATION_NAME".freeze - FRAMEWORK = "rspec".freeze - OPERATION_NAME = "rspec.example".freeze - SERVICE_NAME = "rspec".freeze - TEST_TYPE = "test".freeze + APP = "rspec" + ENV_ENABLED = "DD_TRACE_RSPEC_ENABLED" + ENV_OPERATION_NAME = "DD_TRACE_RSPEC_OPERATION_NAME" + FRAMEWORK = "rspec" + OPERATION_NAME = "rspec.example" + SERVICE_NAME = "rspec" + TEST_TYPE = "test" end end end diff --git a/lib/datadog/ci/contrib/rspec/integration.rb b/lib/datadog/ci/contrib/rspec/integration.rb index 5ce19878..2121c50e 100644 --- a/lib/datadog/ci/contrib/rspec/integration.rb +++ b/lib/datadog/ci/contrib/rspec/integration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "datadog/tracing/contrib/integration" require_relative "configuration/settings" diff --git a/lib/datadog/ci/contrib/rspec/patcher.rb b/lib/datadog/ci/contrib/rspec/patcher.rb index 0dc057b6..80365e67 100644 --- a/lib/datadog/ci/contrib/rspec/patcher.rb +++ b/lib/datadog/ci/contrib/rspec/patcher.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "datadog/tracing/contrib/patcher" require_relative "example" diff --git a/lib/datadog/ci/ext/app_types.rb b/lib/datadog/ci/ext/app_types.rb index 297e78a1..e83ad3c3 100644 --- a/lib/datadog/ci/ext/app_types.rb +++ b/lib/datadog/ci/ext/app_types.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + module Datadog module CI module Ext module AppTypes - TYPE_TEST = "test".freeze + TYPE_TEST = "test" end end end diff --git a/lib/datadog/ci/ext/environment/providers/base.rb b/lib/datadog/ci/ext/environment/providers/base.rb index 77d1682c..82d2b514 100644 --- a/lib/datadog/ci/ext/environment/providers/base.rb +++ b/lib/datadog/ci/ext/environment/providers/base.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Datadog module CI module Ext diff --git a/lib/datadog/ci/ext/settings.rb b/lib/datadog/ci/ext/settings.rb index c9424739..d74dbbd6 100644 --- a/lib/datadog/ci/ext/settings.rb +++ b/lib/datadog/ci/ext/settings.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + module Datadog module CI module Ext # Defines constants for test tags module Settings - ENV_MODE_ENABLED = "DD_TRACE_CI_ENABLED".freeze + ENV_MODE_ENABLED = "DD_TRACE_CI_ENABLED" end end end diff --git a/lib/datadog/ci/ext/test.rb b/lib/datadog/ci/ext/test.rb index 8d4a0471..af7199fb 100644 --- a/lib/datadog/ci/ext/test.rb +++ b/lib/datadog/ci/ext/test.rb @@ -1,33 +1,35 @@ +# frozen_string_literal: true + module Datadog module CI module Ext # Defines constants for test tags module Test - CONTEXT_ORIGIN = "ciapp-test".freeze + CONTEXT_ORIGIN = "ciapp-test" - TAG_ARGUMENTS = "test.arguments".freeze - TAG_FRAMEWORK = "test.framework".freeze - TAG_FRAMEWORK_VERSION = "test.framework_version".freeze - TAG_NAME = "test.name".freeze - TAG_SKIP_REASON = "test.skip_reason".freeze # DEV: Not populated yet - TAG_STATUS = "test.status".freeze - TAG_SUITE = "test.suite".freeze - TAG_TRAITS = "test.traits".freeze - TAG_TYPE = "test.type".freeze + TAG_ARGUMENTS = "test.arguments" + TAG_FRAMEWORK = "test.framework" + TAG_FRAMEWORK_VERSION = "test.framework_version" + TAG_NAME = "test.name" + TAG_SKIP_REASON = "test.skip_reason" # DEV: Not populated yet + TAG_STATUS = "test.status" + TAG_SUITE = "test.suite" + TAG_TRAITS = "test.traits" + TAG_TYPE = "test.type" # Environment runtime tags - TAG_OS_ARCHITECTURE = "os.architecture".freeze - TAG_OS_PLATFORM = "os.platform".freeze - TAG_RUNTIME_NAME = "runtime.name".freeze - TAG_RUNTIME_VERSION = "runtime.version".freeze + TAG_OS_ARCHITECTURE = "os.architecture" + TAG_OS_PLATFORM = "os.platform" + TAG_RUNTIME_NAME = "runtime.name" + TAG_RUNTIME_VERSION = "runtime.version" # TODO: is there a better place for SPAN_KIND? - TAG_SPAN_KIND = "span.kind".freeze + TAG_SPAN_KIND = "span.kind" module Status - PASS = "pass".freeze - FAIL = "fail".freeze - SKIP = "skip".freeze + PASS = "pass" + FAIL = "fail" + SKIP = "skip" end end end diff --git a/lib/datadog/ci/extensions.rb b/lib/datadog/ci/extensions.rb index e0ec9f28..7c0c1ec2 100644 --- a/lib/datadog/ci/extensions.rb +++ b/lib/datadog/ci/extensions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "datadog/core/configuration/settings" require "datadog/core/configuration/components" diff --git a/lib/datadog/ci/flush.rb b/lib/datadog/ci/flush.rb index c3771404..5fabf41e 100644 --- a/lib/datadog/ci/flush.rb +++ b/lib/datadog/ci/flush.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "datadog/tracing/metadata/ext" require "datadog/tracing/flush" diff --git a/lib/datadog/ci/utils/git.rb b/lib/datadog/ci/utils/git.rb index 0afe8c7a..4e674966 100644 --- a/lib/datadog/ci/utils/git.rb +++ b/lib/datadog/ci/utils/git.rb @@ -1,19 +1,19 @@ +# frozen_string_literal: true + module Datadog module CI module Utils module Git - module_function - - def normalize_ref(name) - return nil if name.nil? + def self.normalize_ref(ref) + return nil if ref.nil? refs = %r{^refs/(heads/)?} origin = %r{^origin/} tags = %r{^tags/} - name.gsub(refs, "").gsub(origin, "").gsub(tags, "") + ref.gsub(refs, "").gsub(origin, "").gsub(tags, "") end - def is_git_tag?(ref) + def self.is_git_tag?(ref) !ref.nil? && ref.include?("tags/") end end diff --git a/spec/datadog/ci/utils/git_spec.rb b/spec/datadog/ci/utils/git_spec.rb new file mode 100644 index 00000000..c17700c5 --- /dev/null +++ b/spec/datadog/ci/utils/git_spec.rb @@ -0,0 +1,49 @@ +RSpec.describe ::Datadog::CI::Utils::Git do + describe ".normalize_ref" do + subject { described_class.normalize_ref(ref) } + + context "when input is nil" do + let(:ref) { nil } + + it { is_expected.to be_nil } + end + + context "when input is github ref" do + let(:ref) { "refs/heads/master" } + + it "strips everything out except ref name" do + is_expected.to eq("master") + end + end + + context "when input includes tags" do + let(:ref) { "refs/heads/tags/0.1.0" } + + it "strips everything out except ref name" do + is_expected.to eq("0.1.0") + end + end + end + + describe ".is_git_tag?" do + subject { described_class.is_git_tag?(ref) } + + context "when input is nil" do + let(:ref) { nil } + + it { is_expected.to be_falsey } + end + + context "when input is a branch" do + let(:ref) { "refs/heads/master" } + + it { is_expected.to be_falsey } + end + + context "when input includes tags" do + let(:ref) { "refs/heads/tags/0.1.0" } + + it { is_expected.to be_truthy } + end + end +end From 0837f355667fff4dff53cacd516a13aea86471c7 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Wed, 6 Sep 2023 15:51:34 +0200 Subject: [PATCH 31/31] supply provider class to Extractor --- lib/datadog/ci/ext/environment.rb | 6 ++---- lib/datadog/ci/ext/environment/extractor.rb | 4 ++-- lib/datadog/ci/ext/environment/providers.rb | 3 +++ sig/datadog/ci/ext/environment/extractor.rbs | 2 +- spec/support/provider_test_helpers.rb | 6 +----- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/datadog/ci/ext/environment.rb b/lib/datadog/ci/ext/environment.rb index 4d1bd32e..5e53253c 100644 --- a/lib/datadog/ci/ext/environment.rb +++ b/lib/datadog/ci/ext/environment.rb @@ -2,8 +2,6 @@ require_relative "git" require_relative "environment/extractor" -require_relative "environment/providers/local_git" -require_relative "environment/providers/user_defined_tags" module Datadog module CI @@ -33,11 +31,11 @@ def tags(env) # If user defined metadata is defined, overwrite tags.merge!( - Environment::Extractor.new(env, provider: Providers::UserDefinedTags.new(env)).tags + Environment::Extractor.new(env, provider_klass: Providers::UserDefinedTags).tags ) # Fill out tags from local git as fallback - local_git_tags = Environment::Extractor.new(env, provider: Providers::LocalGit.new(env)).tags + local_git_tags = Environment::Extractor.new(env, provider_klass: Providers::LocalGit).tags local_git_tags.each do |key, value| tags[key] ||= value end diff --git a/lib/datadog/ci/ext/environment/extractor.rb b/lib/datadog/ci/ext/environment/extractor.rb index d3b55cf6..99e64408 100644 --- a/lib/datadog/ci/ext/environment/extractor.rb +++ b/lib/datadog/ci/ext/environment/extractor.rb @@ -13,9 +13,9 @@ module Environment # Extractor is responsible for detecting where pipeline is being executed based on environment vars # and return the specific extractor that is able to return environment- and git-specific tags class Extractor - def initialize(env, provider: nil) + def initialize(env, provider_klass: nil) @env = env - @provider = provider || Providers.for_environment(env) + @provider = provider_klass ? provider_klass.new(env) : Providers.for_environment(env) end def tags diff --git a/lib/datadog/ci/ext/environment/providers.rb b/lib/datadog/ci/ext/environment/providers.rb index 0e854dd0..40b4fcd0 100644 --- a/lib/datadog/ci/ext/environment/providers.rb +++ b/lib/datadog/ci/ext/environment/providers.rb @@ -15,6 +15,9 @@ require_relative "providers/teamcity" require_relative "providers/travis" +require_relative "providers/local_git" +require_relative "providers/user_defined_tags" + module Datadog module CI module Ext diff --git a/sig/datadog/ci/ext/environment/extractor.rbs b/sig/datadog/ci/ext/environment/extractor.rbs index 1ccf644c..541f9671 100644 --- a/sig/datadog/ci/ext/environment/extractor.rbs +++ b/sig/datadog/ci/ext/environment/extractor.rbs @@ -7,7 +7,7 @@ module Datadog @provider: Providers::Base @tags: Hash[String, untyped] - def initialize: (Hash[String, String?] env, ?provider: Providers::Base?) -> void + def initialize: (Hash[String, String?] env, ?provider_klass: singleton(Providers::Base)?) -> void def tags: () -> Hash[String, untyped] diff --git a/spec/support/provider_test_helpers.rb b/spec/support/provider_test_helpers.rb index ae1a736f..b9e98d15 100644 --- a/spec/support/provider_test_helpers.rb +++ b/spec/support/provider_test_helpers.rb @@ -1,11 +1,7 @@ shared_context "extract tags from environment with given provider and use a subject" do |git_fixture| - let(:provider) do - described_class.new(env) - end - subject(:extracted_tags) do ClimateControl.modify(environment_variables) do - ::Datadog::CI::Ext::Environment::Extractor.new(env, provider: provider).tags + ::Datadog::CI::Ext::Environment::Extractor.new(env, provider_klass: described_class).tags end end