datadog-ci 1.21.0 → 1.22.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -2
- data/lib/datadog/ci/configuration/components.rb +13 -2
- data/lib/datadog/ci/configuration/settings.rb +11 -0
- data/lib/datadog/ci/contrib/instrumentation.rb +0 -6
- data/lib/datadog/ci/contrib/minitest/helpers.rb +12 -1
- data/lib/datadog/ci/contrib/rspec/integration.rb +11 -5
- data/lib/datadog/ci/contrib/rspec/patcher.rb +7 -1
- data/lib/datadog/ci/ext/environment/extractor.rb +2 -0
- data/lib/datadog/ci/ext/environment/providers/aws_code_pipeline.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/azure.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/base.rb +6 -0
- data/lib/datadog/ci/ext/environment/providers/buildkite.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/circleci.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/github_actions.rb +18 -3
- data/lib/datadog/ci/ext/environment/providers/gitlab.rb +12 -0
- data/lib/datadog/ci/ext/environment.rb +2 -1
- data/lib/datadog/ci/ext/git.rb +1 -0
- data/lib/datadog/ci/ext/settings.rb +3 -0
- data/lib/datadog/ci/ext/telemetry.rb +1 -0
- data/lib/datadog/ci/ext/test.rb +1 -0
- data/lib/datadog/ci/ext/test_discovery.rb +16 -0
- data/lib/datadog/ci/git/base_branch_sha_detector.rb +1 -15
- data/lib/datadog/ci/git/local_repository.rb +41 -3
- data/lib/datadog/ci/remote/component.rb +34 -22
- data/lib/datadog/ci/test.rb +14 -2
- data/lib/datadog/ci/test_discovery/component.rb +131 -0
- data/lib/datadog/ci/test_visibility/component.rb +30 -1
- data/lib/datadog/ci/test_visibility/telemetry.rb +10 -1
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +13 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64b3da927cc62294a16d73045c2585a0d943d81d638b9ac61f95f10b2f69f6b6
|
4
|
+
data.tar.gz: 72451663fb18398c49bfa61ac43b0317e21792853d2681b44e77239e932d1bfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 209a3a9d3c6c6081b864231e0c63742f34c5ba64b51c60e879742410a3da16bac7eefc802dd18a23bed30f9cdc4be0282258d51c28fdac560792a91423acaef7
|
7
|
+
data.tar.gz: 13bb63efb8388ac57a396c299fc5d36f8bda7889914c31cee7eacc409a4bbf9fad70e96e7b01b8ce2cf2139fd467f8f1dda21fe7090e826958440e701abbcfdc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.22.0] - 2025-08-12
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add pr_number extraction to GitHub Actions provider ([#390][])
|
7
|
+
* Add ci.job.id tag to events ([#387][])
|
8
|
+
* Test discovery mode - internal, intended for usage with Datadog test runner ([#378][])
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
* fetch exact head commit instead of unshallowing parent for impacted tests detection ([#393][])
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
* Fix: make test_suite_name parameter optional for Datadog::CI.active_test_suite method ([#396][])
|
15
|
+
* Fix handling of base branch commit SHA for Github Actions and Gitlab ([#394][])
|
16
|
+
* fix Minitest's test suite name when encountering relative source file paths ([#391][])
|
17
|
+
|
18
|
+
## [1.21.1] - 2025-07-22
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
|
22
|
+
* fix: RSpec's DocumentationFormatter might not be present at instrumentation time ([#384][])
|
23
|
+
* fix: do not crash when `Minitest.run` is called in a fork ([#383][])
|
24
|
+
|
3
25
|
## [1.21.0] - 2025-07-14
|
4
26
|
|
5
27
|
### Added
|
@@ -492,7 +514,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
492
514
|
|
493
515
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
494
516
|
|
495
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.
|
517
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.22.0...main
|
518
|
+
[1.22.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.21.1...v1.22.0
|
519
|
+
[1.21.1]: https://github.com/DataDog/datadog-ci-rb/compare/v1.21.0...v1.21.1
|
496
520
|
[1.21.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.20.2...v1.21.0
|
497
521
|
[1.20.2]: https://github.com/DataDog/datadog-ci-rb/compare/v1.20.1...v1.20.2
|
498
522
|
[1.20.1]: https://github.com/DataDog/datadog-ci-rb/compare/v1.20.0...v1.20.1
|
@@ -698,4 +722,13 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
698
722
|
[#355]: https://github.com/DataDog/datadog-ci-rb/issues/355
|
699
723
|
[#359]: https://github.com/DataDog/datadog-ci-rb/issues/359
|
700
724
|
[#366]: https://github.com/DataDog/datadog-ci-rb/issues/366
|
701
|
-
[#370]: https://github.com/DataDog/datadog-ci-rb/issues/370
|
725
|
+
[#370]: https://github.com/DataDog/datadog-ci-rb/issues/370
|
726
|
+
[#378]: https://github.com/DataDog/datadog-ci-rb/issues/378
|
727
|
+
[#383]: https://github.com/DataDog/datadog-ci-rb/issues/383
|
728
|
+
[#384]: https://github.com/DataDog/datadog-ci-rb/issues/384
|
729
|
+
[#387]: https://github.com/DataDog/datadog-ci-rb/issues/387
|
730
|
+
[#390]: https://github.com/DataDog/datadog-ci-rb/issues/390
|
731
|
+
[#391]: https://github.com/DataDog/datadog-ci-rb/issues/391
|
732
|
+
[#393]: https://github.com/DataDog/datadog-ci-rb/issues/393
|
733
|
+
[#394]: https://github.com/DataDog/datadog-ci-rb/issues/394
|
734
|
+
[#396]: https://github.com/DataDog/datadog-ci-rb/issues/396
|
@@ -16,6 +16,7 @@ require_relative "../test_optimisation/component"
|
|
16
16
|
require_relative "../test_optimisation/coverage/transport"
|
17
17
|
require_relative "../test_retries/component"
|
18
18
|
require_relative "../test_retries/null_component"
|
19
|
+
require_relative "../test_discovery/component"
|
19
20
|
require_relative "../test_visibility/component"
|
20
21
|
require_relative "../test_visibility/flush"
|
21
22
|
require_relative "../test_visibility/known_tests"
|
@@ -37,7 +38,7 @@ module Datadog
|
|
37
38
|
# Adds CI behavior to Datadog trace components
|
38
39
|
module Components
|
39
40
|
attr_reader :test_visibility, :test_optimisation, :git_tree_upload_worker, :ci_remote, :test_retries,
|
40
|
-
:test_management, :agentless_logs_submission, :impacted_tests_detection
|
41
|
+
:test_management, :agentless_logs_submission, :impacted_tests_detection, :test_discovery
|
41
42
|
|
42
43
|
def initialize(settings)
|
43
44
|
@test_optimisation = nil
|
@@ -47,6 +48,7 @@ module Datadog
|
|
47
48
|
@test_retries = TestRetries::NullComponent.new
|
48
49
|
@test_management = TestManagement::NullComponent.new
|
49
50
|
@impacted_tests_detection = nil
|
51
|
+
@test_discovery = nil
|
50
52
|
|
51
53
|
# Activate CI mode if enabled
|
52
54
|
if settings.ci.enabled
|
@@ -62,6 +64,7 @@ module Datadog
|
|
62
64
|
@test_visibility&.shutdown!
|
63
65
|
@test_optimisation&.shutdown!
|
64
66
|
@agentless_logs_submission&.shutdown!
|
67
|
+
@test_discovery&.shutdown!
|
65
68
|
@git_tree_upload_worker&.stop
|
66
69
|
end
|
67
70
|
|
@@ -112,9 +115,17 @@ module Datadog
|
|
112
115
|
|
113
116
|
settings.tracing.test_mode.writer_options = trace_writer_options
|
114
117
|
|
118
|
+
# @type ivar @test_discovery: Datadog::CI::TestDiscovery::Component
|
119
|
+
@test_discovery = TestDiscovery::Component.new(
|
120
|
+
enabled: settings.ci.test_discovery_enabled,
|
121
|
+
output_path: settings.ci.test_discovery_output_path
|
122
|
+
)
|
123
|
+
@test_discovery.disable_features_for_test_discovery!(settings)
|
124
|
+
|
115
125
|
@git_tree_upload_worker = build_git_upload_worker(settings, test_visibility_api)
|
116
126
|
@ci_remote = Remote::Component.new(
|
117
|
-
library_settings_client: build_library_settings_client(settings, test_visibility_api)
|
127
|
+
library_settings_client: build_library_settings_client(settings, test_visibility_api),
|
128
|
+
test_discovery_enabled: settings.ci.test_discovery_enabled
|
118
129
|
)
|
119
130
|
@test_retries = TestRetries::Component.new(
|
120
131
|
retry_failed_tests_enabled: settings.ci.retry_failed_tests_enabled,
|
@@ -157,6 +157,17 @@ module Datadog
|
|
157
157
|
o.default false
|
158
158
|
end
|
159
159
|
|
160
|
+
option :test_discovery_enabled do |o|
|
161
|
+
o.type :bool
|
162
|
+
o.env Ext::Settings::ENV_TEST_DISCOVERY_MODE_ENABLED
|
163
|
+
o.default false
|
164
|
+
end
|
165
|
+
|
166
|
+
option :test_discovery_output_path do |o|
|
167
|
+
o.type :string, nilable: true
|
168
|
+
o.env CI::Ext::Settings::ENV_TEST_DISCOVERY_OUTPUT_PATH
|
169
|
+
end
|
170
|
+
|
160
171
|
define_method(:instrument) do |integration_name, options = {}, &block|
|
161
172
|
return unless enabled
|
162
173
|
|
@@ -9,7 +9,6 @@ module Datadog
|
|
9
9
|
class InvalidIntegrationError < StandardError; end
|
10
10
|
|
11
11
|
@registry = {}
|
12
|
-
@auto_instrumented = false
|
13
12
|
|
14
13
|
def self.registry
|
15
14
|
@registry
|
@@ -19,10 +18,6 @@ module Datadog
|
|
19
18
|
@registry[integration_name(integration_class)] = integration_class.new
|
20
19
|
end
|
21
20
|
|
22
|
-
def self.auto_instrumented?
|
23
|
-
@auto_instrumented
|
24
|
-
end
|
25
|
-
|
26
21
|
# Auto instrumentation of all integrations.
|
27
22
|
#
|
28
23
|
# Registers a :script_compiled tracepoint to watch for new Ruby files being loaded.
|
@@ -30,7 +25,6 @@ module Datadog
|
|
30
25
|
# Only the integrations that are available in the environment are checked.
|
31
26
|
def self.auto_instrument
|
32
27
|
Datadog.logger.debug("Auto instrumenting all integrations...")
|
33
|
-
@auto_instrumented = true
|
34
28
|
|
35
29
|
auto_instrumented_integrations = fetch_auto_instrumented_integrations
|
36
30
|
if auto_instrumented_integrations.empty?
|
@@ -38,7 +38,18 @@ module Datadog
|
|
38
38
|
source_location, = klass.instance_method(method_name).source_location
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
# According to https://github.com/DataDog/datadog-ci-rb/issues/386
|
42
|
+
# the source file path coould be relative when using minitest mixins.
|
43
|
+
#
|
44
|
+
# Note that it doesn't break for test suite source location in .start_test_suite method
|
45
|
+
# because it outputs path relative to the repository root.
|
46
|
+
#
|
47
|
+
# For backwards compatibility, we'll continue to use the relative path from the current
|
48
|
+
# working directory for test suite name.
|
49
|
+
source_file_path = Pathname.new(source_location.to_s)
|
50
|
+
if source_file_path.absolute?
|
51
|
+
source_file_path = source_file_path.relative_path_from(Pathname.pwd).to_s
|
52
|
+
end
|
42
53
|
|
43
54
|
"#{klass.name} at #{source_file_path}"
|
44
55
|
end
|
@@ -24,10 +24,7 @@ module Datadog
|
|
24
24
|
!defined?(::RSpec).nil? && !defined?(::RSpec::Core).nil? &&
|
25
25
|
!defined?(::RSpec::Core::Example).nil? &&
|
26
26
|
!defined?(::RSpec::Core::Runner).nil? &&
|
27
|
-
!defined?(::RSpec::Core::ExampleGroup).nil?
|
28
|
-
!defined?(::RSpec::Core::Formatters::DocumentationFormatter).nil? &&
|
29
|
-
!defined?(::RSpec::Core::Formatters::BaseFormatter).nil? &&
|
30
|
-
!defined?(::RSpec::Core::Formatters::BaseTextFormatter).nil?
|
27
|
+
!defined?(::RSpec::Core::ExampleGroup).nil?
|
31
28
|
end
|
32
29
|
|
33
30
|
def compatible?
|
@@ -35,12 +32,21 @@ module Datadog
|
|
35
32
|
end
|
36
33
|
|
37
34
|
def new_configuration
|
38
|
-
Configuration::Settings.new
|
35
|
+
settings = Configuration::Settings.new
|
36
|
+
# if we are running in test discovery mode, we are most likely running in dry run - we need to allow it
|
37
|
+
settings.dry_run_enabled = true if test_discovery_component&.enabled?
|
38
|
+
settings
|
39
39
|
end
|
40
40
|
|
41
41
|
def patcher
|
42
42
|
Patcher
|
43
43
|
end
|
44
|
+
|
45
|
+
def test_discovery_component
|
46
|
+
components = Datadog.send(:components)
|
47
|
+
return nil unless components.respond_to?(:test_discovery)
|
48
|
+
components.test_discovery
|
49
|
+
end
|
44
50
|
end
|
45
51
|
end
|
46
52
|
end
|
@@ -21,7 +21,13 @@ module Datadog
|
|
21
21
|
::RSpec::Core::Runner.include(Runner)
|
22
22
|
::RSpec::Core::Example.include(Example)
|
23
23
|
::RSpec::Core::ExampleGroup.include(ExampleGroup)
|
24
|
-
|
24
|
+
|
25
|
+
# only add DocumentationFormatter's patch if it's loaded at this point
|
26
|
+
if defined?(::RSpec::Core::Formatters::DocumentationFormatter) &&
|
27
|
+
defined?(::RSpec::Core::Formatters::BaseFormatter) &&
|
28
|
+
defined?(::RSpec::Core::Formatters::BaseTextFormatter)
|
29
|
+
::RSpec::Core::Formatters::DocumentationFormatter.include(DocumentationFormatter)
|
30
|
+
end
|
25
31
|
end
|
26
32
|
end
|
27
33
|
end
|
@@ -23,6 +23,7 @@ module Datadog
|
|
23
23
|
return @tags if defined?(@tags)
|
24
24
|
|
25
25
|
@tags = {
|
26
|
+
Environment::TAG_JOB_ID => @provider.job_id,
|
26
27
|
Environment::TAG_JOB_NAME => @provider.job_name,
|
27
28
|
Environment::TAG_JOB_URL => @provider.job_url,
|
28
29
|
Environment::TAG_PIPELINE_ID => @provider.pipeline_id,
|
@@ -51,6 +52,7 @@ module Datadog
|
|
51
52
|
|
52
53
|
Git::TAG_PULL_REQUEST_BASE_BRANCH => @provider.git_pull_request_base_branch,
|
53
54
|
Git::TAG_PULL_REQUEST_BASE_BRANCH_SHA => @provider.git_pull_request_base_branch_sha,
|
55
|
+
Git::TAG_PULL_REQUEST_BASE_BRANCH_HEAD_SHA => @provider.git_pull_request_base_branch_head_sha,
|
54
56
|
Environment::TAG_PR_NUMBER => @provider.pr_number,
|
55
57
|
|
56
58
|
Git::TAG_COMMIT_HEAD_SHA => @provider.git_commit_head_sha,
|
@@ -18,6 +18,9 @@ module Datadog
|
|
18
18
|
@env = env
|
19
19
|
end
|
20
20
|
|
21
|
+
def job_id
|
22
|
+
end
|
23
|
+
|
21
24
|
def job_name
|
22
25
|
end
|
23
26
|
|
@@ -104,6 +107,9 @@ module Datadog
|
|
104
107
|
def git_pull_request_base_branch_sha
|
105
108
|
end
|
106
109
|
|
110
|
+
def git_pull_request_base_branch_head_sha
|
111
|
+
end
|
112
|
+
|
107
113
|
def git_commit_head_sha
|
108
114
|
end
|
109
115
|
|
@@ -31,6 +31,10 @@ module Datadog
|
|
31
31
|
"#{github_server_url}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks"
|
32
32
|
end
|
33
33
|
|
34
|
+
def job_id
|
35
|
+
env["GITHUB_JOB"]
|
36
|
+
end
|
37
|
+
|
34
38
|
def pipeline_id
|
35
39
|
env["GITHUB_RUN_ID"]
|
36
40
|
end
|
@@ -80,7 +84,7 @@ module Datadog
|
|
80
84
|
env["GITHUB_BASE_REF"]
|
81
85
|
end
|
82
86
|
|
83
|
-
def
|
87
|
+
def git_pull_request_base_branch_head_sha
|
84
88
|
return nil if git_pull_request_base_branch.nil?
|
85
89
|
|
86
90
|
event_json = github_event_json
|
@@ -88,8 +92,8 @@ module Datadog
|
|
88
92
|
|
89
93
|
event_json.dig("pull_request", "base", "sha")
|
90
94
|
rescue => e
|
91
|
-
Datadog.logger.error("Failed to extract pull request base branch SHA from GitHub Actions: #{e}")
|
92
|
-
Core::Telemetry::Logger.report(e, description: "Failed to extract pull request base branch SHA from GitHub Actions")
|
95
|
+
Datadog.logger.error("Failed to extract pull request base branch head SHA from GitHub Actions: #{e}")
|
96
|
+
Core::Telemetry::Logger.report(e, description: "Failed to extract pull request base branch head SHA from GitHub Actions")
|
93
97
|
nil
|
94
98
|
end
|
95
99
|
|
@@ -106,6 +110,17 @@ module Datadog
|
|
106
110
|
nil
|
107
111
|
end
|
108
112
|
|
113
|
+
def pr_number
|
114
|
+
event_json = github_event_json
|
115
|
+
return nil if event_json.nil?
|
116
|
+
|
117
|
+
event_json["number"]
|
118
|
+
rescue => e
|
119
|
+
Datadog.logger.error("Failed to extract PR number from GitHub Actions: #{e}")
|
120
|
+
Core::Telemetry::Logger.report(e, description: "Failed to extract PR number from GitHub Actions")
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
|
109
124
|
private
|
110
125
|
|
111
126
|
def github_event_json
|
@@ -18,6 +18,10 @@ module Datadog
|
|
18
18
|
Provider::GITLAB
|
19
19
|
end
|
20
20
|
|
21
|
+
def job_id
|
22
|
+
env["CI_JOB_ID"]
|
23
|
+
end
|
24
|
+
|
21
25
|
def job_name
|
22
26
|
env["CI_JOB_NAME"]
|
23
27
|
end
|
@@ -104,6 +108,14 @@ module Datadog
|
|
104
108
|
env["CI_MERGE_REQUEST_TARGET_BRANCH_NAME"]
|
105
109
|
end
|
106
110
|
|
111
|
+
def git_pull_request_base_branch_sha
|
112
|
+
env["CI_MERGE_REQUEST_DIFF_BASE_SHA"]
|
113
|
+
end
|
114
|
+
|
115
|
+
def git_pull_request_base_branch_head_sha
|
116
|
+
env["CI_MERGE_REQUEST_TARGET_BRANCH_SHA"]
|
117
|
+
end
|
118
|
+
|
107
119
|
def git_commit_head_sha
|
108
120
|
env["CI_MERGE_REQUEST_SOURCE_BRANCH_SHA"]
|
109
121
|
end
|
@@ -13,6 +13,7 @@ module Datadog
|
|
13
13
|
module Ext
|
14
14
|
# Defines constants for CI tags
|
15
15
|
module Environment
|
16
|
+
TAG_JOB_ID = "ci.job.id"
|
16
17
|
TAG_JOB_NAME = "ci.job.name"
|
17
18
|
TAG_JOB_URL = "ci.job.url"
|
18
19
|
TAG_PIPELINE_ID = "ci.pipeline.id"
|
@@ -70,7 +71,7 @@ module Datadog
|
|
70
71
|
# we need to unshallow at least the parent of the current merge commit to be able to extract information
|
71
72
|
# from the real original commit.
|
72
73
|
if tags[Git::TAG_COMMIT_HEAD_SHA]
|
73
|
-
CI::Git::LocalRepository.
|
74
|
+
CI::Git::LocalRepository.fetch_head_commit_sha(tags[Git::TAG_COMMIT_HEAD_SHA]) if CI::Git::LocalRepository.git_shallow_clone?
|
74
75
|
|
75
76
|
env[ENV_SPECIAL_KEY_FOR_GIT_COMMIT_HEAD_SHA] = tags[Git::TAG_COMMIT_HEAD_SHA]
|
76
77
|
end
|
data/lib/datadog/ci/ext/git.rb
CHANGED
@@ -23,6 +23,7 @@ module Datadog
|
|
23
23
|
# additional tags that we use for github actions jobs with "pull_request" target
|
24
24
|
TAG_PULL_REQUEST_BASE_BRANCH = "git.pull_request.base_branch"
|
25
25
|
TAG_PULL_REQUEST_BASE_BRANCH_SHA = "git.pull_request.base_branch_sha"
|
26
|
+
TAG_PULL_REQUEST_BASE_BRANCH_HEAD_SHA = "git.pull_request.base_branch_head_sha"
|
26
27
|
|
27
28
|
TAG_COMMIT_HEAD_SHA = "git.commit.head.sha"
|
28
29
|
TAG_COMMIT_HEAD_MESSAGE = "git.commit.head.message"
|
@@ -26,6 +26,9 @@ module Datadog
|
|
26
26
|
ENV_AGENTLESS_LOGS_SUBMISSION_ENABLED = "DD_AGENTLESS_LOG_SUBMISSION_ENABLED"
|
27
27
|
ENV_AGENTLESS_LOGS_SUBMISSION_URL = "DD_AGENTLESS_LOG_SUBMISSION_URL"
|
28
28
|
ENV_IMPACTED_TESTS_DETECTION_ENABLED = "DD_CIVISIBILITY_IMPACTED_TESTS_DETECTION_ENABLED"
|
29
|
+
ENV_TEST_DISCOVERY_MODE_ENABLED = "DD_TEST_OPTIMIZATION_DISCOVERY_ENABLED"
|
30
|
+
ENV_TEST_DISCOVERY_OUTPUT_PATH = "DD_TEST_OPTIMIZATION_DISCOVERY_FILE"
|
31
|
+
ENV_AUTO_INSTRUMENTATION_PROVIDER = "DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER"
|
29
32
|
|
30
33
|
# Source: https://docs.datadoghq.com/getting_started/site/
|
31
34
|
DD_SITE_ALLOWLIST = %w[
|
data/lib/datadog/ci/ext/test.rb
CHANGED
@@ -171,6 +171,7 @@ module Datadog
|
|
171
171
|
module SkipReason
|
172
172
|
TEST_IMPACT_ANALYSIS = "Skipped by Datadog's Test Impact Analysis"
|
173
173
|
TEST_MANAGEMENT_DISABLED = "Flaky test is disabled by Datadog"
|
174
|
+
TEST_DISCOVERY_MODE = "Skipped by Datadog's Test Discovery Mode"
|
174
175
|
end
|
175
176
|
end
|
176
177
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Ext
|
6
|
+
# Defines constants for test discovery mode
|
7
|
+
module TestDiscovery
|
8
|
+
# Default output path for test discovery mode
|
9
|
+
DEFAULT_OUTPUT_PATH = "./.dd/test_discovery/tests.json"
|
10
|
+
|
11
|
+
# Maximum buffer size before writing to file
|
12
|
+
MAX_BUFFER_SIZE = 10_000
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -10,7 +10,7 @@ module Datadog
|
|
10
10
|
def self.base_branch_sha(base_branch)
|
11
11
|
Datadog.logger.debug { "Base branch: '#{base_branch}'" }
|
12
12
|
|
13
|
-
remote_name = get_remote_name
|
13
|
+
remote_name = LocalRepository.get_remote_name
|
14
14
|
Datadog.logger.debug { "Remote name: '#{remote_name}'" }
|
15
15
|
|
16
16
|
source_branch = get_source_branch
|
@@ -27,20 +27,6 @@ module Datadog
|
|
27
27
|
strategy.call
|
28
28
|
end
|
29
29
|
|
30
|
-
def self.get_remote_name
|
31
|
-
# Try to find remote from upstream tracking
|
32
|
-
upstream = LocalRepository.get_upstream_branch
|
33
|
-
|
34
|
-
if upstream
|
35
|
-
upstream.split("/").first
|
36
|
-
else
|
37
|
-
# Fallback to first remote if no upstream is set
|
38
|
-
first_remote_value = CLI.exec_git_command(["remote"])&.split("\n")&.first
|
39
|
-
Datadog.logger.debug { "First remote value: '#{first_remote_value}'" }
|
40
|
-
first_remote_value || "origin"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
30
|
def self.get_source_branch
|
45
31
|
source_branch = CLI.exec_git_command(["rev-parse", "--abbrev-ref", "HEAD"])
|
46
32
|
if source_branch.nil?
|
@@ -268,7 +268,7 @@ module Datadog
|
|
268
268
|
false
|
269
269
|
end
|
270
270
|
|
271
|
-
def self.git_unshallow
|
271
|
+
def self.git_unshallow
|
272
272
|
Telemetry.git_command(Ext::Telemetry::Command::UNSHALLOW)
|
273
273
|
# @type var res: String?
|
274
274
|
res = nil
|
@@ -289,11 +289,10 @@ module Datadog
|
|
289
289
|
|
290
290
|
res =
|
291
291
|
begin
|
292
|
-
unshallowing_depth = parent_only ? "--deepen=1" : "--shallow-since=\"1 month ago\""
|
293
292
|
# @type var cmd: Array[String]
|
294
293
|
cmd = [
|
295
294
|
"fetch",
|
296
|
-
|
295
|
+
"--shallow-since=\"1 month ago\"",
|
297
296
|
"--update-shallow",
|
298
297
|
"--filter=blob:none",
|
299
298
|
"--recurse-submodules=no",
|
@@ -318,6 +317,32 @@ module Datadog
|
|
318
317
|
res
|
319
318
|
end
|
320
319
|
|
320
|
+
def self.fetch_head_commit_sha(commit_sha)
|
321
|
+
remote = get_remote_name
|
322
|
+
# @type var res: String?
|
323
|
+
res = nil
|
324
|
+
|
325
|
+
duration_ms = Core::Utils::Time.measure(:float_millisecond) do
|
326
|
+
cmd = [
|
327
|
+
"fetch",
|
328
|
+
"--update-shallow",
|
329
|
+
"--filter=blob:none",
|
330
|
+
"--recurse-submodules=no",
|
331
|
+
"--no-write-fetch-head",
|
332
|
+
remote,
|
333
|
+
commit_sha
|
334
|
+
]
|
335
|
+
res = CLI.exec_git_command(cmd)
|
336
|
+
end
|
337
|
+
|
338
|
+
Telemetry.git_command_ms(Ext::Telemetry::Command::FETCH_HEAD_COMMIT_SHA, duration_ms)
|
339
|
+
res
|
340
|
+
rescue => e
|
341
|
+
log_failure(e, "git fetch_head_commit_sha")
|
342
|
+
Telemetry.track_error(e, Ext::Telemetry::Command::FETCH_HEAD_COMMIT_SHA)
|
343
|
+
nil
|
344
|
+
end
|
345
|
+
|
321
346
|
# Returns a Diff object with relative file paths for files that were changed since the given base_commit.
|
322
347
|
# If base_commit is nil, returns nil. On error, returns nil.
|
323
348
|
def self.get_changes_since(base_commit)
|
@@ -369,6 +394,19 @@ module Datadog
|
|
369
394
|
nil
|
370
395
|
end
|
371
396
|
|
397
|
+
def self.get_remote_name
|
398
|
+
upstream = LocalRepository.get_upstream_branch
|
399
|
+
|
400
|
+
if upstream
|
401
|
+
upstream.split("/").first
|
402
|
+
else
|
403
|
+
# Fallback to first remote if no upstream is set
|
404
|
+
first_remote_value = CLI.exec_git_command(["remote"])&.split("\n")&.first
|
405
|
+
Datadog.logger.debug { "First remote value: '#{first_remote_value}'" }
|
406
|
+
first_remote_value || "origin"
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
372
410
|
def self.filter_invalid_commits(commits)
|
373
411
|
commits.filter { |commit| Utils::Git.valid_commit_sha?(commit) }
|
374
412
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "../worker"
|
4
4
|
require_relative "../utils/stateful"
|
5
|
+
require_relative "library_settings"
|
5
6
|
|
6
7
|
module Datadog
|
7
8
|
module CI
|
@@ -13,33 +14,14 @@ module Datadog
|
|
13
14
|
|
14
15
|
FILE_STORAGE_KEY = "remote_component_state"
|
15
16
|
|
16
|
-
def initialize(library_settings_client:)
|
17
|
+
def initialize(library_settings_client:, test_discovery_enabled: false)
|
17
18
|
@library_settings_client = library_settings_client
|
18
|
-
@
|
19
|
+
@test_discovery_enabled = test_discovery_enabled
|
19
20
|
end
|
20
21
|
|
21
22
|
# called on test session start, uses test session info to send configuration request to the backend
|
22
23
|
def configure(test_session)
|
23
|
-
|
24
|
-
unless load_component_state
|
25
|
-
@library_configuration = @library_settings_client.fetch(test_session)
|
26
|
-
# sometimes we can skip code coverage for default branch if there are no changes in the repository
|
27
|
-
# backend needs git metadata uploaded for this test session to check if we can skip code coverage
|
28
|
-
if @library_configuration.require_git?
|
29
|
-
Datadog.logger.debug { "Library configuration endpoint requires git upload to be finished, waiting..." }
|
30
|
-
git_tree_upload_worker.wait_until_done
|
31
|
-
|
32
|
-
Datadog.logger.debug { "Requesting library configuration again..." }
|
33
|
-
@library_configuration = @library_settings_client.fetch(test_session)
|
34
|
-
|
35
|
-
if @library_configuration.require_git?
|
36
|
-
Datadog.logger.debug { "git metadata upload did not complete in time when configuring library" }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Store component state for distributed test runs
|
41
|
-
store_component_state if test_session.distributed
|
42
|
-
end
|
24
|
+
fetch_library_configuration(test_session)
|
43
25
|
|
44
26
|
# configure different components in parallel because they might block on HTTP requests
|
45
27
|
configuration_workers = [
|
@@ -74,6 +56,36 @@ module Datadog
|
|
74
56
|
|
75
57
|
private
|
76
58
|
|
59
|
+
def fetch_library_configuration(test_session)
|
60
|
+
# In test discovery mode, skip backend fetching and use default settings (everything is disabled)
|
61
|
+
return @library_configuration = LibrarySettings.new(nil) if @test_discovery_enabled
|
62
|
+
|
63
|
+
# skip backend request if library configuration was loaded by a different process and stored on disk
|
64
|
+
library_configuration_loaded = load_component_state
|
65
|
+
return @library_configuration if library_configuration_loaded
|
66
|
+
|
67
|
+
@library_configuration = @library_settings_client.fetch(test_session)
|
68
|
+
|
69
|
+
# sometimes we can skip code coverage for default branch if there are no changes in the repository
|
70
|
+
# backend needs git metadata uploaded for this test session to check if we can skip code coverage
|
71
|
+
if @library_configuration.require_git?
|
72
|
+
Datadog.logger.debug { "Library configuration endpoint requires git upload to be finished, waiting..." }
|
73
|
+
git_tree_upload_worker.wait_until_done
|
74
|
+
|
75
|
+
Datadog.logger.debug { "Requesting library configuration again..." }
|
76
|
+
@library_configuration = @library_settings_client.fetch(test_session)
|
77
|
+
|
78
|
+
if @library_configuration.require_git?
|
79
|
+
Datadog.logger.debug { "git metadata upload did not complete in time when configuring library" }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Store component state for distributed test runs
|
84
|
+
store_component_state if test_session.distributed
|
85
|
+
|
86
|
+
@library_configuration
|
87
|
+
end
|
88
|
+
|
77
89
|
def test_management
|
78
90
|
Datadog.send(:components).test_management
|
79
91
|
end
|
data/lib/datadog/ci/test.rb
CHANGED
@@ -216,7 +216,9 @@ module Datadog
|
|
216
216
|
|
217
217
|
# @internal
|
218
218
|
def datadog_skip_reason
|
219
|
-
if
|
219
|
+
if in_test_discovery_mode?
|
220
|
+
Ext::Test::SkipReason::TEST_DISCOVERY_MODE
|
221
|
+
elsif skipped_by_test_impact_analysis?
|
220
222
|
Ext::Test::SkipReason::TEST_IMPACT_ANALYSIS
|
221
223
|
elsif disabled? || quarantined?
|
222
224
|
Ext::Test::SkipReason::TEST_MANAGEMENT_DISABLED
|
@@ -225,7 +227,7 @@ module Datadog
|
|
225
227
|
|
226
228
|
# @internal
|
227
229
|
def should_skip?
|
228
|
-
skipped_by_test_impact_analysis? || (disabled? && !attempt_to_fix?)
|
230
|
+
in_test_discovery_mode? || skipped_by_test_impact_analysis? || (disabled? && !attempt_to_fix?)
|
229
231
|
end
|
230
232
|
|
231
233
|
# @internal
|
@@ -238,6 +240,16 @@ module Datadog
|
|
238
240
|
get_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR) == "true"
|
239
241
|
end
|
240
242
|
|
243
|
+
# @internal
|
244
|
+
def in_test_discovery_mode?
|
245
|
+
!!@in_test_discovery_mode
|
246
|
+
end
|
247
|
+
|
248
|
+
# @internal
|
249
|
+
def mark_test_discovery_mode!
|
250
|
+
@in_test_discovery_mode = true
|
251
|
+
end
|
252
|
+
|
241
253
|
private
|
242
254
|
|
243
255
|
def record_test_result(datadog_status)
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "json"
|
5
|
+
require_relative "../ext/test"
|
6
|
+
require_relative "../ext/test_discovery"
|
7
|
+
|
8
|
+
module Datadog
|
9
|
+
module CI
|
10
|
+
module TestDiscovery
|
11
|
+
# Test discovery mode component that manages test discovery output and lifecycle
|
12
|
+
class Component
|
13
|
+
def initialize(
|
14
|
+
enabled:,
|
15
|
+
output_path:
|
16
|
+
)
|
17
|
+
@enabled = enabled
|
18
|
+
@output_path = output_path
|
19
|
+
|
20
|
+
@buffer = []
|
21
|
+
@buffer_mutex = Mutex.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure(library_settings, test_session)
|
25
|
+
# This method is noop for this component, it is present for compatibility with other components
|
26
|
+
end
|
27
|
+
|
28
|
+
def enabled?
|
29
|
+
@enabled
|
30
|
+
end
|
31
|
+
|
32
|
+
def disable_features_for_test_discovery!(settings)
|
33
|
+
return unless @enabled
|
34
|
+
|
35
|
+
Datadog.logger.debug("ATTENTION! Running in test discovery mode, disabling all features")
|
36
|
+
|
37
|
+
# in test discovery mode don't send anything to Datadog
|
38
|
+
settings.ci.discard_traces = true
|
39
|
+
|
40
|
+
# Disable all feature flags when in test discovery mode
|
41
|
+
settings.telemetry.enabled = false
|
42
|
+
settings.ci.itr_enabled = false
|
43
|
+
settings.ci.git_metadata_upload_enabled = false
|
44
|
+
settings.ci.retry_failed_tests_enabled = false
|
45
|
+
settings.ci.retry_new_tests_enabled = false
|
46
|
+
settings.ci.test_management_enabled = false
|
47
|
+
settings.ci.agentless_logs_submission_enabled = false
|
48
|
+
settings.ci.impacted_tests_detection_enabled = false
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_test_session_start
|
52
|
+
return unless @enabled
|
53
|
+
|
54
|
+
if @output_path.nil? || @output_path&.empty?
|
55
|
+
@output_path = Ext::TestDiscovery::DEFAULT_OUTPUT_PATH
|
56
|
+
end
|
57
|
+
|
58
|
+
# thanks RBS for this weirdness
|
59
|
+
output_path = @output_path
|
60
|
+
return unless output_path
|
61
|
+
|
62
|
+
output_dir = File.dirname(output_path)
|
63
|
+
FileUtils.mkdir_p(output_dir) unless Dir.exist?(output_dir)
|
64
|
+
|
65
|
+
Datadog.logger.debug { "Test discovery output path: #{output_path}" }
|
66
|
+
|
67
|
+
@buffer_mutex.synchronize { @buffer.clear }
|
68
|
+
end
|
69
|
+
|
70
|
+
def on_test_session_end
|
71
|
+
return unless @enabled
|
72
|
+
|
73
|
+
@buffer_mutex.synchronize do
|
74
|
+
flush_buffer_unsafe if @buffer.any?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def on_test_started(test)
|
79
|
+
return unless @enabled
|
80
|
+
|
81
|
+
# Mark test as being in test discovery mode so it will be skipped
|
82
|
+
# even if we are not running in dry run mode.
|
83
|
+
test.mark_test_discovery_mode!
|
84
|
+
|
85
|
+
test_info = {
|
86
|
+
"name" => test.name,
|
87
|
+
"suite" => test.test_suite_name,
|
88
|
+
"sourceFile" => test.source_file,
|
89
|
+
"fqn" => test.datadog_test_id
|
90
|
+
}
|
91
|
+
|
92
|
+
Datadog.logger.debug { "Discovered test: #{test_info}" }
|
93
|
+
|
94
|
+
@buffer_mutex.synchronize do
|
95
|
+
@buffer << test_info
|
96
|
+
|
97
|
+
flush_buffer_unsafe if @buffer.size >= Ext::TestDiscovery::MAX_BUFFER_SIZE
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def shutdown!
|
102
|
+
return unless @enabled
|
103
|
+
|
104
|
+
@buffer_mutex.synchronize do
|
105
|
+
flush_buffer_unsafe if @buffer.any?
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# Unsafe version - caller must hold @buffer_mutex
|
112
|
+
def flush_buffer_unsafe
|
113
|
+
return unless @output_path && @buffer.any?
|
114
|
+
|
115
|
+
output_path = @output_path
|
116
|
+
return unless output_path
|
117
|
+
|
118
|
+
Datadog.logger.debug { "Flushing test discovery buffer with #{@buffer.size} entries to #{output_path}" }
|
119
|
+
|
120
|
+
File.open(output_path, "a") do |file|
|
121
|
+
# disk IO latency is much bigger than time to serialize 10k JSON objects, so we do it in memory and then write to disk
|
122
|
+
json_lines = @buffer.map { |test_info| JSON.generate(test_info) }
|
123
|
+
file.puts(json_lines)
|
124
|
+
end
|
125
|
+
|
126
|
+
@buffer.clear
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -162,6 +162,10 @@ module Datadog
|
|
162
162
|
end
|
163
163
|
|
164
164
|
def active_test_suite(test_suite_name)
|
165
|
+
# when test_suite_name is not provided (from public API most likely)
|
166
|
+
# we return the single active test suite because most of the time there is only one test suite running
|
167
|
+
return single_active_test_suite if test_suite_name.nil?
|
168
|
+
|
165
169
|
# when fetching test_suite to use as test's context, try local context instance first
|
166
170
|
local_test_suite = @context.active_test_suite(test_suite_name)
|
167
171
|
return local_test_suite if local_test_suite
|
@@ -215,7 +219,11 @@ module Datadog
|
|
215
219
|
end
|
216
220
|
|
217
221
|
def client_process?
|
218
|
-
forked
|
222
|
+
# We cannot assume here that every forked process is a client process
|
223
|
+
# there are examples of custom test runners that run tests in forks but don't have a test session
|
224
|
+
# started in the parent process.
|
225
|
+
# So we need to check if the process is forked and if the context service URI is not empty.
|
226
|
+
(forked? && !@context_service_uri.nil? && !@context_service_uri.empty?) || @is_client_process
|
219
227
|
end
|
220
228
|
|
221
229
|
private
|
@@ -234,6 +242,8 @@ module Datadog
|
|
234
242
|
# Signal Remote::Component to configure the library.
|
235
243
|
# Note that it will call this component back (unfortunate circular dependency).
|
236
244
|
remote.configure(test_session)
|
245
|
+
|
246
|
+
test_discovery&.on_test_session_start
|
237
247
|
end
|
238
248
|
|
239
249
|
# intentionally empty
|
@@ -269,6 +279,8 @@ module Datadog
|
|
269
279
|
test_optimisation.start_coverage(test)
|
270
280
|
|
271
281
|
test_retries.record_test_started(test)
|
282
|
+
|
283
|
+
test_discovery&.on_test_started(test)
|
272
284
|
end
|
273
285
|
|
274
286
|
def on_test_session_finished(test_session)
|
@@ -278,6 +290,8 @@ module Datadog
|
|
278
290
|
|
279
291
|
Telemetry.event_finished(test_session)
|
280
292
|
|
293
|
+
test_discovery&.on_test_session_end
|
294
|
+
|
281
295
|
Utils::FileStorage.cleanup
|
282
296
|
end
|
283
297
|
|
@@ -304,6 +318,14 @@ module Datadog
|
|
304
318
|
end
|
305
319
|
|
306
320
|
# HELPERS
|
321
|
+
def single_active_test_suite
|
322
|
+
# when fetching test_suite to use as test's context, try local context instance first
|
323
|
+
local_test_suite = @context.single_active_test_suite
|
324
|
+
return local_test_suite if local_test_suite
|
325
|
+
|
326
|
+
maybe_remote_context.single_active_test_suite
|
327
|
+
end
|
328
|
+
|
307
329
|
def skip_tracing(block = nil)
|
308
330
|
block&.call(nil)
|
309
331
|
end
|
@@ -442,10 +464,17 @@ module Datadog
|
|
442
464
|
Datadog.send(:components).impacted_tests_detection
|
443
465
|
end
|
444
466
|
|
467
|
+
def test_discovery
|
468
|
+
Datadog.send(:components).test_discovery
|
469
|
+
end
|
470
|
+
|
445
471
|
# DISTRIBUTED RUBY CONTEXT
|
446
472
|
def start_drb_service
|
447
473
|
return if @context_service_uri
|
448
474
|
return if client_process?
|
475
|
+
# it doesn't make sense to start DRb in a fork - we are already running in a forked process
|
476
|
+
# and there is no parent process to communicate with
|
477
|
+
return if forked?
|
449
478
|
|
450
479
|
@context_service = DRb.start_service("drbunix:", @context)
|
451
480
|
@context_service_uri = @context_service.uri
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require_relative "../contrib/instrumentation"
|
4
4
|
require_relative "../ext/app_types"
|
5
5
|
require_relative "../ext/environment"
|
6
|
+
require_relative "../ext/settings"
|
6
7
|
require_relative "../ext/telemetry"
|
7
8
|
require_relative "../ext/test"
|
8
9
|
require_relative "../utils/telemetry"
|
@@ -30,11 +31,15 @@ module Datadog
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def self.test_session_started(test_session)
|
34
|
+
auto_injected = !ENV[Ext::Settings::ENV_AUTO_INSTRUMENTATION_PROVIDER].nil?
|
35
|
+
agentless_logs_enabled = !!agentless_logs_component&.enabled
|
36
|
+
|
33
37
|
Utils::Telemetry.inc(
|
34
38
|
Ext::Telemetry::METRIC_TEST_SESSION,
|
35
39
|
1,
|
36
40
|
{
|
37
|
-
Ext::Telemetry::TAG_AUTO_INJECTED =>
|
41
|
+
Ext::Telemetry::TAG_AUTO_INJECTED => auto_injected.to_s,
|
42
|
+
Ext::Telemetry::TAG_AGENTLESS_LOG_SUBMISSION_ENABLED => agentless_logs_enabled.to_s,
|
38
43
|
Ext::Telemetry::TAG_PROVIDER => test_session.ci_provider || Ext::Telemetry::Provider::UNSUPPORTED
|
39
44
|
}
|
40
45
|
)
|
@@ -86,6 +91,10 @@ module Datadog
|
|
86
91
|
browser_driver = span.get_tag(Ext::Test::TAG_BROWSER_DRIVER)
|
87
92
|
tags[Ext::Telemetry::TAG_BROWSER_DRIVER] = browser_driver if browser_driver
|
88
93
|
end
|
94
|
+
|
95
|
+
def self.agentless_logs_component
|
96
|
+
Datadog.send(:components).agentless_logs_submission
|
97
|
+
end
|
89
98
|
end
|
90
99
|
end
|
91
100
|
end
|
data/lib/datadog/ci/version.rb
CHANGED
data/lib/datadog/ci.rb
CHANGED
@@ -187,9 +187,21 @@ module Datadog
|
|
187
187
|
# test_suite.finish
|
188
188
|
# ```
|
189
189
|
#
|
190
|
+
# Most of the time, there is only one active test suite - except when using minitest with parallel test runner,
|
191
|
+
# such as rails built-in test runner.
|
192
|
+
#
|
193
|
+
# When using RSpec or minitest without parallel test runner, there is only one active test suite, so you can use the following code to fetch it:
|
194
|
+
#
|
195
|
+
# ```
|
196
|
+
# test_suite = Datadog::CI.active_test_suite
|
197
|
+
# test_suite.finish
|
198
|
+
# ```
|
199
|
+
#
|
200
|
+
# @param test_suite_name [String?] the name of the test suite to fetch. Optional. When not provided, it assumes that there is a single active test suite and returns it. If there are multiple active test suites and test_suite_name is not provided, it returns nil.
|
201
|
+
#
|
190
202
|
# @return [Datadog::CI::TestSuite] the active test suite
|
191
203
|
# @return [nil] if no test suite with given name is active
|
192
|
-
def active_test_suite(test_suite_name)
|
204
|
+
def active_test_suite(test_suite_name = nil)
|
193
205
|
test_visibility.active_test_suite(test_suite_name)
|
194
206
|
end
|
195
207
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datadog-ci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.22.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
@@ -193,6 +193,7 @@ files:
|
|
193
193
|
- lib/datadog/ci/ext/settings.rb
|
194
194
|
- lib/datadog/ci/ext/telemetry.rb
|
195
195
|
- lib/datadog/ci/ext/test.rb
|
196
|
+
- lib/datadog/ci/ext/test_discovery.rb
|
196
197
|
- lib/datadog/ci/ext/transport.rb
|
197
198
|
- lib/datadog/ci/git/base_branch_sha_detection/base.rb
|
198
199
|
- lib/datadog/ci/git/base_branch_sha_detection/branch_metric.rb
|
@@ -220,6 +221,7 @@ files:
|
|
220
221
|
- lib/datadog/ci/remote/slow_test_retries.rb
|
221
222
|
- lib/datadog/ci/span.rb
|
222
223
|
- lib/datadog/ci/test.rb
|
224
|
+
- lib/datadog/ci/test_discovery/component.rb
|
223
225
|
- lib/datadog/ci/test_management/component.rb
|
224
226
|
- lib/datadog/ci/test_management/null_component.rb
|
225
227
|
- lib/datadog/ci/test_management/tests_properties.rb
|
@@ -316,7 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
316
318
|
- !ruby/object:Gem::Version
|
317
319
|
version: 2.0.0
|
318
320
|
requirements: []
|
319
|
-
rubygems_version: 3.6.
|
321
|
+
rubygems_version: 3.6.9
|
320
322
|
specification_version: 4
|
321
323
|
summary: Datadog Test Optimization for your ruby application
|
322
324
|
test_files: []
|