ddtrace 0.42.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/add-milestone-to-pull-requests.yml +42 -0
  3. data/.github/workflows/create-next-milestone.yml +20 -0
  4. data/.simplecov +1 -1
  5. data/Appraisals +160 -132
  6. data/CHANGELOG.md +36 -0
  7. data/CONTRIBUTING.md +1 -1
  8. data/Rakefile +39 -0
  9. data/docs/DevelopmentGuide.md +2 -2
  10. data/docs/GettingStarted.md +71 -1
  11. data/lib/ddtrace.rb +2 -0
  12. data/lib/ddtrace/configuration.rb +20 -4
  13. data/lib/ddtrace/configuration/settings.rb +4 -2
  14. data/lib/ddtrace/context.rb +18 -0
  15. data/lib/ddtrace/context_provider.rb +12 -1
  16. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +104 -3
  17. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +21 -0
  18. data/lib/ddtrace/contrib/active_support/ext.rb +3 -0
  19. data/lib/ddtrace/contrib/active_support/notifications/event.rb +10 -0
  20. data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -1
  21. data/lib/ddtrace/contrib/aws/patcher.rb +0 -1
  22. data/lib/ddtrace/contrib/configurable.rb +2 -0
  23. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +4 -5
  24. data/lib/ddtrace/contrib/cucumber/configuration/settings.rb +38 -0
  25. data/lib/ddtrace/contrib/cucumber/ext.rb +19 -0
  26. data/lib/ddtrace/contrib/cucumber/formatter.rb +104 -0
  27. data/lib/ddtrace/contrib/cucumber/instrumentation.rb +24 -0
  28. data/lib/ddtrace/contrib/cucumber/integration.rb +40 -0
  29. data/lib/ddtrace/contrib/cucumber/patcher.rb +23 -0
  30. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +1 -0
  31. data/lib/ddtrace/contrib/delayed_job/plugin.rb +3 -1
  32. data/lib/ddtrace/contrib/excon/middleware.rb +7 -1
  33. data/lib/ddtrace/contrib/faraday/patcher.rb +1 -1
  34. data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -0
  35. data/lib/ddtrace/contrib/grape/endpoint.rb +19 -4
  36. data/lib/ddtrace/contrib/http/instrumentation.rb +2 -2
  37. data/lib/ddtrace/contrib/httprb/instrumentation.rb +2 -2
  38. data/lib/ddtrace/contrib/kafka/event.rb +1 -1
  39. data/lib/ddtrace/contrib/que/configuration/settings.rb +1 -0
  40. data/lib/ddtrace/contrib/que/tracer.rb +2 -1
  41. data/lib/ddtrace/contrib/rails/patcher.rb +5 -2
  42. data/lib/ddtrace/contrib/resque/configuration/settings.rb +1 -0
  43. data/lib/ddtrace/contrib/resque/resque_job.rb +1 -1
  44. data/lib/ddtrace/contrib/rspec/configuration/settings.rb +38 -0
  45. data/lib/ddtrace/contrib/rspec/example.rb +61 -0
  46. data/lib/ddtrace/contrib/rspec/example_group.rb +61 -0
  47. data/lib/ddtrace/contrib/rspec/ext.rb +19 -0
  48. data/lib/ddtrace/contrib/rspec/integration.rb +41 -0
  49. data/lib/ddtrace/contrib/rspec/patcher.rb +25 -0
  50. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +1 -0
  51. data/lib/ddtrace/contrib/shoryuken/tracer.rb +4 -1
  52. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +1 -0
  53. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +4 -1
  54. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +1 -0
  55. data/lib/ddtrace/contrib/sneakers/tracer.rb +17 -20
  56. data/lib/ddtrace/contrib/status_code_matcher.rb +67 -0
  57. data/lib/ddtrace/ext/app_types.rb +1 -0
  58. data/lib/ddtrace/ext/ci.rb +265 -0
  59. data/lib/ddtrace/ext/distributed.rb +8 -2
  60. data/lib/ddtrace/ext/git.rb +12 -0
  61. data/lib/ddtrace/ext/runtime.rb +1 -0
  62. data/lib/ddtrace/ext/test.rb +24 -0
  63. data/lib/ddtrace/runtime/identity.rb +4 -5
  64. data/lib/ddtrace/sampling/rate_limiter.rb +65 -16
  65. data/lib/ddtrace/tracer.rb +14 -1
  66. data/lib/ddtrace/utils.rb +10 -11
  67. data/lib/ddtrace/utils/forking.rb +52 -0
  68. data/lib/ddtrace/version.rb +1 -1
  69. data/lib/ddtrace/writer.rb +19 -1
  70. metadata +23 -31
