datadog-ci 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -1
  3. data/LICENSE-3rdparty.csv +1 -0
  4. data/README.md +64 -0
  5. data/lib/datadog/ci/configuration/components.rb +72 -5
  6. data/lib/datadog/ci/configuration/settings.rb +36 -8
  7. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +2 -3
  8. data/lib/datadog/ci/contrib/cucumber/formatter.rb +8 -10
  9. data/lib/datadog/ci/contrib/cucumber/integration.rb +3 -5
  10. data/lib/datadog/ci/contrib/integration.rb +149 -0
  11. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +2 -3
  12. data/lib/datadog/ci/contrib/minitest/hooks.rb +8 -4
  13. data/lib/datadog/ci/contrib/minitest/integration.rb +3 -5
  14. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +2 -3
  15. data/lib/datadog/ci/contrib/rspec/example.rb +5 -8
  16. data/lib/datadog/ci/contrib/rspec/integration.rb +3 -5
  17. data/lib/datadog/ci/contrib/settings.rb +33 -0
  18. data/lib/datadog/ci/ext/environment/providers/appveyor.rb +4 -0
  19. data/lib/datadog/ci/ext/environment/providers/aws_code_pipeline.rb +39 -0
  20. data/lib/datadog/ci/ext/environment/providers/azure.rb +4 -0
  21. data/lib/datadog/ci/ext/environment/providers/base.rb +4 -0
  22. data/lib/datadog/ci/ext/environment/providers/bitbucket.rb +4 -0
  23. data/lib/datadog/ci/ext/environment/providers/bitrise.rb +4 -0
  24. data/lib/datadog/ci/ext/environment/providers/buddy.rb +4 -0
  25. data/lib/datadog/ci/ext/environment/providers/buildkite.rb +4 -0
  26. data/lib/datadog/ci/ext/environment/providers/circleci.rb +4 -0
  27. data/lib/datadog/ci/ext/environment/providers/codefresh.rb +4 -0
  28. data/lib/datadog/ci/ext/environment/providers/github_actions.rb +4 -0
  29. data/lib/datadog/ci/ext/environment/providers/gitlab.rb +4 -0
  30. data/lib/datadog/ci/ext/environment/providers/jenkins.rb +4 -0
  31. data/lib/datadog/ci/ext/environment/providers/local_git.rb +7 -0
  32. data/lib/datadog/ci/ext/environment/providers/teamcity.rb +4 -0
  33. data/lib/datadog/ci/ext/environment/providers/travis.rb +4 -0
  34. data/lib/datadog/ci/ext/environment/providers.rb +16 -14
  35. data/lib/datadog/ci/ext/settings.rb +2 -0
  36. data/lib/datadog/ci/ext/transport.rb +24 -0
  37. data/lib/datadog/ci/{test.rb → recorder.rb} +6 -5
  38. data/lib/datadog/ci/test_visibility/flush.rb +40 -0
  39. data/lib/datadog/ci/test_visibility/serializers/base.rb +161 -0
  40. data/lib/datadog/ci/test_visibility/serializers/factories/test_level.rb +30 -0
  41. data/lib/datadog/ci/test_visibility/serializers/span.rb +51 -0
  42. data/lib/datadog/ci/test_visibility/serializers/test_v1.rb +60 -0
  43. data/lib/datadog/ci/test_visibility/transport.rb +151 -0
  44. data/lib/datadog/ci/transport/api/base.rb +36 -0
  45. data/lib/datadog/ci/transport/api/builder.rb +46 -0
  46. data/lib/datadog/ci/transport/api/ci_test_cycle.rb +30 -0
  47. data/lib/datadog/ci/transport/api/evp_proxy.rb +44 -0
  48. data/lib/datadog/ci/transport/gzip.rb +22 -0
  49. data/lib/datadog/ci/transport/http.rb +77 -0
  50. data/lib/datadog/ci/version.rb +2 -2
  51. data/sig/datadog/ci/configuration/components.rbs +4 -0
  52. data/sig/datadog/ci/configuration/settings.rbs +2 -0
  53. data/sig/datadog/ci/contrib/cucumber/configuration/settings.rbs +1 -1
  54. data/sig/datadog/ci/contrib/cucumber/integration.rbs +2 -1
  55. data/sig/datadog/ci/contrib/integration.rbs +44 -0
  56. data/sig/datadog/ci/contrib/minitest/configuration/settings.rbs +1 -1
  57. data/sig/datadog/ci/contrib/minitest/integration.rbs +4 -3
  58. data/sig/datadog/ci/contrib/rspec/configuration/settings.rbs +1 -1
  59. data/sig/datadog/ci/contrib/rspec/integration.rbs +3 -2
  60. data/sig/datadog/ci/contrib/settings.rbs +25 -0
  61. data/sig/datadog/ci/ext/environment/providers/aws_code_pipeline.rbs +19 -0
  62. data/sig/datadog/ci/ext/environment/providers/base.rbs +2 -0
  63. data/sig/datadog/ci/ext/environment/providers.rbs +1 -1
  64. data/sig/datadog/ci/ext/settings.rbs +2 -0
  65. data/sig/datadog/ci/ext/transport.rbs +29 -0
  66. data/sig/datadog/ci/{test.rbs → recorder.rbs} +1 -1
  67. data/sig/datadog/ci/test_visibility/flush.rbs +17 -0
  68. data/sig/datadog/ci/test_visibility/serializers/base.rbs +73 -0
  69. data/sig/datadog/ci/test_visibility/serializers/factories/test_level.rbs +13 -0
  70. data/sig/datadog/ci/test_visibility/serializers/span.rbs +18 -0
  71. data/sig/datadog/ci/test_visibility/serializers/test_v1.rbs +23 -0
  72. data/sig/datadog/ci/test_visibility/transport.rbs +35 -0
  73. data/sig/datadog/ci/transport/api/base.rbs +21 -0
  74. data/sig/datadog/ci/transport/api/builder.rbs +12 -0
  75. data/sig/datadog/ci/transport/api/ci_test_cycle.rbs +21 -0
  76. data/sig/datadog/ci/transport/api/evp_proxy.rbs +19 -0
  77. data/sig/datadog/ci/transport/gzip.rbs +9 -0
  78. data/sig/datadog/ci/transport/http.rbs +36 -0
  79. metadata +52 -8
  80. data/lib/datadog/ci/flush.rb +0 -38
  81. data/sig/datadog/ci/flush.rbs +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20f65248441964ee0af226ab2a401cb0c3b951bdde8cd359cfb43f46f379e3e5
