datadog-ci 0.7.0 → 0.8.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14828e8c64b8eeb9c04d4ae2563e568b3b920b587f8e97e628896b143219daf0
4
- data.tar.gz: b538d180acd0c18e1d8070adfdcd9f44dad65331048619de40db04cd876dfe01
3
+ metadata.gz: bf750f24412b0800ba1599f22c5b12e8679dddc1d0e9a30aed98d0a51a6badd3
4
+ data.tar.gz: 652631fac9702beb340f136e32d4b72b3b38d7c84a8de7dc8ce4f203dc67983b
5
5
  SHA512:
6
- metadata.gz: 60f8fda5f530404027669902b194c7e056af834c882adbc2b7d350eb62f7f75c2d63dae23bf6e98a8bebea0cc8ec34d4f5416fe667d1c30dff1fdb7ebb42854d
7
- data.tar.gz: 1b2ad405dee8a1dd2ce24c3d5738ddcbc751f85d5aa5c29a287b614dcfc0a4764230a3b53e59967247fd0f64711fd81fc3863e49895098e7664aa81a3bf1b8e6
6
+ metadata.gz: 3295d136609aca4be41cc041613873297a5e91bb37a428a6612a1e62f7e547db2bb2c836f4a0348fdd4466d085a29ec78a26962d48f1c59e05163dcb26668783
7
+ data.tar.gz: 5446bba62689a4133a75b64437efd47f8369814e863c8ddab0c91d52692b5bf71b5be2a4f4264839ec81374ff3c4ff498e4c2cd7a8c54f566e63558cb1f55cff
data/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.8.3] - 2024-03-20
4
+
5
+ ### Fixed
6
+
7
+ * fix: cucumber-ruby 9.2 includes breaking change for Cucumber::Core::Test::Result ([#145][])
8
+
9
+ ### Changed
10
+
11
+ * remove temporary hack and use Core::Remote::Negotiation's new constructor param ([#142][])
12
+ * use filter_basic_auth method from Datadog::Core ([#141][])
13
+
14
+ ## [0.8.2] - 2024-03-19
15
+
16
+ ### Fixed
17
+
18
+ * assign the single running test suite for a test if none found by test suite name ([#139][])
19
+
20
+ ## [0.8.1] - 2024-03-12
21
+
22
+ ### Fixed
23
+
24
+ * fix minitest instrumentation with mixins ([#134][])
25
+
26
+ ## [0.8.0] - 2024-03-08
27
+
28
+ ### Added
29
+
30
+ * gzip agent payloads support via evp_proxy/v4 ([#123][])
31
+
32
+ ### Changed
33
+
34
+ * Add note to README on using VCR ([#122][])
35
+
36
+ ### Fixed
37
+
38
+ * use framework name as test module name to make test fingerprints stable ([#131][])
39
+
3
40
  ## [0.7.0] - 2024-01-26
4
41
 
5
42
  ### Added
@@ -150,7 +187,11 @@ Currently test suite level visibility is not used by our instrumentation: it wil
150
187
 
151
188
  * Ruby versions < 2.7 no longer supported ([#8][])
152
189
 
153
- [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.7.0...main
190
+ [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.3...main
191
+ [0.8.3]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.2...v0.8.3
192
+ [0.8.2]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.1...v0.8.2
193
+ [0.8.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.8.0...v0.8.1
194
+ [0.8.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.7.0...v0.8.0
154
195
  [0.7.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.6.0...v0.7.0
155
196
  [0.6.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.5.1...v0.6.0
156
197
  [0.5.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.5.0...v0.5.1
@@ -213,3 +254,11 @@ Currently test suite level visibility is not used by our instrumentation: it wil
213
254
  [#113]: https://github.com/DataDog/datadog-ci-rb/issues/113
214
255
  [#114]: https://github.com/DataDog/datadog-ci-rb/issues/114
215
256
  [#115]: https://github.com/DataDog/datadog-ci-rb/issues/115
257
+ [#122]: https://github.com/DataDog/datadog-ci-rb/issues/122
258
+ [#123]: https://github.com/DataDog/datadog-ci-rb/issues/123
259
+ [#131]: https://github.com/DataDog/datadog-ci-rb/issues/131
260
+ [#134]: https://github.com/DataDog/datadog-ci-rb/issues/134
261
+ [#139]: https://github.com/DataDog/datadog-ci-rb/issues/139
262
+ [#141]: https://github.com/DataDog/datadog-ci-rb/issues/141
263
+ [#142]: https://github.com/DataDog/datadog-ci-rb/issues/142
264
+ [#145]: https://github.com/DataDog/datadog-ci-rb/issues/145
data/README.md CHANGED
@@ -79,6 +79,25 @@ if ENV["DD_ENV"] == "ci"
79
79
  end
80
80
  ```
81
81
 
82
+ > [!IMPORTANT]
83
+ > When using `minitest/autorun` the order of requires matters: `datadog/ci` must be
84
+ > always required before `minitest/autorun`.
85
+
86
+ Example using `minitest/autorun`
87
+
88
+ ```ruby
89
+ require 'datadog/ci'
90
+ require 'minitest/autorun'
91
+
92
+ if ENV["DD_ENV"] == "ci"
93
+ Datadog.configure do |c|
94
+ c.ci.enabled = true
95
+ c.service = 'my-ruby-app'
96
+ c.ci.instrument :minitest
97
+ end
98
+ end
99
+ ```
100
+
82
101
  `options` are the following keyword arguments:
83
102
 
84
103
  | Key | Description | Default |
@@ -175,7 +194,7 @@ Webmock accordingly.
175
194
  ```ruby
176
195
  # when using agentless mode
177
196
  # note to use the correct datadog site (e.g. datadoghq.eu, etc)
178
- WebMock.disable_net_connect!(:allow => "citestcycle-intake.datadoghq.com")
197
+ WebMock.disable_net_connect!(:allow => /datadoghq.com/)
179
198
 
180
199
  # when using agent
181
200
  WebMock.disable_net_connect!(:allow_localhost => true)
@@ -184,6 +203,25 @@ WebMock.disable_net_connect!(:allow_localhost => true)
184
203
  WebMock.disable_net_connect!(:allow => "localhost:8126")
185
204
  ```
186
205
 
206
+ ### VCR
207
+
208
+ [VCR](https://github.com/vcr/vcr) is another popular testing library for HTTP interactions.
209
+
210
+ It requires additional configuration to correctly work with datadog-ci:
211
+
212
+ ```ruby
213
+ VCR.configure do |config|
214
+ # ... your usual configuration here ...
215
+
216
+ # when using agent
217
+ config.ignore_hosts "127.0.0.1", "localhost"
218
+
219
+ # when using agentless mode
220
+ # note to use the correct datadog site (e.g. datadoghq.eu, etc)
221
+ config.ignore_hosts "citestcycle-intake.datadoghq.com", "api.datadoghq.com"
222
+ end
223
+ ```
224
+
187
225
  ### Disabling startup logs
188
226
 
189
227
  Startup logs produce a report of tracing state when the application is initially configured.
@@ -1,10 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "datadog/core/configuration/agent_settings_resolver"
4
- require "datadog/core/remote/negotiation"
5
-
6
- require_relative "../ext/transport"
7
3
  require_relative "../ext/settings"
4
+ require_relative "../itr/runner"
8
5
  require_relative "../test_visibility/flush"
9
6
  require_relative "../test_visibility/recorder"
10
7
  require_relative "../test_visibility/null_recorder"
@@ -12,6 +9,7 @@ require_relative "../test_visibility/serializers/factories/test_level"
12
9
  require_relative "../test_visibility/serializers/factories/test_suite_level"
13
10
  require_relative "../test_visibility/transport"
14
11
  require_relative "../transport/api/builder"
12
+ require_relative "../transport/remote_settings_api"
15
13
 
16
14
  module Datadog
17
15
  module CI
@@ -32,18 +30,7 @@ module Datadog
32
30
  end
33
31
 
34
32
  def activate_ci!(settings)
35
- test_visibility_transport = nil
36
- agent_settings = Datadog::Core::Configuration::AgentSettingsResolver.call(settings)
37
-
38
- if settings.ci.agentless_mode_enabled
39
- check_dd_site(settings)
40
- test_visibility_transport = build_agentless_transport(settings)
41
- elsif can_use_evp_proxy?(settings, agent_settings)
42
- test_visibility_transport = build_evp_proxy_transport(settings, agent_settings)
43
- else
44
- settings.ci.force_test_level_visibility = true
45
- end
46
-
33
+ # Configure ddtrace library for CI visibility mode
47
34
  # Deactivate telemetry
48
35
  settings.telemetry.enabled = false
49
36
 
@@ -60,62 +47,77 @@ module Datadog
60
47
  # Choose user defined TraceFlush or default to CI TraceFlush
61
48
  settings.tracing.test_mode.trace_flush = settings.ci.trace_flush || CI::TestVisibility::Flush::Partial.new
62
49
 
50
+ # transport creation
63
51
  writer_options = settings.ci.writer_options
64
- if test_visibility_transport
65
- writer_options[:transport] = test_visibility_transport
52
+ test_visibility_api = build_test_visibility_api(settings)
53
+
54
+ if test_visibility_api
55
+ writer_options[:transport] = Datadog::CI::TestVisibility::Transport.new(
56
+ api: test_visibility_api,
57
+ serializers_factory: serializers_factory(settings),
58
+ dd_env: settings.env
59
+ )
66
60
  writer_options[:shutdown_timeout] = 60
67
61
  writer_options[:buffer_size] = 10_000
68
62
 
69
63
  settings.tracing.test_mode.async = true
64
+ else
65
+ # only legacy APM protocol is supported, so no test suite level visibility
66
+ settings.ci.force_test_level_visibility = true
67
+
68
+ # ITR is not supported with APM protocol
69
+ settings.ci.itr_enabled = false
70
70
  end
71
71
 
72
72
  settings.tracing.test_mode.writer_options = writer_options
73
73
 
74
- @ci_recorder = TestVisibility::Recorder.new(
75
- test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility
74
+ itr = Datadog::CI::ITR::Runner.new(
75
+ enabled: settings.ci.enabled && settings.ci.itr_enabled
76
76
  )
77
- end
78
77
 
79
- def can_use_evp_proxy?(settings, agent_settings)
80
- Datadog::Core::Remote::Negotiation.new(settings, agent_settings).endpoint?(
81
- Ext::Transport::EVP_PROXY_PATH_PREFIX
78
+ remote_settings_api = Transport::RemoteSettingsApi.new(
79
+ api: test_visibility_api,
80
+ dd_env: settings.env
81
+ )
82
+
83
+ # CI visibility recorder global instance
84
+ @ci_recorder = TestVisibility::Recorder.new(
85
+ test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
86
+ itr: itr,
87
+ remote_settings_api: remote_settings_api
82
88
  )
83
89
  end
84
90
 
85
- def build_agentless_transport(settings)
86
- if settings.api_key.nil?
87
- # agentless mode is requested but no API key is provided -
88
- # we cannot continue and log an error
89
- # Tests are running without CI visibility enabled
91
+ def build_test_visibility_api(settings)
92
+ if settings.ci.agentless_mode_enabled
93
+ check_dd_site(settings)
90
94
 
91
- Datadog.logger.error(
92
- "DATADOG CONFIGURATION - CI VISIBILITY - ATTENTION - " \
93
- "Agentless mode was enabled but DD_API_KEY is not set: CI visibility is disabled. " \
94
- "Please make sure to set valid api key in DD_API_KEY environment variable"
95
- )
95
+ Datadog.logger.debug("CI visibility configured to use agentless transport")
96
96
 
97
- settings.ci.enabled = false
97
+ api = Transport::Api::Builder.build_agentless_api(settings)
98
+ if api.nil?
99
+ Datadog.logger.error do
100
+ "DATADOG CONFIGURATION - CI VISIBILITY - ATTENTION - " \
101
+ "Agentless mode was enabled but DD_API_KEY is not set: CI visibility is disabled. " \
102
+ "Please make sure to set valid api key in DD_API_KEY environment variable"
103
+ end
98
104
 
99
- nil
100
- else
101
- Datadog.logger.debug("CI visibility configured to use agentless transport")
105
+ # Tests are running without CI visibility enabled
106
+ settings.ci.enabled = false
107
+ end
102
108
 
103
- Datadog::CI::TestVisibility::Transport.new(
104
- api: Transport::Api::Builder.build_ci_test_cycle_api(settings),
105
- serializers_factory: serializers_factory(settings),
106
- dd_env: settings.env
107
- )
109
+ else
110
+ Datadog.logger.debug("CI visibility configured to use agent transport via EVP proxy")
111
+
112
+ api = Transport::Api::Builder.build_evp_proxy_api(settings)
113
+ if api.nil?
114
+ Datadog.logger.debug(
115
+ "Old agent version detected, no evp_proxy support. Forcing test level visibility mode"
116
+ )
117
+ end
108
118
  end
109
- end
110
-
111
- def build_evp_proxy_transport(settings, agent_settings)
112
- Datadog.logger.debug("CI visibility configured to use agent transport via EVP proxy")
113
119
 
114
- Datadog::CI::TestVisibility::Transport.new(
115
- api: Transport::Api::Builder.build_evp_proxy_api(agent_settings),
116
- serializers_factory: serializers_factory(settings),
117
- dd_env: settings.env
118
- )
120
+ api
119
121
  end
120
122
 
121
123
  def serializers_factory(settings)
@@ -130,11 +132,11 @@ module Datadog
130
132
  return if settings.site.nil?
131
133
  return if Ext::Settings::DD_SITE_ALLOWLIST.include?(settings.site)
132
134
 
133
- Datadog.logger.warn(
135
+ Datadog.logger.warn do
134
136
  "CI VISIBILITY CONFIGURATION " \
135
137
  "Agentless mode was enabled but DD_SITE is not set to one of the following: #{Ext::Settings::DD_SITE_ALLOWLIST.join(", ")}. " \
136
138
  "Please make sure to set valid site in DD_SITE environment variable"
137
- )
139
+ end
138
140
  end
139
141
  end
140
142
  end
@@ -55,6 +55,12 @@ module Datadog
55
55
  end
56
56
  end
57
57
 
58
+ option :itr_enabled do |o|
59
+ o.type :bool
60
+ o.env CI::Ext::Settings::ENV_ITR_ENABLED
61
+ o.default false
62
+ end
63
+
58
64
  define_method(:instrument) do |integration_name, options = {}, &block|
59
65
  return unless enabled
60
66
 
@@ -34,14 +34,14 @@ module Datadog
34
34
  end
35
35
 
36
36
  def on_test_run_started(event)
37
- test_session = CI.start_test_session(
37
+ CI.start_test_session(
38
38
  tags: {
39
39
  CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
40
40
  CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Cucumber::Integration.version.to_s
41
41
  },
42
42
  service: configuration[:service_name]
43
43
  )
44
- CI.start_test_module(test_session.name) if test_session
44
+ CI.start_test_module(Ext::FRAMEWORK)
45
45
  end
46
46
 
47
47
  def on_test_run_finished(event)
@@ -113,7 +113,7 @@ module Datadog
113
113
  end
114
114
 
115
115
  def finish_span(span, result)
116
- if !result.passed? && result.ok?(@config.strict)
116
+ if !result.passed? && ok?(result, @config.strict)
117
117
  span.skipped!(reason: result.message)
118
118
  elsif result.passed?
119
119
  span.passed!
@@ -186,6 +186,16 @@ module Datadog
186
186
  nil
187
187
  end
188
188
 
189
+ def ok?(result, strict)
190
+ # in minor update in Cucumber 9.2.0, the arity of the `ok?` method changed
191
+ parameters = result.method(:ok?).parameters
192
+ if parameters == [[:opt, :be_strict]]
193
+ result.ok?(strict)
194
+ else
195
+ result.ok?(strict: strict)
196
+ end
197
+ end
198
+
189
199
  def configuration
190
200
  Datadog.configuration.ci[:cucumber]
191
201
  end
@@ -6,7 +6,12 @@ module Datadog
6
6
  module Minitest
7
7
  module Helpers
8
8
  def self.test_suite_name(klass, method_name)
9
- source_location, = klass.instance_method(method_name).source_location
9
+ source_location = extract_source_location_from_class(klass)
10
+ # if we are in anonymous class, fallback to the method source location
11
+ if source_location.nil?
12
+ source_location, = klass.instance_method(method_name).source_location
13
+ end
14
+
10
15
  source_file_path = Pathname.new(source_location.to_s).relative_path_from(Pathname.pwd).to_s
11
16
 
12
17
  "#{klass.name} at #{source_file_path}"
@@ -16,6 +21,15 @@ module Datadog
16
21
  klass.ancestors.include?(::Minitest::Parallel::Test) ||
17
22
  (defined?(::Minitest::Queue) && ::Minitest.singleton_class.ancestors.include?(::Minitest::Queue))
18
23
  end
24
+
25
+ def self.extract_source_location_from_class(klass)
26
+ return nil if klass.nil? || klass.name.nil?
27
+
28
+ source_location = klass.const_source_location(klass.name)
29
+ source_location.first unless source_location.nil?
30
+ rescue
31
+ nil
32
+ end
19
33
  end
20
34
  end
21
35
  end
@@ -18,14 +18,14 @@ module Datadog
18
18
 
19
19
  return unless datadog_configuration[:enabled]
20
20
 
21
- test_session = CI.start_test_session(
21
+ CI.start_test_session(
22
22
  tags: {
23
23
  CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
24
24
  CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Minitest::Integration.version.to_s
25
25
  },
26
26
  service: datadog_configuration[:service_name]
27
27
  )
28
- CI.start_test_module(test_session.name) if test_session
28
+ CI.start_test_module(Ext::FRAMEWORK)
29
29
  end
30
30
 
31
31
  private
@@ -25,13 +25,12 @@ module Datadog
25
25
  service: datadog_configuration[:service_name]
26
26
  )
27
27
 
28
- test_module = CI.start_test_module(test_session.name) if test_session
28
+ test_module = CI.start_test_module(Ext::FRAMEWORK)
29
29
 
30
30
  result = super
31
31
  return result unless test_module && test_session
32
32
 
33
33
  if result != 0
34
- # TODO: repeating this twice feels clunky, we need to remove test_module API before GA
35
34
  test_module.failed!
36
35
  test_session.failed!
37
36
  else
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "datadog/core/utils/url"
4
+
3
5
  require_relative "../git"
4
6
  require_relative "../../utils/git"
5
- require_relative "../../utils/url"
6
7
  require_relative "providers"
7
8
 
8
9
  module Datadog
@@ -76,7 +77,7 @@ module Datadog
76
77
 
77
78
  @tags[Git::TAG_TAG] = Utils::Git.normalize_ref(@tags[Git::TAG_TAG])
78
79
  @tags[Git::TAG_BRANCH] = Utils::Git.normalize_ref(@tags[Git::TAG_BRANCH])
79
- @tags[Git::TAG_REPOSITORY_URL] = Utils::Url.filter_sensitive_info(
80
+ @tags[Git::TAG_REPOSITORY_URL] = Datadog::Core::Utils::Url.filter_basic_auth(
80
81
  @tags[Git::TAG_REPOSITORY_URL]
81
82
  )
82
83
  end
@@ -2,8 +2,9 @@
2
2
 
3
3
  require "json"
4
4
 
5
+ require "datadog/core/utils/url"
6
+
5
7
  require_relative "base"
6
- require_relative "../../../utils/url"
7
8
 
8
9
  module Datadog
9
10
  module CI
@@ -79,7 +80,7 @@ module Datadog
79
80
  def github_server_url
80
81
  return @github_server_url if defined?(@github_server_url)
81
82
 
82
- @github_server_url ||= Utils::Url.filter_sensitive_info(env["GITHUB_SERVER_URL"])
83
+ @github_server_url ||= Datadog::Core::Utils::Url.filter_basic_auth(env["GITHUB_SERVER_URL"])
83
84
  end
84
85
  end
85
86
  end
@@ -10,6 +10,7 @@ module Datadog
10
10
  ENV_AGENTLESS_URL = "DD_CIVISIBILITY_AGENTLESS_URL"
11
11
  ENV_EXPERIMENTAL_TEST_SUITE_LEVEL_VISIBILITY_ENABLED = "DD_CIVISIBILITY_EXPERIMENTAL_TEST_SUITE_LEVEL_VISIBILITY_ENABLED"
12
12
  ENV_FORCE_TEST_LEVEL_VISIBILITY = "DD_CIVISIBILITY_FORCE_TEST_LEVEL_VISIBILITY"
13
+ ENV_ITR_ENABLED = "DD_CIVISIBILITY_ITR_ENABLED"
13
14
 
14
15
  # Source: https://docs.datadoghq.com/getting_started/site/
15
16
  DD_SITE_ALLOWLIST = [
@@ -23,6 +23,13 @@ module Datadog
23
23
  TAG_CODEOWNERS = "test.codeowners"
24
24
  TAG_PARAMETERS = "test.parameters"
25
25
 
26
+ # ITR tags
27
+ TAG_ITR_TEST_SKIPPING_ENABLED = "test.itr.tests_skipping.enabled"
28
+ TAG_ITR_TEST_SKIPPING_TYPE = "test.itr.tests_skipping.type"
29
+
30
+ # Code coverage tags
31
+ TAG_CODE_COVERAGE_ENABLED = "test.code_coverage.enabled"
32
+
26
33
  # those tags are special and used to correlate tests with the test sessions, suites, and modules
27
34
  # they are transient and not sent to the backend
28
35
  TAG_TEST_SESSION_ID = "_test.session_id"
@@ -43,6 +50,10 @@ module Datadog
43
50
  TAG_SPAN_KIND = "span.kind"
44
51
  SPAN_KIND_TEST = "test"
45
52
 
53
+ # could be either "test" or "suite" depending on whether we skip individual tests or whole suites
54
+ # we use test skipping for Ruby
55
+ ITR_TEST_SKIPPING_MODE = "test"
56
+
46
57
  # test status as recognized by Datadog
47
58
  module Status
48
59
  PASS = "pass"
@@ -12,11 +12,29 @@ module Datadog
12
12
  HEADER_EVP_SUBDOMAIN = "X-Datadog-EVP-Subdomain"
13
13
  HEADER_CONTAINER_ID = "Datadog-Container-ID"
14
14
 
15
- EVP_PROXY_PATH_PREFIX = "/evp_proxy/v2/"
15
+ EVP_PROXY_V2_PATH_PREFIX = "/evp_proxy/v2/"
16
+ EVP_PROXY_V4_PATH_PREFIX = "/evp_proxy/v4/"
17
+ EVP_PROXY_PATH_PREFIXES = [EVP_PROXY_V4_PATH_PREFIX, EVP_PROXY_V2_PATH_PREFIX].freeze
18
+ EVP_PROXY_COMPRESSION_SUPPORTED = {
19
+ EVP_PROXY_V4_PATH_PREFIX => true,
20
+ EVP_PROXY_V2_PATH_PREFIX => false
21
+ }
22
+
16
23
  TEST_VISIBILITY_INTAKE_HOST_PREFIX = "citestcycle-intake"
17
24
  TEST_VISIBILITY_INTAKE_PATH = "/api/v2/citestcycle"
18
25
 
26
+ DD_API_HOST_PREFIX = "api"
27
+ DD_API_SETTINGS_PATH = "/api/v2/libraries/tests/services/setting"
28
+ DD_API_SETTINGS_TYPE = "ci_app_test_service_libraries_settings"
29
+ DD_API_SETTINGS_RESPONSE_DIG_KEYS = %w[data attributes].freeze
30
+ DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY = "itr_enabled"
31
+ DD_API_SETTINGS_RESPONSE_CODE_COVERAGE_KEY = "code_coverage"
32
+ DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY = "tests_skipping"
33
+ DD_API_SETTINGS_RESPONSE_REQUIRE_GIT_KEY = "require_git"
34
+ DD_API_SETTINGS_RESPONSE_DEFAULT = {DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY => false}.freeze
35
+
19
36
  CONTENT_TYPE_MESSAGEPACK = "application/msgpack"
37
+ CONTENT_TYPE_JSON = "application/json"
20
38
  CONTENT_ENCODING_GZIP = "gzip"
21
39
  end
22
40
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../ext/test"
4
+ require_relative "../ext/transport"
5
+
6
+ module Datadog
7
+ module CI
8
+ module ITR
9
+ # Intelligent test runner implementation
10
+ # Integrates with backend to provide test impact analysis data and
11
+ # skip tests that are not impacted by the changes
12
+ class Runner
13
+ def initialize(
14
+ enabled: false
15
+ )
16
+ @enabled = enabled
17
+ @test_skipping_enabled = false
18
+ @code_coverage_enabled = false
19
+
20
+ Datadog.logger.debug("ITR Runner initialized with enabled: #{@enabled}")
21
+ end
22
+
23
+ def configure(remote_configuration, test_session)
24
+ Datadog.logger.debug("Configuring ITR Runner with remote configuration: #{remote_configuration}")
25
+
26
+ @enabled = convert_to_bool(
27
+ remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY, false)
28
+ )
29
+ @test_skipping_enabled = @enabled && convert_to_bool(
30
+ remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY, false)
31
+ )
32
+ @code_coverage_enabled = @enabled && convert_to_bool(
33
+ remote_configuration.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_CODE_COVERAGE_KEY, false)
34
+ )
35
+
36
+ test_session.set_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_ENABLED, @test_skipping_enabled)
37
+ # currently we set this tag when ITR requires collecting code coverage
38
+ # this will change as soon as we implement total code coverage support in this library
39
+ test_session.set_tag(Ext::Test::TAG_CODE_COVERAGE_ENABLED, @code_coverage_enabled)
40
+
41
+ # we skip tests, not suites
42
+ test_session.set_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_TYPE, Ext::Test::ITR_TEST_SKIPPING_MODE)
43
+
44
+ Datadog.logger.debug("Configured ITR Runner with enabled: #{@enabled}, skipping_tests: #{@test_skipping_enabled}, code_coverage: #{@code_coverage_enabled}")
45
+ end
46
+
47
+ def enabled?
48
+ @enabled
49
+ end
50
+
51
+ def skipping_tests?
52
+ @test_skipping_enabled
53
+ end
54
+
55
+ def code_coverage?
56
+ @code_coverage_enabled
57
+ end
58
+
59
+ private
60
+
61
+ def convert_to_bool(value)
62
+ value.to_s == "true"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -121,6 +121,48 @@ module Datadog
121
121
  tracer_span.set_tags(tags)
122
122
  end
123
123
 
124
+ # Returns the git repository URL extracted from the environment.
125
+ # @return [String] the repository URL.
126
+ def git_repository_url
127
+ tracer_span.get_tag(Ext::Git::TAG_REPOSITORY_URL)
128
+ end
129
+
130
+ # Returns the latest commit SHA extracted from the environment.
131
+ # @return [String] the commit SHA of the last commit.
132
+ def git_commit_sha
133
+ tracer_span.get_tag(Ext::Git::TAG_COMMIT_SHA)
134
+ end
135
+
136
+ # Returns the git branch name extracted from the environment.
137
+ # @return [String] the branch.
138
+ def git_branch
139
+ tracer_span.get_tag(Ext::Git::TAG_BRANCH)
140
+ end
141
+
142
+ # Returns the OS architecture extracted from the environment.
143
+ # @return [String] OS arch.
144
+ def os_architecture
145
+ tracer_span.get_tag(Ext::Test::TAG_OS_ARCHITECTURE)
146
+ end
147
+
148
+ # Returns the OS platform extracted from the environment.
149
+ # @return [String] OS platform.
150
+ def os_platform
151
+ tracer_span.get_tag(Ext::Test::TAG_OS_PLATFORM)
152
+ end
153
+
154
+ # Returns the runtime name extracted from the environment.
155
+ # @return [String] runtime name.
156
+ def runtime_name
157
+ tracer_span.get_tag(Ext::Test::TAG_RUNTIME_NAME)
158
+ end
159
+
160
+ # Returns the runtime version extracted from the environment.
161
+ # @return [String] runtime version.
162
+ def runtime_version
163
+ tracer_span.get_tag(Ext::Test::TAG_RUNTIME_VERSION)
164
+ end
165
+
124
166
  def set_environment_runtime_tags
125
167
  tracer_span.set_tag(Ext::Test::TAG_OS_ARCHITECTURE, ::RbConfig::CONFIG["host_cpu"])
126
168
  tracer_span.set_tag(Ext::Test::TAG_OS_PLATFORM, ::RbConfig::CONFIG["host_os"])
@@ -26,6 +26,14 @@ module Datadog
26
26
  get_tag(Ext::Test::TAG_COMMAND)
27
27
  end
28
28
 
29
+ def skipping_tests?
30
+ get_tag(Ext::Test::TAG_ITR_TEST_SKIPPING_ENABLED) == "true"
31
+ end
32
+
33
+ def code_coverage?
34
+ get_tag(Ext::Test::TAG_CODE_COVERAGE_ENABLED) == "true"
35
+ end
36
+
29
37
  # Return the test session tags that could be inherited by sub-spans
30
38
  # @return [Hash] the tags to be inherited by sub-spans.
31
39
  def inheritable_tags
@@ -21,6 +21,14 @@ module Datadog
21
21
  end
22
22
  end
23
23
 
24
+ def fetch_single_test_suite
25
+ @mutex.synchronize do
26
+ return nil if @test_suites.empty? || @test_suites.size > 1
27
+
28
+ @test_suites.values.first
29
+ end
30
+ end
31
+
24
32
  def fetch_or_activate_test_module(&block)
25
33
  @mutex.synchronize do
26
34
  @test_module ||= block.call
@@ -29,7 +29,7 @@ module Datadog
29
29
  attr_reader :environment_tags, :test_suite_level_visibility_enabled
30
30
 
31
31
  def initialize(
32
- test_suite_level_visibility_enabled: false,
32
+ itr:, remote_settings_api:, test_suite_level_visibility_enabled: false,
33
33
  codeowners: Codeowners::Parser.new(Utils::Git.root).parse
34
34
  )
35
35
  @test_suite_level_visibility_enabled = test_suite_level_visibility_enabled
@@ -37,7 +37,11 @@ module Datadog
37
37
  @environment_tags = Ext::Environment.tags(ENV).freeze
38
38
  @local_context = Context::Local.new
39
39
  @global_context = Context::Global.new
40
+
40
41
  @codeowners = codeowners
42
+
43
+ @itr = itr
44
+ @remote_settings_api = remote_settings_api
41
45
  end
42
46
 
43
47
  def start_test_session(service: nil, tags: {})
@@ -49,7 +53,11 @@ module Datadog
49
53
  )
50
54
  set_session_context(tags, tracer_span)
51
55
 
52
- build_test_session(tracer_span, tags)
56
+ test_session = build_test_session(tracer_span, tags)
57
+
58
+ configure_library(test_session)
59
+
60
+ test_session
53
61
  end
54
62
  end
55
63
 
@@ -175,8 +183,20 @@ module Datadog
175
183
  @global_context.deactivate_test_suite!(test_suite_name)
176
184
  end
177
185
 
186
+ def itr_enabled?
187
+ @itr.enabled?
188
+ end
189
+
178
190
  private
179
191
 
192
+ def configure_library(test_session)
193
+ # this will change when EFD is implemented
194
+ return unless itr_enabled?
195
+
196
+ remote_configuration = @remote_settings_api.fetch_library_settings(test_session)
197
+ @itr.configure(remote_configuration.payload, test_session)
198
+ end
199
+
180
200
  def skip_tracing(block = nil)
181
201
  block.call(nil) if block
182
202
  end
@@ -207,6 +227,11 @@ module Datadog
207
227
  def build_test(tracer_span, tags)
208
228
  test = Test.new(tracer_span)
209
229
  set_initial_tags(test, tags)
230
+
231
+ # sometimes test suite is not being assigned correctly
232
+ # fix it by fetching the one single running test suite from the global context
233
+ fix_test_suite!(test) if test.test_suite_id.nil?
234
+
210
235
  validate_test_suite_level_visibility_correctness(test)
211
236
  set_codeowners(test)
212
237
 
@@ -274,6 +299,24 @@ module Datadog
274
299
  end
275
300
  end
276
301
 
302
+ def fix_test_suite!(test)
303
+ test_suite = @global_context.fetch_single_test_suite
304
+ unless test_suite
305
+ Datadog.logger.debug do
306
+ "Trying to fix test suite for test [#{test.name}] but no single test suite is running."
307
+ end
308
+ return
309
+ end
310
+
311
+ Datadog.logger.debug do
312
+ "For test [#{test.name}]: expected test suite [#{test.test_suite_name}] to be running, " \
313
+ "but it was not found. Fixing it by assigning test suite [#{test_suite.name}] to the test."
314
+ end
315
+
316
+ test.set_tag(Ext::Test::TAG_TEST_SUITE_ID, test_suite.id.to_s)
317
+ test.set_tag(Ext::Test::TAG_SUITE, test_suite.name)
318
+ end
319
+
277
320
  def start_datadog_tracer_span(span_name, span_options, &block)
278
321
  if block
279
322
  Datadog::Tracing.trace(span_name, **span_options) do |tracer_span, trace|
@@ -55,10 +55,6 @@ module Datadog
55
55
 
56
56
  response = send_payload(encoded_payload)
57
57
 
58
- Datadog.logger.debug do
59
- "Received server response: #{response.inspect}"
60
- end
61
-
62
58
  responses << response
63
59
  end
64
60
 
@@ -68,7 +64,7 @@ module Datadog
68
64
  private
69
65
 
70
66
  def send_payload(encoded_payload)
71
- api.request(
67
+ api.citestcycle_request(
72
68
  path: Datadog::CI::Ext::Transport::TEST_VISIBILITY_INTAKE_PATH,
73
69
  payload: encoded_payload
74
70
  )
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative "../../ext/transport"
5
+
6
+ module Datadog
7
+ module CI
8
+ module Transport
9
+ module Api
10
+ class Agentless < Base
11
+ attr_reader :api_key
12
+
13
+ def initialize(api_key:, citestcycle_url:, api_url:)
14
+ @api_key = api_key
15
+ @citestcycle_http = build_http_client(citestcycle_url, compress: true)
16
+ @api_http = build_http_client(api_url, compress: false)
17
+ end
18
+
19
+ def citestcycle_request(path:, payload:, headers: {}, verb: "post")
20
+ super
21
+
22
+ perform_request(@citestcycle_http, path: path, payload: payload, headers: headers, verb: verb)
23
+ end
24
+
25
+ def api_request(path:, payload:, headers: {}, verb: "post")
26
+ super
27
+
28
+ perform_request(@api_http, path: path, payload: payload, headers: headers, verb: verb)
29
+ end
30
+
31
+ private
32
+
33
+ def perform_request(http_client, path:, payload:, headers:, verb:)
34
+ http_client.request(
35
+ path: path,
36
+ payload: payload,
37
+ headers: headers_with_default(headers),
38
+ verb: verb
39
+ )
40
+ end
41
+
42
+ def build_http_client(url, compress:)
43
+ uri = URI.parse(url)
44
+ raise "Invalid agentless mode URL: #{url}" if uri.host.nil?
45
+
46
+ Datadog::CI::Transport::HTTP.new(
47
+ host: uri.host,
48
+ port: uri.port,
49
+ ssl: uri.scheme == "https" || uri.port == 443,
50
+ compress: compress
51
+ )
52
+ end
53
+
54
+ def default_headers
55
+ headers = super
56
+ headers[Ext::Transport::HEADER_DD_API_KEY] = api_key
57
+ headers
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -7,27 +7,23 @@ module Datadog
7
7
  module Transport
8
8
  module Api
9
9
  class Base
10
- attr_reader :http
10
+ def api_request(path:, payload:, headers: {}, verb: "post")
11
+ headers[Ext::Transport::HEADER_CONTENT_TYPE] ||= Ext::Transport::CONTENT_TYPE_JSON
12
+ end
11
13
 
12
- def initialize(http:)
13
- @http = http
14
+ def citestcycle_request(path:, payload:, headers: {}, verb: "post")
15
+ headers[Ext::Transport::HEADER_CONTENT_TYPE] ||= Ext::Transport::CONTENT_TYPE_MESSAGEPACK
14
16
  end
15
17
 
16
- def request(path:, payload:, verb: "post")
17
- http.request(
18
- path: path,
19
- payload: payload,
20
- verb: verb,
21
- headers: headers
22
- )
18
+ def headers_with_default(headers)
19
+ request_headers = default_headers
20
+ request_headers.merge!(headers)
23
21
  end
24
22
 
25
23
  private
26
24
 
27
- def headers
28
- {
29
- Ext::Transport::HEADER_CONTENT_TYPE => Ext::Transport::CONTENT_TYPE_MESSAGEPACK
30
- }
25
+ def default_headers
26
+ {}
31
27
  end
32
28
  end
33
29
  end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "ci_test_cycle"
3
+ require "datadog/core/configuration/agent_settings_resolver"
4
+ require "datadog/core/remote/negotiation"
5
+
6
+ require_relative "agentless"
4
7
  require_relative "evp_proxy"
5
8
  require_relative "../http"
6
9
  require_relative "../../ext/transport"
@@ -10,34 +13,35 @@ module Datadog
10
13
  module Transport
11
14
  module Api
12
15
  module Builder
13
- def self.build_ci_test_cycle_api(settings)
16
+ def self.build_agentless_api(settings)
17
+ return nil if settings.api_key.nil?
18
+
14
19
  dd_site = settings.site || Ext::Transport::DEFAULT_DD_SITE
15
- url = settings.ci.agentless_url ||
20
+
21
+ citestcycle_url = settings.ci.agentless_url ||
16
22
  "https://#{Ext::Transport::TEST_VISIBILITY_INTAKE_HOST_PREFIX}.#{dd_site}:443"
17
23
 
18
- uri = URI.parse(url)
19
- raise "Invalid agentless mode URL: #{url}" if uri.host.nil?
24
+ api_url = settings.ci.agentless_url ||
25
+ "https://#{Ext::Transport::DD_API_HOST_PREFIX}.#{dd_site}:443"
20
26
 
21
- http = Datadog::CI::Transport::HTTP.new(
22
- host: uri.host,
23
- port: uri.port,
24
- ssl: uri.scheme == "https" || uri.port == 443,
25
- compress: true
26
- )
27
-
28
- CiTestCycle.new(api_key: settings.api_key, http: http)
27
+ Agentless.new(api_key: settings.api_key, citestcycle_url: citestcycle_url, api_url: api_url)
29
28
  end
30
29
 
31
- def self.build_evp_proxy_api(agent_settings)
32
- http = Datadog::CI::Transport::HTTP.new(
33
- host: agent_settings.hostname,
34
- port: agent_settings.port,
35
- ssl: agent_settings.ssl,
36
- timeout: agent_settings.timeout_seconds,
37
- compress: false
30
+ def self.build_evp_proxy_api(settings)
31
+ agent_settings = Datadog::Core::Configuration::AgentSettingsResolver.call(settings)
32
+ negotiation = Datadog::Core::Remote::Negotiation.new(
33
+ settings,
34
+ agent_settings,
35
+ suppress_logging: {no_config_endpoint: true}
38
36
  )
39
37
 
40
- EvpProxy.new(http: http)
38
+ evp_proxy_path_prefix = Ext::Transport::EVP_PROXY_PATH_PREFIXES.find do |path_prefix|
39
+ negotiation.endpoint?(path_prefix)
40
+ end
41
+
42
+ return nil if evp_proxy_path_prefix.nil?
43
+
44
+ EvpProxy.new(agent_settings: agent_settings, path_prefix: evp_proxy_path_prefix)
41
45
  end
42
46
  end
43
47
  end
@@ -10,17 +10,48 @@ module Datadog
10
10
  module Transport
11
11
  module Api
12
12
  class EvpProxy < Base
13
- def request(path:, payload:, verb: "post")
14
- path = "#{Ext::Transport::EVP_PROXY_PATH_PREFIX}#{path.sub(/^\//, "")}"
13
+ def initialize(agent_settings:, path_prefix: Ext::Transport::EVP_PROXY_V2_PATH_PREFIX)
14
+ @agent_intake_http = build_http_client(
15
+ agent_settings,
16
+ compress: Ext::Transport::EVP_PROXY_COMPRESSION_SUPPORTED[path_prefix]
17
+ )
18
+
19
+ @agent_api_http = build_http_client(agent_settings, compress: false)
20
+
21
+ path_prefix = "#{path_prefix}/" unless path_prefix.end_with?("/")
22
+ @path_prefix = path_prefix
23
+ end
24
+
25
+ def citestcycle_request(path:, payload:, headers: {}, verb: "post")
26
+ super
27
+
28
+ headers[Ext::Transport::HEADER_EVP_SUBDOMAIN] = Ext::Transport::TEST_VISIBILITY_INTAKE_HOST_PREFIX
29
+
30
+ perform_request(@agent_intake_http, path: path, payload: payload, headers: headers, verb: verb)
31
+ end
32
+
33
+ def api_request(path:, payload:, headers: {}, verb: "post")
34
+ super
35
+
36
+ headers[Ext::Transport::HEADER_EVP_SUBDOMAIN] = Ext::Transport::DD_API_HOST_PREFIX
15
37
 
16
- super(
17
- path: path,
38
+ perform_request(@agent_api_http, path: path, payload: payload, headers: headers, verb: verb)
39
+ end
40
+
41
+ private
42
+
43
+ def perform_request(http_client, path:, payload:, headers:, verb:)
44
+ http_client.request(
45
+ path: path_with_prefix(path),
18
46
  payload: payload,
47
+ headers: headers_with_default(headers),
19
48
  verb: verb
20
49
  )
21
50
  end
22
51
 
23
- private
52
+ def path_with_prefix(path)
53
+ "#{@path_prefix}#{path.sub(/^\//, "")}"
54
+ end
24
55
 
25
56
  def container_id
26
57
  return @container_id if defined?(@container_id)
@@ -28,15 +59,24 @@ module Datadog
28
59
  @container_id = Datadog::Core::Environment::Container.container_id
29
60
  end
30
61
 
31
- def headers
62
+ def default_headers
32
63
  headers = super
33
- headers[Ext::Transport::HEADER_EVP_SUBDOMAIN] = Ext::Transport::TEST_VISIBILITY_INTAKE_HOST_PREFIX
34
64
 
35
65
  c_id = container_id
36
66
  headers[Ext::Transport::HEADER_CONTAINER_ID] = c_id unless c_id.nil?
37
67
 
38
68
  headers
39
69
  end
70
+
71
+ def build_http_client(agent_settings, compress:)
72
+ Datadog::CI::Transport::HTTP.new(
73
+ host: agent_settings.hostname,
74
+ port: agent_settings.port,
75
+ ssl: agent_settings.ssl,
76
+ timeout: agent_settings.timeout_seconds,
77
+ compress: compress
78
+ )
79
+ end
40
80
  end
41
81
  end
42
82
  end
@@ -40,11 +40,17 @@ module Datadog
40
40
  "compression_enabled=#{compress}; path=#{path}; payload_size=#{payload.size}"
41
41
  end
42
42
 
43
- ResponseDecorator.new(
43
+ response = ResponseDecorator.new(
44
44
  adapter.call(
45
45
  build_env(path: path, payload: payload, headers: headers, verb: verb)
46
46
  )
47
47
  )
48
+
49
+ Datadog.logger.debug do
50
+ "Received server response: #{response.inspect}"
51
+ end
52
+
53
+ response
48
54
  end
49
55
 
50
56
  private
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ require "datadog/core/environment/identity"
6
+
7
+ require_relative "../ext/transport"
8
+
9
+ module Datadog
10
+ module CI
11
+ module Transport
12
+ # Datadog API client
13
+ # Calls settings endpoint to fetch library settings for given service and env
14
+ class RemoteSettingsApi
15
+ class Response
16
+ def initialize(http_response)
17
+ @http_response = http_response
18
+ @json = nil
19
+ end
20
+
21
+ def ok?
22
+ resp = @http_response
23
+ !resp.nil? && resp.ok?
24
+ end
25
+
26
+ def payload
27
+ cached = @json
28
+ return cached unless cached.nil?
29
+
30
+ resp = @http_response
31
+ return @json = default_payload if resp.nil? || !resp.ok?
32
+
33
+ begin
34
+ @json = JSON.parse(resp.payload).dig(*Ext::Transport::DD_API_SETTINGS_RESPONSE_DIG_KEYS) ||
35
+ default_payload
36
+ rescue JSON::ParserError => e
37
+ Datadog.logger.error("Failed to parse settings response payload: #{e}. Payload was: #{resp.payload}")
38
+ @json = default_payload
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def default_payload
45
+ Ext::Transport::DD_API_SETTINGS_RESPONSE_DEFAULT
46
+ end
47
+ end
48
+
49
+ def initialize(api: nil, dd_env: nil)
50
+ @api = api
51
+ @dd_env = dd_env
52
+ end
53
+
54
+ def fetch_library_settings(test_session)
55
+ api = @api
56
+ return Response.new(nil) unless api
57
+
58
+ request_payload = payload(test_session)
59
+ Datadog.logger.debug("Fetching library settings with request: #{request_payload}")
60
+
61
+ http_response = api.api_request(
62
+ path: Ext::Transport::DD_API_SETTINGS_PATH,
63
+ payload: request_payload
64
+ )
65
+
66
+ Response.new(http_response)
67
+ end
68
+
69
+ private
70
+
71
+ def payload(test_session)
72
+ {
73
+ "data" => {
74
+ "id" => Datadog::Core::Environment::Identity.id,
75
+ "type" => Ext::Transport::DD_API_SETTINGS_TYPE,
76
+ "attributes" => {
77
+ "service" => test_session.service,
78
+ "env" => @dd_env,
79
+ "repository_url" => test_session.git_repository_url,
80
+ "branch" => test_session.git_branch,
81
+ "sha" => test_session.git_commit_sha,
82
+ "test_level" => Ext::Test::ITR_TEST_SKIPPING_MODE,
83
+ "configurations" => {
84
+ "os.platform" => test_session.os_platform,
85
+ "os.arch" => test_session.os_architecture,
86
+ "runtime.name" => test_session.runtime_name,
87
+ "runtime.version" => test_session.runtime_version
88
+ }
89
+ }
90
+ }
91
+ }.to_json
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -4,8 +4,8 @@ module Datadog
4
4
  module CI
5
5
  module VERSION
6
6
  MAJOR = "0"
7
- MINOR = "7"
8
- PATCH = "0"
7
+ MINOR = "8"
8
+ PATCH = "3"
9
9
  PRE = nil
10
10
  BUILD = nil
11
11
  # PRE and BUILD above are modified for dev gems during gem build GHA workflow
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog-ci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-26 00:00:00.000000000 Z
11
+ date: 2024-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -98,6 +98,7 @@ files:
98
98
  - lib/datadog/ci/ext/settings.rb
99
99
  - lib/datadog/ci/ext/test.rb
100
100
  - lib/datadog/ci/ext/transport.rb
101
+ - lib/datadog/ci/itr/runner.rb
101
102
  - lib/datadog/ci/span.rb
102
103
  - lib/datadog/ci/test.rb
103
104
  - lib/datadog/ci/test_module.rb
@@ -118,16 +119,16 @@ files:
118
119
  - lib/datadog/ci/test_visibility/serializers/test_v1.rb
119
120
  - lib/datadog/ci/test_visibility/serializers/test_v2.rb
120
121
  - lib/datadog/ci/test_visibility/transport.rb
122
+ - lib/datadog/ci/transport/api/agentless.rb
121
123
  - lib/datadog/ci/transport/api/base.rb
122
124
  - lib/datadog/ci/transport/api/builder.rb
123
- - lib/datadog/ci/transport/api/ci_test_cycle.rb
124
125
  - lib/datadog/ci/transport/api/evp_proxy.rb
125
126
  - lib/datadog/ci/transport/gzip.rb
126
127
  - lib/datadog/ci/transport/http.rb
128
+ - lib/datadog/ci/transport/remote_settings_api.rb
127
129
  - lib/datadog/ci/utils/configuration.rb
128
130
  - lib/datadog/ci/utils/git.rb
129
131
  - lib/datadog/ci/utils/test_run.rb
130
- - lib/datadog/ci/utils/url.rb
131
132
  - lib/datadog/ci/version.rb
132
133
  homepage: https://github.com/DataDog/datadog-ci-rb
133
134
  licenses:
@@ -155,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
156
  - !ruby/object:Gem::Version
156
157
  version: 2.0.0
157
158
  requirements: []
158
- rubygems_version: 3.5.3
159
+ rubygems_version: 3.5.6
159
160
  signing_key:
160
161
  specification_version: 4
161
162
  summary: Datadog CI visibility for your ruby application
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "base"
4
- require_relative "../../ext/transport"
5
-
6
- module Datadog
7
- module CI
8
- module Transport
9
- module Api
10
- class CiTestCycle < Base
11
- attr_reader :api_key
12
-
13
- def initialize(api_key:, http:)
14
- @api_key = api_key
15
-
16
- super(http: http)
17
- end
18
-
19
- private
20
-
21
- def headers
22
- headers = super
23
- headers[Ext::Transport::HEADER_DD_API_KEY] = api_key
24
- headers
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Datadog
4
- module CI
5
- module Utils
6
- module Url
7
- def self.filter_sensitive_info(url)
8
- return nil if url.nil?
9
-
10
- url.gsub(%r{((https?|ssh)://)[^/]*@}, '\1')
11
- end
12
- end
13
- end
14
- end
15
- end