@@ -0,0 +1,19 @@
1
+ module Datadog
2
+ module Contrib
3
+ module RSpec
4
+ # RSpec integration constants
5
+ module Ext
6
+ APP = 'rspec'.freeze
7
+ ENV_ANALYTICS_ENABLED = 'DD_TRACE_RSPEC_ANALYTICS_ENABLED'.freeze
8
+ ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_RSPEC_ANALYTICS_SAMPLE_RATE'.freeze
9
+ ENV_ENABLED = 'DD_TRACE_RSPEC_ENABLED'.freeze
10
+ ENV_OPERATION_NAME = 'DD_TRACE_RSPEC_OPERATION_NAME'.freeze
11
+ FRAMEWORK = 'rspec'.freeze
12
+ OPERATION_NAME = 'rspec.example'.freeze
13
+ EXAMPLE_GROUP_OPERATION_NAME = 'rspec.example_group'.freeze
14
+ SERVICE_NAME = 'rspec'.freeze
15
+ TEST_TYPE = 'test'.freeze
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/rspec/configuration/settings'
3
+ require 'ddtrace/contrib/rspec/patcher'
4
+ require 'ddtrace/contrib/integration'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module RSpec
9
+ # Description of RSpec integration
10
+ class Integration
11
+ include Contrib::Integration
12
+
13
+ MINIMUM_VERSION = Gem::Version.new('3.0.0')
14
+
15
+ register_as :rspec, auto_patch: true
16
+
17
+ def self.version
18
+ Gem.loaded_specs['rspec'] \
19
+ && Gem.loaded_specs['rspec'].version
20
+ end
21
+
22
+ def self.loaded?
23
+ !defined?(::RSpec).nil? && !defined?(::RSpec::Core).nil? && \
24
+ !defined?(::RSpec::Core::Example).nil? && !defined?(::RSpec::Core::ExampleGroup).nil?
25
+ end
26
+
27
+ def self.compatible?
28
+ super && version >= MINIMUM_VERSION
29
+ end
30
+
31
+ def default_configuration
32
+ Configuration::Settings.new
33
+ end
34
+
35
+ def patcher
36
+ Patcher
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/rspec/example'
3
+ require 'ddtrace/contrib/rspec/example_group'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module RSpec
8
+ # Patcher enables patching of 'rspec' module.
9
+ module Patcher
10
+ include Contrib::Patcher
11
+
12
+ module_function
13
+
14
+ def target_version
15
+ Integration.version
16
+ end
17
+
18
+ def patch
19
+ ::RSpec::Core::Example.send(:include, Example)
20
+ ::RSpec::Core::ExampleGroup.send(:include, ExampleGroup)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -22,6 +22,7 @@ module Datadog
22
22
  end
23
23
 
24
24
  option :service_name, default: Ext::SERVICE_NAME
25
+ option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
25
26
  end
26
27
  end
27
28
  end
@@ -8,10 +8,13 @@ module Datadog
8
8
  def initialize(options = {})
9
9
  @tracer = options[:tracer] || configuration[:tracer]
10
10
  @shoryuken_service = options[:service_name] || configuration[:service_name]
11
+ @error_handler = options[:error_handler] || configuration[:error_handler]
11
12
  end
12
13
 
13
14
  def call(worker_instance, queue, sqs_msg, body)