4
- data.tar.gz: a8d4e496ae5037a5454072da2a0a3ca308b95889f0b077763f8ed1f4cd9f12b8
3
+ metadata.gz: ce3b4502404f6faa6b05421763ced6582071c9ad025937219b59ba8c63c39175
4
+ data.tar.gz: 7a341aa75161299cb04a29f745e172ef5ca4fec3a24f536ec96e08119de11a97
5
5
  SHA512:
6
- metadata.gz: dbffc3a2f982924c33e896314d6425b2521830b301372f43fba4e6e3038bfd4b5053d4a5efa529086a9854e78c9dc2492cc74f1a9aa3ec295db91d8b7515d0a3
7
- data.tar.gz: a477d14e4ab84c527cbfa988c41b9bbb521269e2c82fc1baaa0fc2ab488799d468b24274b79a40338cdec0500f100830f14a6eec83e286066533dbc90f63b19e
6
+ metadata.gz: 6058fbf497f43040a588018a2104055a303849d5616d063412dae4dab1e5247098e9ecd1b0b718776a51bc090f137d2bcf19cc78d252c7968c9cd6e4723ad902
7
+ data.tar.gz: 3c8d8eb9a34266a690a0dd5103d344b80df5175c703a414b1bc8255dc3c2732d723960e786765f2686fdcaaff5f009b675942c5e39dbd4a6fc9e58a38653051e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2023-10-25
4
+
5
+ ### Added
6
+
7
+ * Add AWS CodePipeline support for automatic CI tags extraction ([#54][])
8
+ * Support test visibility protocol via Datadog Agent with EVP proxy ([#51][])
9
+
10
+ ### Changed
11
+
12
+ * Migrate to Net::HTTP adapter from Core module of ddtrace gem ([#49][])
13
+
14
+ ## [0.2.0] - 2023-10-05
15
+
16
+ ### Added
17
+
18
+ * [CIAPP-2959] Agentless mode ([#33][])
19
+
20
+ ### Fixed
21
+
22
+ * [CIAPP-4278] Fix an issue with emojis in commit message breaking LocalGit tags provider ([#40][])
23
+
3
24
  ## [0.1.1] - 2023-09-14
4
25
 
5
26
  ### Fixed
@@ -26,7 +47,9 @@
26
47
 
27
48
  * Ruby versions < 2.7 no longer supported ([#8][])
28
49
 
29
- [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.1.1...main
50
+ [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.3.0...main
51
+ [0.3.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.2.0...v0.3.0
52
+ [0.2.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.1.1...v0.2.0
30
53
  [0.1.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.1.0...v0.1.1
31
54
 
32
55
  <!--- The following link definition list is generated by PimpMyChangelog --->
@@ -38,3 +61,8 @@
38
61
  [#20]: https://github.com/DataDog/datadog-ci-rb/issues/20
39
62
  [#28]: https://github.com/DataDog/datadog-ci-rb/issues/28
40
63
  [#31]: https://github.com/DataDog/datadog-ci-rb/issues/31
64
+ [#33]: https://github.com/DataDog/datadog-ci-rb/issues/33
65
+ [#40]: https://github.com/DataDog/datadog-ci-rb/issues/40
66
+ [#49]: https://github.com/DataDog/datadog-ci-rb/issues/49
67
+ [#51]: https://github.com/DataDog/datadog-ci-rb/issues/51
68
+ [#54]: https://github.com/DataDog/datadog-ci-rb/issues/54
data/LICENSE-3rdparty.csv CHANGED
@@ -1,2 +1,3 @@
1
1
  Component,Origin,License,Copyright
2
2
  dd-trace-rb,https://github.com/DataDog/dd-trace-rb,Apache 2.0,"Copyright 2016-Present Datadog, Inc."
3
+ msgpack,https://rubygems.org/gems/msgpack,Apache-2.0,"Copyright (c) 2008-2015 Sadayuki Furuhashi"
data/README.md CHANGED
@@ -117,6 +117,70 @@ end
117
117
  | `service_name` | Service name used for `cucumber` instrumentation. | `'cucumber'` |
118
118
  | `operation_name` | Operation name used for `cucumber` instrumentation. Useful if you want rename automatic trace metrics e.g. `trace.#{operation_name}.errors`. | `'cucumber.test'` |
119
119
 
120
+ ## Agentless mode
121
+
122
+ If you are using a cloud CI provider without access to the underlying worker nodes, such as GitHub Actions or CircleCI, configure the library to use the Agentless mode. For this, set the following environment variables:
123
+ `DD_CIVISIBILITY_AGENTLESS_ENABLED=true (Required)` and `DD_API_KEY=your_secret_api_key (Required)`.
124
+
125
+ Additionally, configure which [Datadog site](https://docs.datadoghq.com/getting_started/site/) you want to send data to:
126
+ `DD_SITE=your.datadoghq.com` (datadoghq.com by default).
127
+
128
+ Agentless mode can also be enabled via `Datadog.configure` (but don't forget to set DD_API_KEY environment variable):
129
+
130
+ ```ruby
131
+ Datadog.configure { |c| c.ci.agentless_mode_enabled = true }
132
+ ```
133
+
134
+ ## Additional configuration
135
+
136
+ ### Add tracing instrumentations
137
+
138
+ It can be useful to have rich tracing information about your tests that includes time spent performing database operations
139
+ or other external calls like here:
140
+
141
+ ![Test trace with redis instrumented](./docs/screenshots/test-trace-with-redis.png)
142
+
143
+ In order to achieve this you can configure ddtrace instrumentations in your configure block:
144
+
145
+ ```ruby
146
+ Datadog.configure do |c|
147
+ # ... ci configs and instrumentation here ...
148
+ c.instrument :redis
149
+ c.instrument :pg
150
+ end
151
+ ```
152
+
153
+ ...or enable auto instrumentation in your test_helper/spec_helper:
154
+
155
+ ```ruby
156
+ require "ddtrace/auto_instrument"
157
+ ```
158
+
159
+ Note: in CI mode these traces are going to be submitted to CI Visibility,
160
+ they will **not** show up in Datadog APM.
161
+
162
+ For the full list of available instrumentations see [ddtrace documentation](https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md)
163
+
164
+ ### Disabling startup logs
165
+
166
+ Startup logs produce a report of tracing state when the application is initially configured.
167
+ These logs are activated by default in test mode, if you don't want them you can disable this
168
+ via `diagnostics.startup_logs.enabled = false` or `DD_TRACE_STARTUP_LOGS=0`.
169
+
170
+ ```ruby
171
+ Datadog.configure { |c| c.diagnostics.startup_logs.enabled = false }
172
+ ```
173
+
174
+ ### Enabling debug mode
175
+
176
+ Switching the library into debug mode will produce verbose, detailed logs about tracing activity, including any suppressed errors. This output can be helpful in identifying errors, confirming trace output, or catching HTTP transport issues.
177
+
178
+ You can enable this via `diagnostics.debug = true` or `DD_TRACE_DEBUG=1`.
179
+
180
+ ```ruby
181
+ Datadog.configure { |c| c.diagnostics.debug = true }
182
+ ```
183
+
120
184
  ## Contributing
121
185
 
122
186
  See [development guide](/docs/DevelopmentGuide.md), [static typing guide](docs/StaticTypingGuide.md) and [contributing guidelines](/CONTRIBUTING.md).
@@ -1,6 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../flush"
3
+ require "datadog/core/configuration/agent_settings_resolver"
4
+ require "datadog/core/remote/negotiation"
5
+
6
+ require_relative "../ext/transport"
7
+ require_relative "../test_visibility/flush"
8
+ require_relative "../test_visibility/transport"
9
+ require_relative "../transport/api/builder"
4
10
 
5
11
  module Datadog
6
12
  module CI
@@ -16,15 +22,76 @@ module Datadog
16
22
  end
17
23
 
18
24
  def activate_ci!(settings)
25
+ test_visibility_transport = nil
26
+ agent_settings = Datadog::Core::Configuration::AgentSettingsResolver.call(settings)
27
+
28
+ if settings.ci.agentless_mode_enabled
29
+ test_visibility_transport = build_agentless_transport(settings)
30
+ elsif can_use_evp_proxy?(settings, agent_settings)
31
+ test_visibility_transport = build_evp_proxy_transport(settings, agent_settings)
32
+ end
33
+
34
+ # Deactivate telemetry
35
+ settings.telemetry.enabled = false
36
+
37
+ # Deactivate remote configuration
38
+ settings.remote.enabled = false
39
+
19
40
  # Activate underlying tracing test mode
20
41
  settings.tracing.test_mode.enabled = true
21
42
 
22
43
  # Choose user defined TraceFlush or default to CI TraceFlush
23
- settings.tracing.test_mode.trace_flush = settings.ci.trace_flush \
24
- || CI::Flush::Finished.new
44
+ settings.tracing.test_mode.trace_flush = settings.ci.trace_flush || CI::TestVisibility::Flush::Finished.new
45
+
46
+ writer_options = settings.ci.writer_options
47
+ if test_visibility_transport
48
+ writer_options[:transport] = test_visibility_transport
49
+ writer_options[:shutdown_timeout] = 60
50
+
51
+ settings.tracing.test_mode.async = true
52
+ end
53
+
54
+ settings.tracing.test_mode.writer_options = writer_options
55
+ end
56
+
57
+ def can_use_evp_proxy?(settings, agent_settings)
58
+ Datadog::Core::Remote::Negotiation.new(settings, agent_settings).endpoint?(
59
+ Ext::Transport::EVP_PROXY_PATH_PREFIX
60
+ )
61
+ end
62
+
63
+ def build_agentless_transport(settings)
64
+ if settings.api_key.nil?
65
+ # agentless mode is requested but no API key is provided -
66
+ # we cannot continue and log an error
67
+ # Tests are running without CI visibility enabled
68
+
69
+ Datadog.logger.error(
70
+ "DATADOG CONFIGURATION - CI VISIBILITY - ATTENTION - " \
71
+ "Agentless mode was enabled but DD_API_KEY is not set: CI visibility is disabled. " \
72
+ "Please make sure to set valid api key in DD_API_KEY environment variable"
73
+ )
74
+
75
+ settings.ci.enabled = false
76
+
77
+ nil
78
+ else
79
+ Datadog.logger.debug("CI visibility configured to use agentless transport")
80
+
81
+ Datadog::CI::TestVisibility::Transport.new(
82
+ api: Transport::Api::Builder.build_ci_test_cycle_api(settings),
83
+ dd_env: settings.env
84
+ )
85
+ end
86
+ end
87
+
88
+ def build_evp_proxy_transport(settings, agent_settings)
89
+ Datadog.logger.debug("CI visibility configured to use agent transport via EVP proxy")
25
90
 
26
- # Pass through any other options
27
- settings.tracing.test_mode.writer_options = settings.ci.writer_options
91
+ Datadog::CI::TestVisibility::Transport.new(
92
+ api: Transport::Api::Builder.build_evp_proxy_api(agent_settings),
93
+ dd_env: settings.env
94
+ )
28
95
  end
29
96
  end
30
97
  end
@@ -5,8 +5,10 @@ require_relative "../ext/settings"
5
5
  module Datadog
6
6
  module CI
7
7
  module Configuration
8
- # Adds CI behavior to Datadog trace settings
8
+ # Adds CI behavior to ddtrace settings
9
9
  module Settings
10
+ InvalidIntegrationError = Class.new(StandardError)
11
+
10
12
  def self.extended(base)
11
13
  base = base.singleton_class unless base.is_a?(Class)
12
14
  add_settings!(base)
@@ -21,16 +23,37 @@ module Datadog
21
23
  o.default false
22
24
  end
23
25
 
24
- # DEV: Alias to Datadog::Tracing::Contrib::Extensions::Configuration::Settings#instrument.
25
- # DEV: Should be removed when CI implement its own `c.ci.instrument`.
26
+ option :agentless_mode_enabled do |o|
27
+ o.type :bool
28
+ o.env CI::Ext::Settings::ENV_AGENTLESS_MODE_ENABLED
29
+ o.default false
30
+ end
31
+
32
+ option :agentless_url do |o|
33
+ o.type :string, nilable: true
34
+ o.env CI::Ext::Settings::ENV_AGENTLESS_URL
35
+ end
36
+
26
37
  define_method(:instrument) do |integration_name, options = {}, &block|
27
- Datadog.configuration.tracing.instrument(integration_name, options, &block)
38
+ return unless enabled
39
+
40
+ integration = fetch_integration(integration_name)
41
+ integration.configure(options, &block)
42
+
43
+ return unless integration.enabled
44
+
45
+ patch_results = integration.patch
46
+ next if patch_results == true
47
+
48
+ error_message = <<-ERROR
49
+ Available?: #{patch_results[:available]}, Loaded?: #{patch_results[:loaded]},
50
+ Compatible?: #{patch_results[:compatible]}, Patchable?: #{patch_results[:patchable]}"
51
+ ERROR
52
+ Datadog.logger.warn("Unable to patch #{integration_name} (#{error_message})")
28
53
  end
29
54
 
30
- # DEV: Alias to Datadog::Tracing::Contrib::Extensions::Configuration::Settings#instrument.
31
- # DEV: Should be removed when CI implement its own `c.ci[]`.
32
- define_method(:[]) do |integration_name, key = :default|
33
- Datadog.configuration.tracing[integration_name, key]
55
+ define_method(:[]) do |integration_name|
56
+ fetch_integration(integration_name).configuration
34
57
  end
35
58
 
36
59
  # TODO: Deprecate in the next major version, as `instrument` better describes this method's purpose
@@ -42,6 +65,11 @@ module Datadog
42
65
  o.type :hash
43
66
  o.default({})
44
67
  end
68
+
69
+ define_method(:fetch_integration) do |name|
70
+ Datadog::CI::Contrib::Integration.registry[name] ||
71
+ raise(InvalidIntegrationError, "'#{name}' is not a valid integration.")
72
+ end
45
73
  end
46
74
  end
47
75
  end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../ext"
4
-
5
- require "datadog/tracing/contrib/configuration/settings"
4
+ require_relative "../../settings"
6
5
 
7
6
  module Datadog
8
7
  module CI
@@ -11,7 +10,7 @@ module Datadog
11
10
  module Configuration
12
11
  # Custom settings for the Cucumber integration
13
12
  # TODO: mark as `@public_api` when GA
14
- class Settings < Datadog::Tracing::Contrib::Configuration::Settings
13
+ class Settings < Datadog::CI::Contrib::Settings
15
14
  option :enabled do |o|
16
15
  o.type :bool
17
16
  o.env Ext::ENV_ENABLED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../test"
4
- require_relative "../../ext/app_types"
5
- require_relative "../../ext/environment"
3
+ require_relative "../../recorder"
6
4
  require_relative "../../ext/test"
7
5
  require_relative "ext"
8
6
 
@@ -30,7 +28,7 @@ module Datadog
30
28
  end
31
29
 
32
30
  def on_test_case_started(event)
33
- @current_feature_span = CI::Test.trace(
31
+ @current_feature_span = CI::Recorder.trace(
34
32
  configuration[:operation_name],
35
33
  {
36
34
  span_options: {
@@ -50,11 +48,11 @@ module Datadog
50
48
  return if @current_feature_span.nil?
51
49
 
52
50
  if event.result.skipped?
53
- CI::Test.skipped!(@current_feature_span)
51
+ CI::Recorder.skipped!(@current_feature_span)
54
52
  elsif event.result.ok?
55
- CI::Test.passed!(@current_feature_span)
53
+ CI::Recorder.passed!(@current_feature_span)
56
54
  elsif event.result.failed?
57
- CI::Test.failed!(@current_feature_span)
55
+ CI::Recorder.failed!(@current_feature_span)
58
56
  end
59
57
 
60
58
  @current_feature_span.finish
@@ -72,11 +70,11 @@ module Datadog
72
70
  return if @current_step_span.nil?
73
71
 
74
72
  if event.result.skipped?
75
- CI::Test.skipped!(@current_step_span, event.result.exception)
73
+ CI::Recorder.skipped!(@current_step_span, event.result.exception)
76
74
  elsif event.result.ok?
77
- CI::Test.passed!(@current_step_span)
75
+ CI::Recorder.passed!(@current_step_span)
78
76
  elsif event.result.failed?
79
- CI::Test.failed!(@current_step_span, event.result.exception)
77
+ CI::Recorder.failed!(@current_step_span, event.result.exception)
80
78
  end
81
79
 
82
80
  @current_step_span.finish
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "datadog/tracing/contrib"
4
- require "datadog/tracing/contrib/integration"
5
-
3
+ require_relative "../integration"
6
4
  require_relative "configuration/settings"
7
5
  require_relative "patcher"
8
6
 
@@ -12,11 +10,11 @@ module Datadog
12
10
  module Cucumber
13
11
  # Description of Cucumber integration
14
12
  class Integration
15
- include Datadog::Tracing::Contrib::Integration
13
+ include Datadog::CI::Contrib::Integration
16
14
 
17
15
  MINIMUM_VERSION = Gem::Version.new("3.0.0")
18
16
 
19
- register_as :cucumber, auto_patch: true
17
+ register_as :cucumber
20
18
 
21
19
  def self.version
22
20
  Gem.loaded_specs["cucumber"] \
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "settings"
4
+
5
+ module Datadog
6
+ module CI
7
+ module Contrib
8
+ module Integration
9
+ @registry = {}
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ base.include(InstanceMethods)
14
+ end
15
+
16
+ def self.register(klass, name)
17
+ registry[name] = klass.new
18
+ end
19
+
20
+ def self.registry
21
+ @registry
22
+ end
23
+
24
+ # Class-level methods for Integration
25
+ module ClassMethods
26
+ def register_as(name)
27
+ Integration.register(self, name)
28
+ end
29
+
30
+ # Version of the integration target code in the environment.
31
+ #
32
+ # This is the gem version, when the instrumentation target is a Ruby gem.
33
+ #
34
+ # If the target for instrumentation has concept of versioning, override {.version},
35
+ # otherwise override {.available?} and implement a custom target presence check.
36
+ # @return [Object] the target version
37
+ def version
38
+ nil
39
+ end
40
+
41
+ # Is the target available to be instrumented? (e.g. gem installed?)
42
+ #
43
+ # The target doesn't have to be loaded (e.g. `require`) yet, but needs to be able
44
+ # to be loaded before instrumentation can commence.
45
+ #
46
+ # By default, {.available?} checks if {.version} returned a non-nil object.
47
+ #
48
+ # If the target for instrumentation has concept of versioning, override {.version},
49
+ # otherwise override {.available?} and implement a custom target presence check.
50
+ # @return [Boolean] is the target available for instrumentation in this Ruby environment?
51
+ def available?
52
+ !version.nil?
53
+ end
54
+
55
+ # Is the target loaded into the application? (e.g. gem required? Constant defined?)
56
+ #
57
+ # The target's objects should be ready to be referenced by the instrumented when {.loaded}
58
+ # returns `true`.
59
+ #
60
+ # @return [Boolean] is the target ready to be referenced during instrumentation?
61
+ def loaded?
62
+ true
63
+ end
64
+
65
+ # Is this instrumentation compatible with the available target? (e.g. minimum version met?)
66
+ # @return [Boolean] is the available target compatible with this instrumentation?
67
+ def compatible?
68
+ available?
69
+ end
70
+
71
+ # Can the patch for this integration be applied?
72
+ #
73
+ # By default, this is equivalent to {#available?}, {#loaded?}, and {#compatible?}
74
+ # all being truthy.
75
+ def patchable?
76
+ available? && loaded? && compatible?
77
+ end
78
+ end
79
+
80
+ module InstanceMethods
81
+ # returns the configuration instance.
82
+ def configuration
83
+ @configuration ||= new_configuration
84
+ end
85
+
86
+ def configure(options = {}, &block)
87
+ configuration.configure(options, &block)
88
+ configuration
89
+ end
90
+
91
+ # Resets all configuration options
92
+ def reset_configuration!
93
+ @configuration = nil
94
+ end
95
+
96
+ def enabled
97
+ configuration.enabled
98
+ end
99
+
100
+ # The patcher module to inject instrumented objects into the instrumentation target.
101
+ #
102
+ # {Contrib::Patcher} includes the basic functionality of a patcher. `include`ing
103
+ # {Contrib::Patcher} into a new module is the recommend way to create a custom patcher.
104
+ #
105
+ # @return [Contrib::Patcher] a module that `include`s {Contrib::Patcher}
106
+ def patcher
107
+ nil
108
+ end
109
+
110
+ # @!visibility private
111
+ def patch
112
+ # @type var patcher_klass: untyped
113
+ patcher_klass = patcher
114
+ if !self.class.patchable? || patcher_klass.nil?
115
+ return {
116
+ available: self.class.available?,
117
+ loaded: self.class.loaded?,
118
+ compatible: self.class.compatible?,
119
+ patchable: self.class.patchable?
120
+ }
121
+ end
122
+
123
+ patcher_klass.patch
124
+ true
125
+ end
126
+
127
+ # Can the patch for this integration be applied automatically?
128
+ # @return [Boolean] can the tracer activate this instrumentation without explicit user input?
129
+ def auto_instrument?
130
+ true
131
+ end
132
+
133
+ protected
134
+
135
+ # Returns a new configuration object for this integration.
136
+ #
137
+ # This method normally needs to be overridden for each integration
138
+ # as their settings, defaults and environment variables are
139
+ # specific for each integration.
140
+ #
141
+ # @return [Datadog::CI::Contrib::Settings] a new, integration-specific settings object
142
+ def new_configuration
143
+ Datadog::CI::Contrib::Settings.new
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../ext"
4
-
5
- require "datadog/tracing/contrib/configuration/settings"
4
+ require_relative "../../settings"
6
5
 
7
6
  module Datadog
8
7
  module CI
@@ -11,7 +10,7 @@ module Datadog
11
10
  module Configuration
12
11
  # Custom settings for the Minitest integration
13
12
  # TODO: mark as `@public_api` when GA
14
- class Settings < Datadog::Tracing::Contrib::Configuration::Settings
13
+ class Settings < Datadog::CI::Contrib::Settings
15
14
  option :enabled do |o|
16
15
  o.type :bool
17
16
  o.env Ext::ENV_ENABLED
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../recorder"
4
+ require_relative "../../ext/test"
5
+ require_relative "ext"
6
+
3
7
  module Datadog
4
8
  module CI
5
9
  module Contrib
@@ -15,7 +19,7 @@ module Datadog
15
19
  path, = method(name).source_location
16
20
  test_suite = Pathname.new(path.to_s).relative_path_from(Pathname.pwd).to_s
17
21
 
18
- span = CI::Test.trace(
22
+ span = CI::Recorder.trace(
19
23
  configuration[:operation_name],
20
24
  {
21
25
  span_options: {
@@ -41,11 +45,11 @@ module Datadog
41
45
 
42
46
  case result_code
43
47
  when "."
44
- CI::Test.passed!(span)
48
+ CI::Recorder.passed!(span)
45
49
  when "E", "F"
46
- CI::Test.failed!(span, failure)
50
+ CI::Recorder.failed!(span, failure)
47
51
  when "S"
48
- CI::Test.skipped!(span)
52
+ CI::Recorder.skipped!(span)
49
53
  span.set_tag(CI::Ext::Test::TAG_SKIP_REASON, failure.message)
50
54
  end
51
55
 
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "datadog/tracing/contrib"
4
- require "datadog/tracing/contrib/integration"
5
-
3
+ require_relative "../integration"
6
4
  require_relative "configuration/settings"
7
5
  require_relative "patcher"
8
6
 
@@ -12,11 +10,11 @@ module Datadog
12
10
  module Minitest
13
11
  # Description of Minitest integration
14
12
  class Integration
15
- include Datadog::Tracing::Contrib::Integration
13
+ include Datadog::CI::Contrib::Integration
16
14
 
17
15
  MINIMUM_VERSION = Gem::Version.new("5.0.0")
18
16
 
19
- register_as :minitest, auto_patch: true
17
+ register_as :minitest
20
18
 
21
19
  def self.version
22
20
  Gem.loaded_specs["minitest"] && Gem.loaded_specs["minitest"].version
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../ext"
4
-
5
- require "datadog/tracing/contrib/configuration/settings"
4
+ require_relative "../../settings"
6
5
 
7
6
  module Datadog
8
7
  module CI
@@ -11,7 +10,7 @@ module Datadog
11
10
  module Configuration
12
11
  # Custom settings for the RSpec integration
13
12
  # TODO: mark as `@public_api` when GA
14
- class Settings < Datadog::Tracing::Contrib::Configuration::Settings
13
+ class Settings < Datadog::CI::Contrib::Settings
15
14
  option :enabled do |o|
16
15
  o.type :bool
17
16
  o.env Ext::ENV_ENABLED
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../test"
4
-
5
- require_relative "../../ext/app_types"
6
- require_relative "../../ext/environment"
3
+ require_relative "../../recorder"
7
4
  require_relative "../../ext/test"
8
5
  require_relative "ext"
9
6
 
@@ -28,7 +25,7 @@ module Datadog
28
25
  test_name += " #{description}"
29
26
  end
30
27
 
31
- CI::Test.trace(
28
+ CI::Recorder.trace(
32
29
  configuration[:operation_name],
33
30
  {
34
31
  span_options: {
@@ -46,11 +43,11 @@ module Datadog
46
43
 
47
44
  case execution_result.status
48
45
  when :passed
49
- CI::Test.passed!(span)
46
+ CI::Recorder.passed!(span)
50
47
  when :failed
51
- CI::Test.failed!(span, execution_result.exception)
48
+ CI::Recorder.failed!(span, execution_result.exception)
52
49
  else
53
- CI::Test.skipped!(span, execution_result.exception) if execution_result.example_skipped?
50
+ CI::Recorder.skipped!(span, execution_result.exception) if execution_result.example_skipped?
54
51
  end
55
52
 
56
53
  result