From 895ee04ed5515ea16ff8543e3fb4fd6f51f3d4f9 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 1 Sep 2023 15:54:49 +0200 Subject: [PATCH] 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