14
- @tracer.trace(Ext::SPAN_JOB, service: @shoryuken_service, span_type: Datadog::Ext::AppTypes::WORKER) do |span|
15
+ @tracer.trace(Ext::SPAN_JOB, service: @shoryuken_service, span_type: Datadog::Ext::AppTypes::WORKER,
16
+ on_error: @error_handler) do |span|
17
+
15
18
  # Set analytics sample rate
16
19
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
17
20
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
@@ -29,6 +29,7 @@ module Datadog
29
29
 
30
30
  option :service_name, default: Ext::SERVICE_NAME
31
31
  option :client_service_name, default: Ext::CLIENT_SERVICE_NAME
32
+ option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
32
33
  end
33
34
  end
34
35
  end
@@ -11,6 +11,7 @@ module Datadog
11
11
  def initialize(options = {})
12
12
  super
13
13
  @sidekiq_service = options[:service_name] || configuration[:service_name]
14
+ @error_handler = options[:error_handler] || configuration[:error_handler]
14
15
  end
15
16
 
16
17
  def call(worker, job, queue)
@@ -19,7 +20,9 @@ module Datadog
19
20
  service = worker_config(resource, :service_name) || @sidekiq_service
20
21
  tag_args = worker_config(resource, :tag_args) || configuration[:tag_args]
21
22
 
22
- @tracer.trace(Ext::SPAN_JOB, service: service, span_type: Datadog::Ext::AppTypes::WORKER) do |span|
23
+ @tracer.trace(Ext::SPAN_JOB, service: service, span_type: Datadog::Ext::AppTypes::WORKER,
24
+ on_error: @error_handler) do |span|
25
+
23
26
  span.resource = resource
24
27
  # Set analytics sample rate
25
28
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
@@ -24,6 +24,7 @@ module Datadog
24
24
  end
25
25
 
26
26
  option :service_name, default: Ext::SERVICE_NAME
27
+ option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
27
28
  option :tag_body, default: false
28
29
  end
29
30
  end
@@ -15,32 +15,29 @@ module Datadog
15
15
  def call(deserialized_msg, delivery_info, metadata, handler)
16
16
  trace_options = {
17
17
  service: configuration[:service_name],
18
- span_type: Datadog::Ext::AppTypes::WORKER
18
+ span_type: Datadog::Ext::AppTypes::WORKER,
19
+ on_error: configuration[:error_handler]
19
20
  }
20
- request_span = tracer.trace(Ext::SPAN_JOB, trace_options)
21
21
 
22
- # Set analytics sample rate
23
- if Datadog::Contrib::Analytics.enabled?(configuration[:analytics_enabled])
24
- Datadog::Contrib::Analytics.set_sample_rate(request_span, configuration[:analytics_sample_rate])
25
- end
22
+ tracer.trace(Ext::SPAN_JOB, trace_options) do |request_span|
23
+ # Set analytics sample rate
24
+ if Datadog::Contrib::Analytics.enabled?(configuration[:analytics_enabled])
25
+ Datadog::Contrib::Analytics.set_sample_rate(request_span, configuration[:analytics_sample_rate])
26
+ end
26
27
 
27
- # Measure service stats
28
- Contrib::Analytics.set_measured(request_span)
28
+ # Measure service stats
29
+ Contrib::Analytics.set_measured(request_span)
29
30
 
30
- request_span.resource = @app.to_proc.binding.eval('self.class').to_s
31
- request_span.set_tag(Ext::TAG_JOB_ROUTING_KEY, delivery_info.routing_key)
32
- request_span.set_tag(Ext::TAG_JOB_QUEUE, delivery_info.consumer.queue.name)
31
+ request_span.resource = @app.to_proc.binding.eval('self.class').to_s
32
+ request_span.set_tag(Ext::TAG_JOB_ROUTING_KEY, delivery_info.routing_key)
33
+ request_span.set_tag(Ext::TAG_JOB_QUEUE, delivery_info.consumer.queue.name)
33
34
 
