datadog-ci 1.19.0 → 1.20.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 +17 -2
- data/README.md +8 -17
- data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +6 -0
- data/lib/datadog/ci/contrib/rspec/documentation_formatter.rb +126 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +18 -0
- data/lib/datadog/ci/contrib/rspec/ext.rb +9 -0
- data/lib/datadog/ci/contrib/rspec/patcher.rb +2 -0
- data/lib/datadog/ci/ext/environment/configuration_discrepancy_checker.rb +91 -0
- data/lib/datadog/ci/ext/environment/extractor.rb +8 -2
- data/lib/datadog/ci/ext/environment/providers/appveyor.rb +8 -0
- data/lib/datadog/ci/ext/environment/providers/azure.rb +8 -0
- data/lib/datadog/ci/ext/environment/providers/base.rb +3 -0
- data/lib/datadog/ci/ext/environment/providers/bitbucket.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/bitrise.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/buddy.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/buildkite.rb +6 -0
- data/lib/datadog/ci/ext/environment/providers/circleci.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/codefresh.rb +8 -0
- data/lib/datadog/ci/ext/environment/providers/drone.rb +83 -0
- data/lib/datadog/ci/ext/environment/providers/github_actions.rb +0 -2
- data/lib/datadog/ci/ext/environment/providers/gitlab.rb +4 -0
- data/lib/datadog/ci/ext/environment/providers/jenkins.rb +8 -0
- data/lib/datadog/ci/ext/environment/providers/teamcity.rb +8 -0
- data/lib/datadog/ci/ext/environment/providers/travis.rb +22 -0
- data/lib/datadog/ci/ext/environment/providers.rb +2 -0
- data/lib/datadog/ci/ext/environment.rb +9 -3
- data/lib/datadog/ci/ext/telemetry.rb +3 -0
- data/lib/datadog/ci/ext/test.rb +6 -0
- data/lib/datadog/ci/remote/library_settings_client.rb +1 -1
- data/lib/datadog/ci/span.rb +12 -0
- data/lib/datadog/ci/test_retries/component.rb +6 -0
- data/lib/datadog/ci/test_retries/driver/base.rb +7 -2
- data/lib/datadog/ci/test_visibility/component.rb +3 -2
- data/lib/datadog/ci/test_visibility/transport.rb +10 -9
- data/lib/datadog/ci/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b04703fefecfa1e090ce2265ed419e4fa41c170a35c897ab2ac900fe9bca467b
|
4
|
+
data.tar.gz: b94de33937e2116579dcaf36c7a7c4f6040597420b27dff1e0f47641f1966be2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bce96aa0950aecccac7b7382c731c62d29035b403231fec3ca7f59bb85768e52e0041cfa709a62ed5054e360979776d37e0a501a587d875f3263e82d455ab14
|
7
|
+
data.tar.gz: 6035f0db0a5a7eb9aae0f51813f330acd3abbe43175000513860abf5ad406f0d76d0aaf8f6e09409f00c251816aae84c7c3757eb56a660fdcefe7e9cbd478d7a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.20.0] - 2025-07-03
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
* Add Datadog output to RSpec documentation formatter ([#355][])
|
8
|
+
* Add Drone CI support and update CI envs handling ([#349][])
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
|
12
|
+
* FIX: send git.tag when requesting library settings if git.branch is not available ([#359][])
|
13
|
+
|
3
14
|
## [1.19.0] - 2025-06-16
|
4
15
|
|
5
16
|
### Changed
|
@@ -463,7 +474,8 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
463
474
|
|
464
475
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
465
476
|
|
466
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.
|
477
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.20.0...main
|
478
|
+
[1.20.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.19.0...v1.20.0
|
467
479
|
[1.19.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.18.0...v1.19.0
|
468
480
|
[1.18.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.17.0...v1.18.0
|
469
481
|
[1.17.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.16.0...v1.17.0
|
@@ -660,4 +672,7 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
660
672
|
[#327]: https://github.com/DataDog/datadog-ci-rb/issues/327
|
661
673
|
[#329]: https://github.com/DataDog/datadog-ci-rb/issues/329
|
662
674
|
[#335]: https://github.com/DataDog/datadog-ci-rb/issues/335
|
663
|
-
[#339]: https://github.com/DataDog/datadog-ci-rb/issues/339
|
675
|
+
[#339]: https://github.com/DataDog/datadog-ci-rb/issues/339
|
676
|
+
[#349]: https://github.com/DataDog/datadog-ci-rb/issues/349
|
677
|
+
[#355]: https://github.com/DataDog/datadog-ci-rb/issues/355
|
678
|
+
[#359]: https://github.com/DataDog/datadog-ci-rb/issues/359
|
data/README.md
CHANGED
@@ -9,34 +9,25 @@ Learn more on our [official website](https://docs.datadoghq.com/tests/) and chec
|
|
9
9
|
## Features
|
10
10
|
|
11
11
|
- [Test Visibility](https://docs.datadoghq.com/tests/) - collect metrics and results for your tests
|
12
|
+
- [Flaky test management](https://docs.datadoghq.com/tests/flaky_management/) - track, triage, and remediate flaky tests across your organization. Quarantine or disable problematic tests to keep known flakes from breaking builds, and create cases and Jira issues to track work toward fixes.
|
13
|
+
- [Auto test retries](https://docs.datadoghq.com/tests/flaky_tests/auto_test_retries/?tab=ruby) - retrying failing tests up to N times to avoid failing your build due to flaky tests
|
14
|
+
- [Early flake detection](https://docs.datadoghq.com/tests/flaky_tests/early_flake_detection/?tab=ruby) - Datadog’s test flakiness solution that identifies flakes early by running newly added tests multiple times
|
12
15
|
- [Test impact analysis](https://docs.datadoghq.com/tests/test_impact_analysis/) - save time by selectively running only tests affected by code changes
|
13
|
-
- [
|
14
|
-
- [
|
15
|
-
- [Early flake detection](https://docs.datadoghq.com/tests/flaky_test_management/early_flake_detection/?tab=ruby) - Datadog’s test flakiness solution that identifies flakes early by running newly added tests multiple times
|
16
|
-
- [Search and manage CI tests](https://docs.datadoghq.com/tests/search/)
|
16
|
+
- [Test Health](https://docs.datadoghq.com/tests/test_health) - The Test Health dashboard provides analytics to help teams manage and optimize their testing in CI. This includes sections showing the current impact of test flakiness and how Test Optimization is mitigating these problems.
|
17
|
+
- [Inspect your tests' logs in Datadog](https://docs.datadoghq.com/tests/correlate_logs_and_tests)
|
17
18
|
- [Enhance developer workflows](https://docs.datadoghq.com/tests/developer_workflows)
|
18
19
|
- [Add custom measures to your tests](https://docs.datadoghq.com/tests/guides/add_custom_measures/?tab=ruby)
|
19
20
|
- [Browser tests integration with Datadog RUM](https://docs.datadoghq.com/tests/browser_tests)
|
20
21
|
|
21
|
-
##
|
22
|
-
|
23
|
-
Add to your Gemfile.
|
22
|
+
## Setup
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
gem "datadog-ci"
|
28
|
-
end
|
29
|
-
```
|
24
|
+
- [Test visibility setup](https://docs.datadoghq.com/tests/setup/ruby/?tab=cloudciprovideragentless)
|
25
|
+
- [Test impact analysis setup](https://docs.datadoghq.com/tests/test_impact_analysis/setup/ruby/?tab=cloudciprovideragentless) (test visibility setup is required before setting up test impact analysis)
|
30
26
|
|
31
27
|
## Upgrade from ddtrace v1.x
|
32
28
|
|
33
29
|
If you used [test visibility for Ruby](https://docs.datadoghq.com/tests/setup/ruby/) with [ddtrace](https://github.com/datadog/dd-trace-rb) gem, check out our [upgrade guide](/docs/UpgradeGuide.md).
|
34
30
|
|
35
|
-
## Setup
|
36
|
-
|
37
|
-
- [Test visibility setup](https://docs.datadoghq.com/tests/setup/ruby/?tab=cloudciprovideragentless)
|
38
|
-
- [Test impact analysis setup](https://docs.datadoghq.com/tests/test_impact_analysis/setup/ruby/?tab=cloudciprovideragentless) (test visibility setup is required before setting up test impact analysis)
|
39
|
-
|
40
31
|
## Contributing
|
41
32
|
|
42
33
|
See [development guide](/docs/DevelopmentGuide.md), [static typing guide](docs/StaticTypingGuide.md) and [contributing guidelines](/CONTRIBUTING.md).
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Datadog
|
2
|
+
module CI
|
3
|
+
module Contrib
|
4
|
+
module RSpec
|
5
|
+
# Instrument RSpec::Core::Formatters::DocumentationFormatter
|
6
|
+
module DocumentationFormatter
|
7
|
+
def self.included(base)
|
8
|
+
base.prepend(InstanceMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
def example_passed(notification)
|
13
|
+
super
|
14
|
+
|
15
|
+
dd_example_finished(notification.example)
|
16
|
+
end
|
17
|
+
|
18
|
+
def example_failed(notification)
|
19
|
+
super
|
20
|
+
|
21
|
+
dd_example_finished(notification.example)
|
22
|
+
end
|
23
|
+
|
24
|
+
def example_pending(notification)
|
25
|
+
super
|
26
|
+
|
27
|
+
dd_example_finished(notification.example)
|
28
|
+
end
|
29
|
+
|
30
|
+
def dump_summary(notification)
|
31
|
+
super
|
32
|
+
|
33
|
+
return unless @dd_flaky_tests || @dd_quarantined_tests || @dd_disabled_tests || @dd_skipped_by_tia_tests
|
34
|
+
|
35
|
+
summary = "\nDatadog Test Optimization Summary:\n"
|
36
|
+
summary << "#{@dd_flaky_tests} flaky detected " if @dd_flaky_tests&.positive?
|
37
|
+
summary << "#{@dd_quarantined_tests} quarantined " if @dd_quarantined_tests&.positive?
|
38
|
+
summary << "#{@dd_disabled_tests} disabled " if @dd_disabled_tests&.positive?
|
39
|
+
summary << "#{@dd_skipped_by_tia_tests} skipped by test impact analysis " if @dd_skipped_by_tia_tests&.positive?
|
40
|
+
summary << "\n"
|
41
|
+
|
42
|
+
output.puts summary
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def dd_example_finished(example)
|
48
|
+
@group_level += 1
|
49
|
+
|
50
|
+
dd_retries_output(example)
|
51
|
+
dd_test_management_output(example)
|
52
|
+
dd_test_impact_analysis_output(example)
|
53
|
+
|
54
|
+
@group_level -= 1
|
55
|
+
end
|
56
|
+
|
57
|
+
def dd_retries_output(example)
|
58
|
+
if !example.metadata[Ext::METADATA_DD_RETRIES] ||
|
59
|
+
!CI::Ext::Test::RetryReason::DATADOG_RETRY_REASONS.include?(
|
60
|
+
example.metadata[Ext::METADATA_DD_RETRY_REASON]
|
61
|
+
)
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
retries_count = example.metadata[Ext::METADATA_DD_RETRIES]
|
66
|
+
|
67
|
+
output.puts(
|
68
|
+
"#{current_indentation}| Retried #{retries_count} times by #{dd_retry_source(example.metadata[Ext::METADATA_DD_RETRY_REASON])}"
|
69
|
+
)
|
70
|
+
results = example.metadata[Ext::METADATA_DD_RETRY_RESULTS]
|
71
|
+
results_output = results.map { |status, count| "#{count} / #{retries_count} #{status}" }.join(", ")
|
72
|
+
output.puts(
|
73
|
+
"#{current_indentation}| Results were: #{results_output}"
|
74
|
+
)
|
75
|
+
|
76
|
+
if results[CI::Ext::Test::Status::FAIL] > 0 && results[CI::Ext::Test::Status::PASS] > 0
|
77
|
+
output.puts(
|
78
|
+
"#{current_indentation}| Flaky test detected"
|
79
|
+
)
|
80
|
+
|
81
|
+
@dd_flaky_tests ||= 0
|
82
|
+
@dd_flaky_tests += 1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def dd_retry_source(reason)
|
87
|
+
case reason
|
88
|
+
when CI::Ext::Test::RetryReason::RETRY_FAILED
|
89
|
+
"Datadog Auto Test Retries"
|
90
|
+
when CI::Ext::Test::RetryReason::RETRY_DETECT_FLAKY
|
91
|
+
"Datadog Early Flake Detection"
|
92
|
+
when CI::Ext::Test::RetryReason::RETRY_FLAKY_FIXED
|
93
|
+
"Datadog Flaky Test Management"
|
94
|
+
else
|
95
|
+
"Datadog Test Optimization"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def dd_test_management_output(example)
|
100
|
+
if example.metadata[Ext::METADATA_DD_QUARANTINED]
|
101
|
+
output.puts("#{current_indentation}| Test was quarantined by Datadog Flaky Test Management")
|
102
|
+
|
103
|
+
@dd_quarantined_tests ||= 0
|
104
|
+
@dd_quarantined_tests += 1
|
105
|
+
end
|
106
|
+
|
107
|
+
if example.metadata[Ext::METADATA_DD_DISABLED]
|
108
|
+
output.puts("#{current_indentation}| Test was disabled by Datadog Flaky Test Management")
|
109
|
+
|
110
|
+
@dd_disabled_tests ||= 0
|
111
|
+
@dd_disabled_tests += 1
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def dd_test_impact_analysis_output(example)
|
116
|
+
if example.metadata[Ext::METADATA_DD_SKIPPED_BY_ITR]
|
117
|
+
@dd_skipped_by_tia_tests ||= 0
|
118
|
+
@dd_skipped_by_tia_tests += 1
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -74,6 +74,24 @@ module Datadog
|
|
74
74
|
exception: execution_result.pending_exception
|
75
75
|
)
|
76
76
|
end
|
77
|
+
|
78
|
+
if datadog_configuration[:datadog_formatter_enabled]
|
79
|
+
if test_span&.is_retry?
|
80
|
+
metadata[Ext::METADATA_DD_RETRIES] ||= 0
|
81
|
+
metadata[Ext::METADATA_DD_RETRY_RESULTS] ||= Hash.new(0)
|
82
|
+
|
83
|
+
metadata[Ext::METADATA_DD_RETRIES] += 1
|
84
|
+
metadata[Ext::METADATA_DD_RETRY_REASON] = test_span&.retry_reason
|
85
|
+
metadata[Ext::METADATA_DD_RETRY_RESULTS][test_span&.status] += 1
|
86
|
+
end
|
87
|
+
|
88
|
+
metadata[Ext::METADATA_DD_QUARANTINED] = true if test_span&.quarantined?
|
89
|
+
metadata[Ext::METADATA_DD_DISABLED] = true if test_span&.disabled?
|
90
|
+
|
91
|
+
if test_span&.skipped_by_test_impact_analysis?
|
92
|
+
metadata[Ext::METADATA_DD_SKIPPED_BY_ITR] = true
|
93
|
+
end
|
94
|
+
end
|
77
95
|
end
|
78
96
|
end
|
79
97
|
|
@@ -11,6 +11,15 @@ module Datadog
|
|
11
11
|
DEFAULT_SERVICE_NAME = "rspec"
|
12
12
|
|
13
13
|
ENV_ENABLED = "DD_TRACE_RSPEC_ENABLED"
|
14
|
+
ENV_DATADOG_FORMATTER_ENABLED = "DD_TRACE_RSPEC_DATADOG_FORMATTER_ENABLED"
|
15
|
+
|
16
|
+
# Metadata keys
|
17
|
+
METADATA_DD_RETRIES = :dd_retries
|
18
|
+
METADATA_DD_RETRY_RESULTS = :dd_retry_results
|
19
|
+
METADATA_DD_RETRY_REASON = :dd_retry_reason
|
20
|
+
METADATA_DD_QUARANTINED = :dd_quarantined
|
21
|
+
METADATA_DD_DISABLED = :dd_disabled
|
22
|
+
METADATA_DD_SKIPPED_BY_ITR = :dd_skipped_by_itr
|
14
23
|
end
|
15
24
|
end
|
16
25
|
end
|
@@ -5,6 +5,7 @@ require_relative "../patcher"
|
|
5
5
|
require_relative "example"
|
6
6
|
require_relative "example_group"
|
7
7
|
require_relative "runner"
|
8
|
+
require_relative "documentation_formatter"
|
8
9
|
|
9
10
|
module Datadog
|
10
11
|
module CI
|
@@ -20,6 +21,7 @@ module Datadog
|
|
20
21
|
::RSpec::Core::Runner.include(Runner)
|
21
22
|
::RSpec::Core::Example.include(Example)
|
22
23
|
::RSpec::Core::ExampleGroup.include(ExampleGroup)
|
24
|
+
::RSpec::Core::Formatters::DocumentationFormatter.include(DocumentationFormatter)
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../git"
|
4
|
+
require_relative "../telemetry"
|
5
|
+
require_relative "../../utils/telemetry"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Ext
|
10
|
+
module Environment
|
11
|
+
class ConfigurationDiscrepancyChecker
|
12
|
+
def initialize(ci_provider_env_tags, local_git_tags, user_provided_tags)
|
13
|
+
@ci_provider_env_tags = ci_provider_env_tags
|
14
|
+
@local_git_tags = local_git_tags
|
15
|
+
@user_provided_tags = user_provided_tags
|
16
|
+
end
|
17
|
+
|
18
|
+
def check_for_discrepancies
|
19
|
+
checks = [
|
20
|
+
{
|
21
|
+
left: normalize_value(@ci_provider_env_tags[Git::TAG_COMMIT_SHA]),
|
22
|
+
right: normalize_value(@local_git_tags[Git::TAG_COMMIT_SHA]),
|
23
|
+
type: "commit_discrepancy",
|
24
|
+
expected: "ci_provider",
|
25
|
+
discrepant: "git_client"
|
26
|
+
},
|
27
|
+
{
|
28
|
+
left: normalize_value(@user_provided_tags[Git::TAG_COMMIT_SHA]),
|
29
|
+
right: normalize_value(@local_git_tags[Git::TAG_COMMIT_SHA]),
|
30
|
+
type: "commit_discrepancy",
|
31
|
+
expected: "user_supplied",
|
32
|
+
discrepant: "git_client"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
left: normalize_value(@user_provided_tags[Git::TAG_COMMIT_SHA]),
|
36
|
+
right: normalize_value(@ci_provider_env_tags[Git::TAG_COMMIT_SHA]),
|
37
|
+
type: "commit_discrepancy",
|
38
|
+
expected: "user_supplied",
|
39
|
+
discrepant: "ci_provider"
|
40
|
+
},
|
41
|
+
{
|
42
|
+
left: normalize_value(@ci_provider_env_tags[Git::TAG_REPOSITORY_URL]),
|
43
|
+
right: normalize_value(@local_git_tags[Git::TAG_REPOSITORY_URL]),
|
44
|
+
type: "repository_discrepancy",
|
45
|
+
expected: "ci_provider",
|
46
|
+
discrepant: "git_client"
|
47
|
+
},
|
48
|
+
{
|
49
|
+
left: normalize_value(@user_provided_tags[Git::TAG_REPOSITORY_URL]),
|
50
|
+
right: normalize_value(@local_git_tags[Git::TAG_REPOSITORY_URL]),
|
51
|
+
type: "repository_discrepancy",
|
52
|
+
expected: "user_supplied",
|
53
|
+
discrepant: "git_client"
|
54
|
+
},
|
55
|
+
{
|
56
|
+
left: normalize_value(@user_provided_tags[Git::TAG_REPOSITORY_URL]),
|
57
|
+
right: normalize_value(@ci_provider_env_tags[Git::TAG_REPOSITORY_URL]),
|
58
|
+
type: "repository_discrepancy",
|
59
|
+
expected: "user_supplied",
|
60
|
+
discrepant: "ci_provider"
|
61
|
+
}
|
62
|
+
]
|
63
|
+
|
64
|
+
git_info_match = true
|
65
|
+
checks.each do |check|
|
66
|
+
if check[:left] && check[:right] && check[:left] != check[:right]
|
67
|
+
Utils::Telemetry.inc(Ext::Telemetry::METRIC_GIT_COMMIT_SHA_DISCREPANCY, 1, {
|
68
|
+
type: check[:type].to_s,
|
69
|
+
expected_provider: check[:expected].to_s,
|
70
|
+
discrepant_provider: check[:discrepant].to_s
|
71
|
+
})
|
72
|
+
git_info_match = false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
Utils::Telemetry.inc(Ext::Telemetry::METRIC_GIT_COMMIT_SHA_MATCH, 1, {
|
77
|
+
matched: git_info_match.to_s
|
78
|
+
})
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def normalize_value(value)
|
84
|
+
return nil if value.nil? || value == ""
|
85
|
+
value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -49,7 +49,9 @@ module Datadog
|
|
49
49
|
Git::TAG_COMMIT_SHA => @provider.git_commit_sha,
|
50
50
|
Git::TAG_PULL_REQUEST_BASE_BRANCH => @provider.git_pull_request_base_branch,
|
51
51
|
Git::TAG_PULL_REQUEST_BASE_BRANCH_SHA => @provider.git_pull_request_base_branch_sha,
|
52
|
-
Git::TAG_COMMIT_HEAD_SHA => @provider.git_commit_head_sha
|
52
|
+
Git::TAG_COMMIT_HEAD_SHA => @provider.git_commit_head_sha,
|
53
|
+
|
54
|
+
Environment::TAG_PR_NUMBER => @provider.pr_number
|
53
55
|
}
|
54
56
|
|
55
57
|
# Normalize Git references and filter sensitive data
|
@@ -57,13 +59,16 @@ module Datadog
|
|
57
59
|
# Expand ~
|
58
60
|
expand_workspace!
|
59
61
|
|
62
|
+
# Convert all tag values to strings
|
63
|
+
@tags.transform_values! { |v| v&.to_s }
|
64
|
+
|
60
65
|
# remove empty tags
|
61
66
|
@tags.reject! do |_, v|
|
62
67
|
# setting type of v here to untyped because steep does not
|
63
68
|
# understand `v.nil? || something`
|
64
69
|
|
65
70
|
# @type var v: untyped
|
66
|
-
v.nil? || v.strip.empty?
|
71
|
+
v.nil? || v.to_s.strip.empty?
|
67
72
|
end
|
68
73
|
|
69
74
|
@tags
|
@@ -80,6 +85,7 @@ module Datadog
|
|
80
85
|
|
81
86
|
@tags[Git::TAG_TAG] = Utils::Git.normalize_ref(@tags[Git::TAG_TAG])
|
82
87
|
@tags[Git::TAG_BRANCH] = Utils::Git.normalize_ref(@tags[Git::TAG_BRANCH])
|
88
|
+
@tags[Git::TAG_PULL_REQUEST_BASE_BRANCH] = Utils::Git.normalize_ref(@tags[Git::TAG_PULL_REQUEST_BASE_BRANCH])
|
83
89
|
@tags[Git::TAG_REPOSITORY_URL] = Datadog::Core::Utils::Url.filter_basic_auth(
|
84
90
|
@tags[Git::TAG_REPOSITORY_URL]
|
85
91
|
)
|
@@ -74,6 +74,14 @@ module Datadog
|
|
74
74
|
env["APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL"]
|
75
75
|
end
|
76
76
|
|
77
|
+
def git_commit_head_sha
|
78
|
+
env["APPVEYOR_PULL_REQUEST_HEAD_COMMIT"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def pr_number
|
82
|
+
env["APPVEYOR_PULL_REQUEST_NUMBER"]
|
83
|
+
end
|
84
|
+
|
77
85
|
def git_commit_message
|
78
86
|
commit_message = env["APPVEYOR_REPO_COMMIT_MESSAGE"]
|
79
87
|
if commit_message
|
@@ -80,6 +80,14 @@ module Datadog
|
|
80
80
|
env["BUILD_SOURCEVERSIONMESSAGE"]
|
81
81
|
end
|
82
82
|
|
83
|
+
def git_pull_request_base_branch
|
84
|
+
env["SYSTEM_PULLREQUEST_TARGETBRANCH"]
|
85
|
+
end
|
86
|
+
|
87
|
+
def pr_number
|
88
|
+
env["SYSTEM_PULLREQUEST_PULLREQUESTNUMBER"]
|
89
|
+
end
|
90
|
+
|
83
91
|
def ci_env_vars
|
84
92
|
{
|
85
93
|
"SYSTEM_TEAMPROJECTID" => env["SYSTEM_TEAMPROJECTID"],
|
@@ -79,6 +79,10 @@ module Datadog
|
|
79
79
|
# For example, a pull request wants to merge the content of a branch into the branch main. In this case, this Env Var’s value is main.
|
80
80
|
env["BITRISEIO_GIT_BRANCH_DEST"]
|
81
81
|
end
|
82
|
+
|
83
|
+
def pr_number
|
84
|
+
env["BITRISE_PULL_REQUEST"]
|
85
|
+
end
|
82
86
|
end
|
83
87
|
end
|
84
88
|
end
|
@@ -89,6 +89,12 @@ module Datadog
|
|
89
89
|
env["BUILDKITE_PULL_REQUEST_BASE_BRANCH"]
|
90
90
|
end
|
91
91
|
|
92
|
+
def pr_number
|
93
|
+
return nil if env["BUILDKITE_PULL_REQUEST"] == "false"
|
94
|
+
|
95
|
+
env["BUILDKITE_PULL_REQUEST"]
|
96
|
+
end
|
97
|
+
|
92
98
|
def ci_env_vars
|
93
99
|
{
|
94
100
|
"BUILDKITE_BUILD_ID" => env["BUILDKITE_BUILD_ID"],
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
require_relative "base"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Ext
|
10
|
+
module Environment
|
11
|
+
module Providers
|
12
|
+
# Drone CI: https://drone.io/
|
13
|
+
# Environment variables docs: https://docs.drone.io/pipeline/environment/reference/
|
14
|
+
class Drone < Base
|
15
|
+
def self.handles?(env)
|
16
|
+
env.key?("DRONE")
|
17
|
+
end
|
18
|
+
|
19
|
+
def provider_name
|
20
|
+
Provider::DRONE
|
21
|
+
end
|
22
|
+
|
23
|
+
def job_name
|
24
|
+
env["DRONE_STEP_NAME"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def pipeline_number
|
28
|
+
env["DRONE_BUILD_NUMBER"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def pipeline_url
|
32
|
+
env["DRONE_BUILD_LINK"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def stage_name
|
36
|
+
env["DRONE_STAGE_NAME"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def workspace_path
|
40
|
+
env["DRONE_WORKSPACE"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def git_repository_url
|
44
|
+
env["DRONE_GIT_HTTP_URL"]
|
45
|
+
end
|
46
|
+
|
47
|
+
def git_commit_sha
|
48
|
+
env["DRONE_COMMIT_SHA"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def git_branch
|
52
|
+
env["DRONE_BRANCH"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def git_tag
|
56
|
+
env["DRONE_TAG"]
|
57
|
+
end
|
58
|
+
|
59
|
+
def git_commit_author_name
|
60
|
+
env["DRONE_COMMIT_AUTHOR_NAME"]
|
61
|
+
end
|
62
|
+
|
63
|
+
def git_commit_author_email
|
64
|
+
env["DRONE_COMMIT_AUTHOR_EMAIL"]
|
65
|
+
end
|
66
|
+
|
67
|
+
def git_commit_message
|
68
|
+
env["DRONE_COMMIT_MESSAGE"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def git_pull_request_base_branch
|
72
|
+
env["DRONE_TARGET_BRANCH"]
|
73
|
+
end
|
74
|
+
|
75
|
+
def pr_number
|
76
|
+
env["DRONE_PULL_REQUEST"]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -61,6 +61,28 @@ module Datadog
|
|
61
61
|
def git_commit_message
|
62
62
|
env["TRAVIS_COMMIT_MESSAGE"]
|
63
63
|
end
|
64
|
+
|
65
|
+
def git_pull_request_base_branch
|
66
|
+
return nil unless pull_request?
|
67
|
+
|
68
|
+
env["TRAVIS_BRANCH"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def git_commit_head_sha
|
72
|
+
return nil unless pull_request?
|
73
|
+
|
74
|
+
env["TRAVIS_PULL_REQUEST_SHA"]
|
75
|
+
end
|
76
|
+
|
77
|
+
def pr_number
|
78
|
+
return nil unless pull_request?
|
79
|
+
|
80
|
+
env["TRAVIS_PULL_REQUEST"]
|
81
|
+
end
|
82
|
+
|
83
|
+
def pull_request?
|
84
|
+
env["TRAVIS_EVENT_TYPE"] == "pull_request"
|
85
|
+
end
|
64
86
|
end
|
65
87
|
end
|
66
88
|
end
|
@@ -10,6 +10,7 @@ require_relative "providers/buddy"
|
|
10
10
|
require_relative "providers/buildkite"
|
11
11
|
require_relative "providers/circleci"
|
12
12
|
require_relative "providers/codefresh"
|
13
|
+
require_relative "providers/drone"
|
13
14
|
require_relative "providers/github_actions"
|
14
15
|
require_relative "providers/gitlab"
|
15
16
|
require_relative "providers/jenkins"
|
@@ -34,6 +35,7 @@ module Datadog
|
|
34
35
|
Providers::Buildkite,
|
35
36
|
Providers::Circleci,
|
36
37
|
Providers::Codefresh,
|
38
|
+
Providers::Drone,
|
37
39
|
Providers::GithubActions,
|
38
40
|
Providers::Gitlab,
|
39
41
|
Providers::Jenkins,
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "datadog/core/telemetry/logging"
|
4
4
|
|
5
5
|
require_relative "git"
|
6
|
+
require_relative "environment/configuration_discrepancy_checker"
|
6
7
|
require_relative "environment/extractor"
|
7
8
|
|
8
9
|
require_relative "../utils/git"
|
@@ -24,6 +25,7 @@ module Datadog
|
|
24
25
|
TAG_NODE_LABELS = "ci.node.labels"
|
25
26
|
TAG_NODE_NAME = "ci.node.name"
|
26
27
|
TAG_CI_ENV_VARS = "_dd.ci.env_vars"
|
28
|
+
TAG_PR_NUMBER = "pr.number"
|
27
29
|
|
28
30
|
module Provider
|
29
31
|
APPVEYOR = "appveyor"
|
@@ -35,6 +37,7 @@ module Datadog
|
|
35
37
|
BUILDKITE = "buildkite"
|
36
38
|
CIRCLECI = "circleci"
|
37
39
|
CODEFRESH = "codefresh"
|
40
|
+
DRONE = "drone"
|
38
41
|
GITHUB = "github"
|
39
42
|
GITLAB = "gitlab"
|
40
43
|
JENKINS = "jenkins"
|
@@ -51,9 +54,8 @@ module Datadog
|
|
51
54
|
tags = Environment::Extractor.new(env).tags
|
52
55
|
|
53
56
|
# If user defined metadata is defined, overwrite
|
54
|
-
|
55
|
-
|
56
|
-
)
|
57
|
+
user_provided_tags = Environment::Extractor.new(env, provider_klass: Providers::UserDefinedTags).tags
|
58
|
+
tags.merge!(user_provided_tags)
|
57
59
|
|
58
60
|
# Fill out tags from local git as fallback
|
59
61
|
local_git_tags = Environment::Extractor.new(env, provider_klass: Providers::LocalGit).tags
|
@@ -61,6 +63,10 @@ module Datadog
|
|
61
63
|
tags[key] ||= value
|
62
64
|
end
|
63
65
|
|
66
|
+
# send some telemetry for the cases where git commit sha is overriden
|
67
|
+
discrepancy_checker = ConfigurationDiscrepancyChecker.new(tags, local_git_tags, user_provided_tags)
|
68
|
+
discrepancy_checker.check_for_discrepancies
|
69
|
+
|
64
70
|
ensure_post_conditions(tags)
|
65
71
|
|
66
72
|
tags
|
@@ -68,6 +68,9 @@ module Datadog
|
|
68
68
|
|
69
69
|
METRIC_TEST_SESSION = "test_session"
|
70
70
|
|
71
|
+
METRIC_GIT_COMMIT_SHA_MATCH = "git.commit_sha_match"
|
72
|
+
METRIC_GIT_COMMIT_SHA_DISCREPANCY = "git.commit_sha_discrepancy"
|
73
|
+
|
71
74
|
TAG_TEST_FRAMEWORK = "test_framework"
|
72
75
|
TAG_EVENT_TYPE = "event_type"
|
73
76
|
TAG_HAS_CODEOWNER = "has_codeowner"
|
data/lib/datadog/ci/ext/test.rb
CHANGED
@@ -159,6 +159,12 @@ module Datadog
|
|
159
159
|
RETRY_FAILED = "auto_test_retries"
|
160
160
|
RETRY_FLAKY_FIXED = "attempt_to_fix"
|
161
161
|
RETRY_EXTERNAL = "external"
|
162
|
+
|
163
|
+
DATADOG_RETRY_REASONS = [
|
164
|
+
RETRY_FAILED,
|
165
|
+
RETRY_DETECT_FLAKY,
|
166
|
+
RETRY_FLAKY_FIXED
|
167
|
+
]
|
162
168
|
end
|
163
169
|
|
164
170
|
# possible reasons why a test was skipped
|
@@ -81,7 +81,7 @@ module Datadog
|
|
81
81
|
"service" => test_session.service,
|
82
82
|
"env" => @dd_env,
|
83
83
|
"repository_url" => test_session.git_repository_url,
|
84
|
-
"branch" => test_session.git_branch,
|
84
|
+
"branch" => test_session.git_branch || test_session.git_tag,
|
85
85
|
"sha" => test_session.git_commit_sha,
|
86
86
|
"test_level" => Ext::Test::ITR_TEST_SKIPPING_MODE,
|
87
87
|
"configurations" => {
|
data/lib/datadog/ci/span.rb
CHANGED
@@ -72,6 +72,12 @@ module Datadog
|
|
72
72
|
tracer_span.get_tag(Ext::Test::TAG_STATUS) == Ext::Test::Status::SKIP
|
73
73
|
end
|
74
74
|
|
75
|
+
# Returns the current status of the span.
|
76
|
+
# @return [String, nil] the status of the span ("pass", "fail", "skip"), or nil if not set
|
77
|
+
def status
|
78
|
+
tracer_span.get_tag(Ext::Test::TAG_STATUS)
|
79
|
+
end
|
80
|
+
|
75
81
|
# Sets the status of the span to "pass".
|
76
82
|
# @return [void]
|
77
83
|
def passed!
|
@@ -165,6 +171,12 @@ module Datadog
|
|
165
171
|
tracer_span.get_tag(Ext::Git::TAG_BRANCH)
|
166
172
|
end
|
167
173
|
|
174
|
+
# Returns the git tag extracted from the environment.
|
175
|
+
# @return [String, nil] the tag or nil if not set.
|
176
|
+
def git_tag
|
177
|
+
tracer_span.get_tag(Ext::Git::TAG_TAG)
|
178
|
+
end
|
179
|
+
|
168
180
|
# Returns the base commit SHA for the pull request, if available.
|
169
181
|
# @return [String, nil] the base commit SHA or nil if not set.
|
170
182
|
def base_commit_sha
|
@@ -86,6 +86,12 @@ module Datadog
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
def record_test_started(test_span)
|
90
|
+
# mark test as retry in the beginning
|
91
|
+
# if this is a first execution, the current_retry_driver is nil and this is noop
|
92
|
+
current_retry_driver&.mark_as_retry(test_span)
|
93
|
+
end
|
94
|
+
|
89
95
|
def record_test_finished(test_span)
|
90
96
|
if current_retry_driver.nil?
|
91
97
|
# we always run test at least once and after the first pass create a correct retry driver
|
@@ -11,17 +11,22 @@ module Datadog
|
|
11
11
|
false
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def mark_as_retry(test_span)
|
15
15
|
test_span&.set_tag(Ext::Test::TAG_IS_RETRY, "true")
|
16
16
|
test_span&.set_tag(Ext::Test::TAG_RETRY_REASON, retry_reason)
|
17
17
|
end
|
18
18
|
|
19
|
+
def record_retry(test_span)
|
20
|
+
end
|
21
|
+
|
19
22
|
# duration in float seconds
|
20
23
|
def record_duration(duration)
|
21
24
|
end
|
22
25
|
|
23
26
|
def retry_reason
|
24
|
-
|
27
|
+
# we set retry reason to be external (ie retried outside of datadog)
|
28
|
+
# by default if we don't know why the test was retried
|
29
|
+
Ext::Test::RetryReason::RETRY_EXTERNAL
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|
@@ -267,6 +267,8 @@ module Datadog
|
|
267
267
|
|
268
268
|
test_optimisation.mark_if_skippable(test)
|
269
269
|
test_optimisation.start_coverage(test)
|
270
|
+
|
271
|
+
test_retries.record_test_started(test)
|
270
272
|
end
|
271
273
|
|
272
274
|
def on_test_session_finished(test_session)
|
@@ -293,9 +295,8 @@ module Datadog
|
|
293
295
|
test_optimisation.stop_coverage(test)
|
294
296
|
test_optimisation.on_test_finished(test, maybe_remote_context)
|
295
297
|
|
296
|
-
Telemetry.event_finished(test)
|
297
|
-
|
298
298
|
test_retries.record_test_finished(test)
|
299
|
+
Telemetry.event_finished(test)
|
299
300
|
end
|
300
301
|
|
301
302
|
def on_after_test_span_finished(tracer_span)
|
@@ -19,10 +19,6 @@ module Datadog
|
|
19
19
|
class Transport < Datadog::CI::Transport::EventPlatformTransport
|
20
20
|
attr_reader :serializers_factory, :dd_env
|
21
21
|
|
22
|
-
def self.log_once
|
23
|
-
@log_once ||= Datadog::Core::Utils::OnlyOnce.new
|
24
|
-
end
|
25
|
-
|
26
22
|
def initialize(
|
27
23
|
api:,
|
28
24
|
dd_env:,
|
@@ -72,12 +68,17 @@ module Datadog
|
|
72
68
|
|
73
69
|
encoded
|
74
70
|
else
|
75
|
-
message = "
|
76
|
-
|
77
|
-
|
71
|
+
message = "Event with type #{serializer.event_type}(name=#{serializer.name}) is invalid: #{serializer.validation_errors}"
|
72
|
+
|
73
|
+
if serializer.event_type == "span"
|
74
|
+
# events of type span are often skipped because of missing resource field
|
75
|
+
# (because they are misconfigured in tests context)
|
76
|
+
Datadog.logger.debug(message)
|
77
|
+
else
|
78
|
+
Datadog.logger.warn(message)
|
79
|
+
CI::Transport::Telemetry.endpoint_payload_dropped(1, endpoint: telemetry_endpoint_tag)
|
78
80
|
|
79
|
-
|
80
|
-
self.class.log_once.run do
|
81
|
+
# for CI events log all events to internal telemetry
|
81
82
|
Core::Telemetry::Logger.error(message)
|
82
83
|
end
|
83
84
|
|
data/lib/datadog/ci/version.rb
CHANGED
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.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/datadog/ci/contrib/parallel_tests/patcher.rb
|
140
140
|
- lib/datadog/ci/contrib/patcher.rb
|
141
141
|
- lib/datadog/ci/contrib/rspec/configuration/settings.rb
|
142
|
+
- lib/datadog/ci/contrib/rspec/documentation_formatter.rb
|
142
143
|
- lib/datadog/ci/contrib/rspec/example.rb
|
143
144
|
- lib/datadog/ci/contrib/rspec/example_group.rb
|
144
145
|
- lib/datadog/ci/contrib/rspec/ext.rb
|
@@ -166,6 +167,7 @@ files:
|
|
166
167
|
- lib/datadog/ci/contrib/simplecov/result_extractor.rb
|
167
168
|
- lib/datadog/ci/ext/app_types.rb
|
168
169
|
- lib/datadog/ci/ext/environment.rb
|
170
|
+
- lib/datadog/ci/ext/environment/configuration_discrepancy_checker.rb
|
169
171
|
- lib/datadog/ci/ext/environment/extractor.rb
|
170
172
|
- lib/datadog/ci/ext/environment/providers.rb
|
171
173
|
- lib/datadog/ci/ext/environment/providers/appveyor.rb
|
@@ -178,6 +180,7 @@ files:
|
|
178
180
|
- lib/datadog/ci/ext/environment/providers/buildkite.rb
|
179
181
|
- lib/datadog/ci/ext/environment/providers/circleci.rb
|
180
182
|
- lib/datadog/ci/ext/environment/providers/codefresh.rb
|
183
|
+
- lib/datadog/ci/ext/environment/providers/drone.rb
|
181
184
|
- lib/datadog/ci/ext/environment/providers/github_actions.rb
|
182
185
|
- lib/datadog/ci/ext/environment/providers/gitlab.rb
|
183
186
|
- lib/datadog/ci/ext/environment/providers/jenkins.rb
|