34
- if configuration[:tag_body]
35
- request_span.set_tag(Ext::TAG_JOB_BODY, deserialized_msg)
36
- end
35
+ if configuration[:tag_body]
36
+ request_span.set_tag(Ext::TAG_JOB_BODY, deserialized_msg)
37
+ end
37
38
 
38
- @app.call(deserialized_msg, delivery_info, metadata, handler)
39
- rescue StandardError => e
40
- request_span.set_error(e) unless request_span.nil?
41
- raise e
42
- ensure
43
- request_span.finish if request_span
39
+ @app.call(deserialized_msg, delivery_info, metadata, handler)
40
+ end
44
41
  end
45
42
 
46
43
  private
@@ -0,0 +1,67 @@
1
+ require 'set'
2
+ require 'ddtrace/ext/http'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ # Contains methods helpful for tracing/annotating HTTP request libraries
7
+ class StatusCodeMatcher
8
+ REGEX_PARSER = /^\d{3}(?:-\d{3})?(?:,\d{3}(?:-\d{3})?)*$/
9
+
10
+ def initialize(range)
11
+ @error_response_range = range
12
+ set_range
13
+ end
14
+
15
+ def include?(exception_status)
16
+ set_range.include?(exception_status)
17
+ end
18
+
19
+ def to_s
20
+ @error_response_range.to_s
21
+ end
22
+
23
+ private
24
+
25
+ def set_range
26
+ @datadog_set ||= begin
27
+ set = Set.new
28
+ handle_statuses.each do |statuses|
29
+ status = statuses.to_s.split('-')
30
+ if status.length == 1
31
+ set.add(Integer(status[0]))
32
+ elsif status.length == 2
33
+ min, max = status.minmax
34
+ Array(min..max).each do |i|
35
+ set.add(Integer(i))
36
+ end
37
+ end
38
+ end
39
+ set
40
+ end
41
+ @datadog_set
42
+ end
43
+
44
+ def error_responses
45
+ return @error_response_range if @error_response_range.is_a?(String) && !@error_response_range.nil?
46
+ @error_response_range.join(',') if @error_response_range.is_a?(Array) && !@error_response_range.empty?
47
+ end
48
+
49
+ def handle_statuses
50
+ if error_responses
51
+ filter_error_responses = error_responses.gsub(/\s+/, '').split(',').select do |code|
52
+ if !code.to_s.match(REGEX_PARSER)
53
+ Datadog.logger.debug("Invalid config provided: #{code}. Must be formatted like '400-403,405,410-499'.")
54
+ next
55
+ else
56
+ true
57
+ end
58
+ end
59
+ filter_error_responses.empty? ? Datadog::Ext::HTTP::ERROR_RANGE.to_a : filter_error_responses
60
+ else
61
+ Datadog.logger.debug('No valid config was provided for :error_statuses - falling back to default.')
62
+ Datadog::Ext::HTTP::ERROR_RANGE.to_a
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -6,6 +6,7 @@ module Datadog
6
6
  CACHE = 'cache'.freeze
7
7
  WORKER = 'worker'.freeze
8
8
  CUSTOM = 'custom'.freeze
9
+ TEST = 'test'.freeze
9
10
  end
10
11
  end
11
12
  end
@@ -0,0 +1,265 @@
1
+ require 'ddtrace/ext/git'
2
+
3
+ module Datadog
4
+ module Ext
5
+ # Defines constants for CI tags
6
+ # rubocop:disable Metrics/ModuleLength:
7
+ module CI
8
+ TAG_JOB_URL = 'ci.job.url'.freeze
9
+ TAG_PIPELINE_ID = 'ci.pipeline.id'.freeze
10
+ TAG_PIPELINE_NAME = 'ci.pipeline.name'.freeze
11
+ TAG_PIPELINE_NUMBER = 'ci.pipeline.number'.freeze
12
+ TAG_PIPELINE_URL = 'ci.pipeline.url'.freeze
13
+ TAG_PROVIDER_NAME = 'ci.provider.name'.freeze
14
+ TAG_WORKSPACE_PATH = 'ci.workspace_path'.freeze
15
+
16
+ PROVIDERS = [
17
+ ['APPVEYOR'.freeze, :extract_appveyor],
18
+ ['TF_BUILD'.freeze, :extract_azure_pipelines],
19
+ ['BITBUCKET_COMMIT'.freeze, :extract_bitbucket],
20
+ ['BUILDKITE'.freeze, :extract_buildkite],
21
+ ['CIRCLECI'.freeze, :extract_circle_ci],
22
+ ['GITHUB_SHA'.freeze, :extract_github_actions],
23
+ ['GITLAB_CI'.freeze, :extract_gitlab],
24
+ ['JENKINS_URL'.freeze, :extract_jenkins],
25
+ ['TEAMCITY_VERSION'.freeze, :extract_teamcity],
26
+ ['TRAVIS'.freeze, :extract_travis]
27
+ ].freeze
28
+
29
+ module_function
30
+
31
+ def tags(env)
32
+ provider = PROVIDERS.find { |c| env.key? c[0] }
33
+ return {} if provider.nil?
34
+
35
+ tags = send(provider[1], env)
36
+
37
+ tags[Git::TAG_TAG] = normalize_ref(tags[Git::TAG_TAG])
38
+ tags.delete(Git::TAG_BRANCH) unless tags[Git::TAG_TAG].nil?
39
+ tags[Git::TAG_BRANCH] = normalize_ref(tags[Git::TAG_BRANCH])
40
+ tags[Git::TAG_DEPRECATED_COMMIT_SHA] = tags[Git::TAG_COMMIT_SHA]
41
+ tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info(tags[Git::TAG_REPOSITORY_URL])
42
+
43
+ # Expand ~
44
+ workspace_path = tags[TAG_WORKSPACE_PATH]
45
+ if !workspace_path.nil? && (workspace_path == '~' || workspace_path.start_with?('~/'))
46
+ tags[TAG_WORKSPACE_PATH] = File.expand_path(workspace_path)
47
+ end
48
+ tags.reject { |_, v| v.nil? }
49
+ end
50
+
51
+ def normalize_ref(name)
52
+ refs = %r{^refs/(heads/)?}
53
+ origin = %r{^origin/}
54
+ tags = %r{^tags/}
55
+ name.gsub(refs, '').gsub(origin, '').gsub(tags, '') unless name.nil?
56
+ end
57
+
58
+ def filter_sensitive_info(url)
59
+ url.gsub(%r{(https?://)[^/]*@}, '\1') unless url.nil?
60
+ end
61
+
62
+ # CI providers
63
+
64
+ def extract_appveyor(env)
65
+ url = "https://ci.appveyor.com/project/#{env['APPVEYOR_REPO_NAME']}/builds/#{env['APPVEYOR_BUILD_ID']}"
66
+ {
67
+ TAG_PROVIDER_NAME => 'appveyor',
68
+ Git::TAG_REPOSITORY_URL => "https://github.com/#{env['APPVEYOR_REPO_NAME']}.git",
69
+ Git::TAG_COMMIT_SHA => env['APPVEYOR_REPO_COMMIT'],
70
+ TAG_WORKSPACE_PATH => env['APPVEYOR_BUILD_FOLDER'],
71
+ TAG_PIPELINE_ID => env['APPVEYOR_BUILD_ID'],
72
+ TAG_PIPELINE_NAME => env['APPVEYOR_REPO_NAME'],
73
+ TAG_PIPELINE_NUMBER => env['APPVEYOR_BUILD_NUMBER'],
74
+ TAG_PIPELINE_URL => url,
75
+ TAG_JOB_URL => url,
76
+ Git::TAG_BRANCH => (env['APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH'] || env['APPVEYOR_REPO_BRANCH']),
77
+ Git::TAG_TAG => env['APPVEYOR_REPO_TAG_NAME']
78
+ }
79
+ end
80
+
81
+ def extract_azure_pipelines(env)
82
+ if env['SYSTEM_TEAMFOUNDATIONSERVERURI'] && env['SYSTEM_TEAMPROJECT'] && env['BUILD_BUILDID']
83
+ base_url = "#{env['SYSTEM_TEAMFOUNDATIONSERVERURI']}#{env['SYSTEM_TEAMPROJECT']}" \
84
+ "/_build/results?buildId=#{env['BUILD_BUILDID']}"
85
+ pipeline_url = base_url + '&_a=summary'
86
+ job_url = base_url + "&view=logs&j=#{env['SYSTEM_JOBID']}&t=#{env['SYSTEM_TASKINSTANCEID']}"
87
+ else
88
+ pipeline_url = job_url = nil
89
+ end
90
+ branch_or_tag = (
91
+ env['SYSTEM_PULLREQUEST_SOURCEBRANCH'] || env['BUILD_SOURCEBRANCH'] || env['BUILD_SOURCEBRANCHNAME']
92
+ )
93
+ if branch_or_tag.include? 'tags/'
94
+ branch = nil
95
+ tag = branch_or_tag
96
+ else
97
+ branch = branch_or_tag
98
+ tag = nil
99
+ end
100
+ {
101
+ TAG_PROVIDER_NAME => 'azurepipelines',
102
+ TAG_WORKSPACE_PATH => env['BUILD_SOURCESDIRECTORY'],
103
+ TAG_PIPELINE_ID => env['BUILD_BUILDID'],
104
+ TAG_PIPELINE_NAME => env['BUILD_DEFINITIONNAME'],
105
+ TAG_PIPELINE_NUMBER => env['BUILD_BUILDID'],
106
+ TAG_PIPELINE_URL => pipeline_url,
107
+ TAG_JOB_URL => job_url,
108
+ Git::TAG_REPOSITORY_URL => (env['SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI'] || env['BUILD_REPOSITORY_URI']),
109
+ Git::TAG_COMMIT_SHA => (env['SYSTEM_PULLREQUEST_SOURCECOMMITID'] || env['BUILD_SOURCEVERSION']),
110
+ Git::TAG_BRANCH => branch,
111
+ Git::TAG_TAG => tag
112
+ }
113
+ end
114
+
115
+ def extract_bitbucket(env)
116
+ url = "https://bitbucket.org/#{env['BITBUCKET_REPO_FULL_NAME']}/addon/pipelines/home#" \
117
+ "!/results/#{env['BITBUCKET_BUILD_NUMBER']}"
118
+ {
119
+ Git::TAG_BRANCH => env['BITBUCKET_BRANCH'],
120
+ Git::TAG_COMMIT_SHA => env['BITBUCKET_COMMIT'],
121
+ Git::TAG_REPOSITORY_URL => env['BITBUCKET_GIT_SSH_ORIGIN'],
122
+ Git::TAG_TAG => env['BITBUCKET_TAG'],
123
+ TAG_JOB_URL => url,
124
+ TAG_PIPELINE_ID => env['BITBUCKET_PIPELINE_UUID'] ? env['BITBUCKET_PIPELINE_UUID'].tr('{}', '') : None,
125
+ TAG_PIPELINE_NAME => env['BITBUCKET_REPO_FULL_NAME'],
126
+ TAG_PIPELINE_NUMBER => env['BITBUCKET_BUILD_NUMBER'],
127
+ TAG_PIPELINE_URL => url,
128
+ TAG_PROVIDER_NAME => 'bitbucket',
129
+ TAG_WORKSPACE_PATH => env['BITBUCKET_CLONE_DIR']
130
+ }
131
+ end
132
+
133
+ def extract_buildkite(env)
134
+ {
135
+ Git::TAG_BRANCH => env['BUILDKITE_BRANCH'],
136
+ Git::TAG_COMMIT_SHA => env['BUILDKITE_COMMIT'],
137
+ Git::TAG_REPOSITORY_URL => env['BUILDKITE_REPO'],
138
+ Git::TAG_TAG => env['BUILDKITE_TAG'],
139
+ TAG_PIPELINE_ID => env['BUILDKITE_BUILD_ID'],
140
+ TAG_PIPELINE_NAME => env['BUILDKITE_PIPELINE_SLUG'],
141
+ TAG_PIPELINE_NUMBER => env['BUILDKITE_BUILD_NUMBER'],
142
+ TAG_PIPELINE_URL => env['BUILDKITE_BUILD_URL'],
143
+ TAG_JOB_URL => "#{env['BUILDKITE_BUILD_URL']}##{env['BUILDKITE_JOB_ID']}",
144
+ TAG_PROVIDER_NAME => 'buildkite',
145
+ TAG_WORKSPACE_PATH => env['BUILDKITE_BUILD_CHECKOUT_PATH']
146
+ }
147
+ end
148
+
149
+ def extract_circle_ci(env)
150
+ {
151
+ Git::TAG_BRANCH => env['CIRCLE_BRANCH'],
152
+ Git::TAG_COMMIT_SHA => env['CIRCLE_SHA1'],
153
+ Git::TAG_REPOSITORY_URL => env['CIRCLE_REPOSITORY_URL'],
154
+ Git::TAG_TAG => env['CIRCLE_TAG'],
155
+ TAG_PIPELINE_ID => env['CIRCLE_WORKFLOW_ID'],
156
+ TAG_PIPELINE_NAME => env['CIRCLE_PROJECT_REPONAME'],
157
+ TAG_PIPELINE_NUMBER => env['CIRCLE_BUILD_NUM'],
158
+ TAG_PIPELINE_URL => env['CIRCLE_BUILD_URL'],
159
+ TAG_JOB_URL => env['CIRCLE_BUILD_URL'],
160
+ TAG_PROVIDER_NAME => 'circleci',
161
+ TAG_WORKSPACE_PATH => env['CIRCLE_WORKING_DIRECTORY']
162
+ }
163
+ end
164
+
165
+ def extract_github_actions(env)
166
+ branch_or_tag = (env['GITHUB_HEAD_REF'] || env['GITHUB_REF'])
167
+ if branch_or_tag.include? 'tags/'
168
+ branch = nil
169
+ tag = branch_or_tag
170
+ else
171
+ branch = branch_or_tag
172
+ tag = nil
173
+ end
174
+ {
175
+ Git::TAG_BRANCH => branch,
176
+ Git::TAG_COMMIT_SHA => env['GITHUB_SHA'],
177
+ Git::TAG_REPOSITORY_URL => "https://github.com/#{env['GITHUB_REPOSITORY']}.git",
178
+ Git::TAG_TAG => tag,
179
+ TAG_JOB_URL => "https://github.com/#{env['GITHUB_REPOSITORY']}/commit/#{env['GITHUB_SHA']}/checks",
180
+ TAG_PIPELINE_ID => env['GITHUB_RUN_ID'],
181
+ TAG_PIPELINE_NAME => env['GITHUB_WORKFLOW'],
182
+ TAG_PIPELINE_NUMBER => env['GITHUB_RUN_NUMBER'],
183
+ TAG_PIPELINE_URL => "https://github.com/#{env['GITHUB_REPOSITORY']}/commit/#{env['GITHUB_SHA']}/checks",
184
+ TAG_PROVIDER_NAME => 'github',
185
+ TAG_WORKSPACE_PATH => env['GITHUB_WORKSPACE']
186
+ }
187
+ end
188
+
189
+ def extract_gitlab(env)
190
+ url = env['CI_PIPELINE_URL']
191
+ url = url.gsub(%r{/-/pipelines/}, '/pipelines/') unless url.nil?
192
+ {
193
+ Git::TAG_BRANCH => env['CI_COMMIT_BRANCH'],
194
+ Git::TAG_COMMIT_SHA => env['CI_COMMIT_SHA'],
195
+ Git::TAG_REPOSITORY_URL => env['CI_REPOSITORY_URL'],
196
+ Git::TAG_TAG => env['CI_COMMIT_TAG'],
197
+ TAG_JOB_URL => env['CI_JOB_URL'],
198
+ TAG_PIPELINE_ID => env['CI_PIPELINE_ID'],
199
+ TAG_PIPELINE_NAME => env['CI_PROJECT_PATH'],
200
+ TAG_PIPELINE_NUMBER => env['CI_PIPELINE_IID'],
201
+ TAG_PIPELINE_URL => url,
202
+ TAG_PROVIDER_NAME => 'gitlab',
203
+ TAG_WORKSPACE_PATH => env['CI_PROJECT_DIR']
204
+ }
205
+ end
206
+
207
+ def extract_jenkins(env)
208
+ branch_or_tag = env['GIT_BRANCH']
209
+ if branch_or_tag.include? 'tags/'
210
+ branch = nil
211
+ tag = branch_or_tag
212
+ else
213
+ branch = branch_or_tag
214
+ tag = nil
215
+ end
216
+ name = env['JOB_NAME']
217
+ name = name.gsub("/#{normalize_ref(branch)}", '') unless name.nil? || branch.nil?
218
+ name = name.split('/').reject { |v| v.nil? || v.include?('=') }.join('/') unless name.nil?
219
+ {
220
+ Git::TAG_BRANCH => branch,
221
+ Git::TAG_COMMIT_SHA => env['GIT_COMMIT'],
222
+ Git::TAG_REPOSITORY_URL => env['GIT_URL'],
223
+ Git::TAG_TAG => tag,
224
+ TAG_JOB_URL => env['JOB_URL'],
225
+ TAG_PIPELINE_ID => env['BUILD_TAG'],
226
+ TAG_PIPELINE_NAME => name,
227
+ TAG_PIPELINE_NUMBER => env['BUILD_NUMBER'],
228
+ TAG_PIPELINE_URL => env['BUILD_URL'],
229
+ TAG_PROVIDER_NAME => 'jenkins',
230
+ TAG_WORKSPACE_PATH => env['WORKSPACE']
231
+ }
232
+ end
233
+
234
+ def extract_teamcity(env)
235
+ {
236
+ TAG_PROVIDER_NAME => 'teamcity',
237
+ Git::TAG_REPOSITORY_URL => env['BUILD_VCS_URL'],
238
+ Git::TAG_COMMIT_SHA => env['BUILD_VCS_NUMBER'],
239
+ TAG_WORKSPACE_PATH => env['BUILD_CHECKOUTDIR'],
240
+ TAG_PIPELINE_ID => env['BUILD_ID'],
241
+ TAG_PIPELINE_NUMBER => env['BUILD_NUMBER'],
242
+ TAG_PIPELINE_URL => (
243
+ env['SERVER_URL'] && env['BUILD_ID'] ? "#{env['SERVER_URL']}/viewLog.html?buildId=#{env['SERVER_URL']}" : nil
244
+ )
245
+ }
246
+ end
247
+
248
+ def extract_travis(env)
249
+ {
250
+ Git::TAG_BRANCH => (env['TRAVIS_PULL_REQUEST_BRANCH'] || env['TRAVIS_BRANCH']),
251
+ Git::TAG_COMMIT_SHA => env['TRAVIS_COMMIT'],
252
+ Git::TAG_REPOSITORY_URL => "https://github.com/#{env['TRAVIS_REPO_SLUG']}.git",
253
+ Git::TAG_TAG => env['TRAVIS_TAG'],
254
+ TAG_JOB_URL => env['TRAVIS_JOB_WEB_URL'],
255
+ TAG_PIPELINE_ID => env['TRAVIS_BUILD_ID'],
256
+ TAG_PIPELINE_NAME => env['TRAVIS_REPO_SLUG'],
257
+ TAG_PIPELINE_NUMBER => env['TRAVIS_BUILD_NUMBER'],
258
+ TAG_PIPELINE_URL => env['TRAVIS_BUILD_WEB_URL'],
259
+ TAG_PROVIDER_NAME => 'travisci',
260
+ TAG_WORKSPACE_PATH => env['TRAVIS_BUILD_DIR']
261
+ }
262
+ end
263
+ end
264
+ end
265
+ end