dri 0.6.1 → 0.8.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/.gitlab-ci.yml +2 -2
- data/Gemfile.lock +1 -1
- data/README.md +3 -1
- data/lib/dri/api_client.rb +85 -23
- data/lib/dri/command.rb +4 -0
- data/lib/dri/commands/analyze/stack_traces.rb +4 -2
- data/lib/dri/commands/fetch/failures.rb +15 -12
- data/lib/dri/commands/fetch/featureflags.rb +2 -2
- data/lib/dri/commands/fetch/pipelines.rb +32 -19
- data/lib/dri/commands/fetch/quarantines.rb +3 -1
- data/lib/dri/commands/fetch/triaged.rb +6 -4
- data/lib/dri/commands/fetch.rb +1 -1
- data/lib/dri/commands/incidents.rb +4 -2
- data/lib/dri/commands/init.rb +3 -0
- data/lib/dri/commands/publish/report.rb +56 -17
- data/lib/dri/commands/publish.rb +3 -0
- data/lib/dri/commands/rm/emoji.rb +17 -7
- data/lib/dri/commands/rm/reports.rb +1 -1
- data/lib/dri/feature_flag_report.rb +2 -2
- data/lib/dri/report.rb +32 -13
- data/lib/dri/utils/constants.rb +36 -3
- data/lib/dri/version.rb +1 -1
- metadata +2 -3
- data/lib/dri/utils/feature_flag_consts.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b4a86b6e658b2426bfce682d92f34f1441a9a1812f0cc805088b8c250991d4d
|
4
|
+
data.tar.gz: 3cf2b62c9aa5b1ef8de5cd51f8fdd927fa5335c9a1299b4947ab162b8afe2526
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d79cdc2db7e1f959fee5b80988516677455a1d18e151a300923b2d19a58f0bb4fc4342db5e3785c34b5ef4475655b37cb10ad8850e488429ab12cfd8ad03fb8
|
7
|
+
data.tar.gz: 5120e934a2e8a45a51b4328bf5a1ae3af1a55b19e42023e538f65c958bfad0a8810f89844b7f2ef40608d0c7233d64f652ba9f101cff37f203a900d940084771
|
data/.gitlab-ci.yml
CHANGED
@@ -15,12 +15,12 @@
|
|
15
15
|
- vendor/bundle
|
16
16
|
policy: pull
|
17
17
|
rules:
|
18
|
-
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
18
|
+
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
19
19
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
20
20
|
|
21
21
|
include:
|
22
22
|
- project: gitlab-org/quality/pipeline-common
|
23
|
-
ref:
|
23
|
+
ref: 1.2.3
|
24
24
|
file:
|
25
25
|
- /ci/gem-release.yml
|
26
26
|
- /ci/ref-update.gitlab-ci.yml
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -146,6 +146,7 @@ $ dri publish report
|
|
146
146
|
```
|
147
147
|
|
148
148
|
Publishes a handover report on the latest triage issue, in the [pipeline-triage](https://gitlab.com/gitlab-org/quality/pipeline-triage) project.
|
149
|
+
The report includes automatically both triaged failures and incidents.
|
149
150
|
|
150
151
|
**Options**
|
151
152
|
|
@@ -155,12 +156,13 @@ $ dri publish report --format=table # formats the report in a table (default)
|
|
155
156
|
$ dri publish report --dry-run # the report is only generated locally
|
156
157
|
$ dri publish report --actions # activate the actions prompt for each failure
|
157
158
|
$ dri publish report --feature-flags # includes a summary of the feature flag changes on each environment
|
159
|
+
$ dri publish report --update # update the report note if has already been posted
|
158
160
|
```
|
159
161
|
|
160
162
|
**Note:** These options above can be combined like:
|
161
163
|
|
162
164
|
```shell
|
163
|
-
$ dri publish report --format=list --dry-run --actions
|
165
|
+
$ dri publish report --format=list --dry-run --actions --update
|
164
166
|
```
|
165
167
|
|
166
168
|
**Actions**
|
data/lib/dri/api_client.rb
CHANGED
@@ -6,16 +6,17 @@ require "tty-config"
|
|
6
6
|
require "cgi"
|
7
7
|
require "gitlab"
|
8
8
|
|
9
|
+
require_relative './utils/constants'
|
10
|
+
|
9
11
|
module Dri
|
10
12
|
TokenNotProvidedError = Class.new(StandardError)
|
11
13
|
class ApiClient # rubocop:disable Metrics/ClassLength
|
14
|
+
include Dri::Utils::Constants::ProjectIDs
|
15
|
+
include Dri::Utils::Constants::Triage::Labels
|
16
|
+
|
12
17
|
API_URL = "https://gitlab.com/api/v4"
|
13
18
|
OPS_API_URL = "https://ops.gitlab.net/api/v4"
|
14
|
-
|
15
|
-
TRIAGE_PROJECT_ID = "15291320"
|
16
|
-
GITLAB_PROJECT_ID = "278964"
|
17
|
-
FEATURE_FLAG_LOG_PROJECT_ID = "15208716"
|
18
|
-
INFRA_TEAM_PROD_PROJECT_ID = "7444821"
|
19
|
+
|
19
20
|
def initialize(config, ops = false)
|
20
21
|
@token = config.read.dig("settings", "token")
|
21
22
|
@ops_token = config.read.dig("settings", "ops_token")
|
@@ -27,14 +28,31 @@ module Dri
|
|
27
28
|
@ops_instance = ops
|
28
29
|
end
|
29
30
|
|
30
|
-
# Fetch triaged failures
|
31
|
+
# Fetch all triaged failures
|
31
32
|
#
|
32
33
|
# @param [String] emoji
|
33
34
|
# @param [String] state
|
34
|
-
# @return [Gitlab::ObjectifiedHash]
|
35
|
-
def
|
35
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
36
|
+
def fetch_all_triaged_failures(emoji:, state:)
|
37
|
+
project_ids = [GITLAB_PROJECT_ID, CUSTOMERSDOT_PROJECT_ID]
|
38
|
+
failures = []
|
39
|
+
|
40
|
+
project_ids.each do |project_id|
|
41
|
+
failures += fetch_triaged_failures(project_id: project_id, emoji: emoji, state: state)
|
42
|
+
end
|
43
|
+
|
44
|
+
failures
|
45
|
+
end
|
46
|
+
|
47
|
+
# Fetch triaged failures for a given project
|
48
|
+
#
|
49
|
+
# @param [Integer] project_id
|
50
|
+
# @param [String] emoji
|
51
|
+
# @param [String] state
|
52
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
53
|
+
def fetch_triaged_failures(project_id:, emoji:, state:)
|
36
54
|
gitlab.issues(
|
37
|
-
|
55
|
+
project_id,
|
38
56
|
order_by: "updated_at",
|
39
57
|
my_reaction_emoji: emoji,
|
40
58
|
scope: "all",
|
@@ -42,12 +60,26 @@ module Dri
|
|
42
60
|
)
|
43
61
|
end
|
44
62
|
|
63
|
+
# Fetch triaged incidents
|
64
|
+
#
|
65
|
+
# @param [String] emoji
|
66
|
+
def fetch_triaged_incidents(emoji:)
|
67
|
+
gitlab.issues(
|
68
|
+
INFRA_TEAM_PROD_PROJECT_ID,
|
69
|
+
order_by: "updated_at",
|
70
|
+
my_reaction_emoji: emoji,
|
71
|
+
state: "all",
|
72
|
+
labels: "incident"
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
45
76
|
# Fetch award emojis
|
46
77
|
#
|
47
78
|
# @param [Integer] issue_iid
|
79
|
+
# @param [Integer] project_id
|
48
80
|
# @return [Array<Gitlab::ObjectifiedHash>]
|
49
|
-
def fetch_awarded_emojis(issue_iid)
|
50
|
-
gitlab.award_emojis(
|
81
|
+
def fetch_awarded_emojis(issue_iid, project_id:)
|
82
|
+
gitlab.award_emojis(project_id, issue_iid, "issue")
|
51
83
|
end
|
52
84
|
|
53
85
|
# Fetch failing testcases
|
@@ -61,14 +93,14 @@ module Dri
|
|
61
93
|
labels: "#{pipeline}::failed",
|
62
94
|
state: state,
|
63
95
|
scope: "all",
|
64
|
-
"not[labels]":
|
96
|
+
"not[labels]": QUARANTINE
|
65
97
|
).auto_paginate
|
66
98
|
end
|
67
99
|
|
68
100
|
# Fetch issues related to failing test cases
|
69
101
|
#
|
70
102
|
# @return [Array<Gitlab::ObjectifiedHash>]
|
71
|
-
def fetch_test_failure_issues(labels:
|
103
|
+
def fetch_test_failure_issues(labels: FAILURE_NEW)
|
72
104
|
gitlab.issues(
|
73
105
|
GITLAB_PROJECT_ID,
|
74
106
|
labels: labels,
|
@@ -79,10 +111,11 @@ module Dri
|
|
79
111
|
|
80
112
|
# Fetch related issue mrs
|
81
113
|
#
|
114
|
+
# @param [Integer] project_id
|
82
115
|
# @param [Integer] issue_iid
|
83
116
|
# @return [Array<Gitlab::ObjectifiedHash>]
|
84
|
-
def fetch_related_mrs(issue_iid)
|
85
|
-
gitlab.related_issue_merge_requests(
|
117
|
+
def fetch_related_mrs(project_id, issue_iid)
|
118
|
+
gitlab.related_issue_merge_requests(project_id, issue_iid)
|
86
119
|
end
|
87
120
|
|
88
121
|
# Fetch MRs
|
@@ -115,15 +148,42 @@ module Dri
|
|
115
148
|
gitlab.create_issue_note(TRIAGE_PROJECT_ID, iid, body)
|
116
149
|
end
|
117
150
|
|
118
|
-
#
|
151
|
+
# Update triage report note
|
152
|
+
#
|
153
|
+
# @param [Integer] iid
|
154
|
+
# @param [Integer] note_id
|
155
|
+
# @param [String] body
|
156
|
+
# @return [Gitlab::ObjectifiedHash]
|
157
|
+
def update_triage_report_note(iid:, note_id:, body:)
|
158
|
+
gitlab.edit_issue_note(TRIAGE_PROJECT_ID, iid, note_id, body)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Fetch all new failures
|
119
162
|
#
|
120
163
|
# @param [String] date
|
121
164
|
# @param [String] state
|
122
165
|
# @return [Array<Gitlab::ObjectifiedHash>]
|
123
|
-
def
|
166
|
+
def fetch_all_new_failures(date:, state:)
|
167
|
+
project_ids = [GITLAB_PROJECT_ID, CUSTOMERSDOT_PROJECT_ID]
|
168
|
+
failures = []
|
169
|
+
|
170
|
+
project_ids.each do |project_id|
|
171
|
+
failures += fetch_new_failures(project_id: project_id, date: date, state: state)
|
172
|
+
end
|
173
|
+
|
174
|
+
failures
|
175
|
+
end
|
176
|
+
|
177
|
+
# Fetch new failures for a given project
|
178
|
+
#
|
179
|
+
# @param [Integer] project_id
|
180
|
+
# @param [String] date
|
181
|
+
# @param [String] state
|
182
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
183
|
+
def fetch_new_failures(project_id:, date:, state:)
|
124
184
|
gitlab.issues(
|
125
|
-
|
126
|
-
labels:
|
185
|
+
project_id,
|
186
|
+
labels: FAILURE_NEW,
|
127
187
|
order_by: "updated_at",
|
128
188
|
state: state,
|
129
189
|
scope: "all",
|
@@ -134,20 +194,22 @@ module Dri
|
|
134
194
|
|
135
195
|
# Fetch failure notes
|
136
196
|
#
|
197
|
+
# @param [Integer] project_id
|
137
198
|
# @param [Integer] issue_iid
|
138
199
|
# @return [Array<Gitlab::ObjectifiedHash>]
|
139
|
-
def fetch_failure_notes(issue_iid)
|
140
|
-
gitlab.issue_notes(
|
200
|
+
def fetch_failure_notes(project_id, issue_iid)
|
201
|
+
gitlab.issue_notes(project_id, issue_iid, per_page: 100).auto_paginate
|
141
202
|
end
|
142
203
|
|
143
204
|
# Delete award emoji
|
144
205
|
#
|
145
206
|
# @param [Integer] issue_iid
|
146
207
|
# @param [Integer] emoji_id
|
208
|
+
# @param [Integer] project_id
|
147
209
|
# @return [Gitlab::ObjectifiedHash]
|
148
|
-
def delete_award_emoji(issue_iid, emoji_id)
|
210
|
+
def delete_award_emoji(issue_iid, emoji_id:, project_id: GITLAB_PROJECT_ID)
|
149
211
|
gitlab.delete_award_emoji(
|
150
|
-
|
212
|
+
project_id,
|
151
213
|
issue_iid,
|
152
214
|
"issue",
|
153
215
|
emoji_id
|
data/lib/dri/command.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../../command'
|
4
4
|
require_relative '../../utils/table'
|
5
|
+
require_relative '../../utils/constants'
|
5
6
|
require 'amatch'
|
6
7
|
require 'fileutils'
|
7
8
|
|
@@ -11,10 +12,11 @@ module Dri
|
|
11
12
|
class StackTraces < Dri::Command
|
12
13
|
include Amatch
|
13
14
|
include Dri::Utils::Table
|
15
|
+
include Dri::Utils::Constants::Triage::Labels
|
14
16
|
|
15
17
|
def initialize(options)
|
16
18
|
@options = options
|
17
|
-
@labels = options[:labels] ||
|
19
|
+
@labels = options[:labels] || FAILURE_NEW
|
18
20
|
@similarity_score_threshold = options[:similarity_score_threshold] || 0.9
|
19
21
|
end
|
20
22
|
|
@@ -29,7 +31,7 @@ module Dri
|
|
29
31
|
logger.info "#{Time.now.utc} API response completed"
|
30
32
|
|
31
33
|
if response.empty?
|
32
|
-
logger.info
|
34
|
+
logger.info "There are no #{FAILURE_NEW} issues identified!"
|
33
35
|
exit 0
|
34
36
|
end
|
35
37
|
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
require_relative '../../command'
|
4
4
|
require_relative '../../utils/table'
|
5
|
+
require_relative '../../utils/constants'
|
5
6
|
|
6
7
|
module Dri
|
7
8
|
module Commands
|
8
9
|
class Fetch
|
9
10
|
class Failures < Dri::Command
|
10
11
|
include Dri::Utils::Table
|
12
|
+
include Dri::Utils::Constants::Triage::Labels
|
11
13
|
using Refinements
|
12
14
|
|
13
15
|
SORT_BY_OPTIONS = {
|
@@ -34,33 +36,34 @@ module Dri
|
|
34
36
|
author = add_color('Author', :bright_yellow)
|
35
37
|
url = add_color('URL', :bright_yellow)
|
36
38
|
|
37
|
-
|
39
|
+
sorted_failures = []
|
38
40
|
labels = [title, triaged, environment, author, url]
|
39
41
|
triaged_counter = 0
|
40
42
|
|
41
43
|
logger.info "Fetching today's failures..."
|
42
44
|
|
43
45
|
spinner.run do # rubocop:disable Metrics/BlockLength
|
44
|
-
|
46
|
+
failures = api_client.fetch_all_new_failures(date: @today_iso_format, state: 'opened')
|
45
47
|
|
46
|
-
if
|
48
|
+
if failures.empty?
|
47
49
|
logger.info 'Life is great, there are no new failures today!'
|
48
50
|
exit 0
|
49
51
|
end
|
50
52
|
|
51
|
-
|
53
|
+
failures.each do |failure|
|
54
|
+
project_id = failure.project_id
|
52
55
|
title = failure.title.truncate(60)
|
53
56
|
author = failure.to_h.dig('author', 'username')
|
54
57
|
url = failure.web_url
|
55
58
|
triaged = add_color('x', :red)
|
56
|
-
envs = failure.labels.select { |l| l.include?(
|
59
|
+
envs = failure.labels.select { |l| l.include?(FOUND) }.map do |l|
|
57
60
|
env = l.split(':').last.gsub('.gitlab.com', '')
|
58
61
|
|
59
62
|
env == 'gitlab.com' ? 'production' : env
|
60
63
|
end
|
61
64
|
urgent = urgent_environments.all? { |env| envs.include?(env) }
|
62
65
|
|
63
|
-
emoji_awards = api_client.fetch_awarded_emojis(failure.iid).find do |e|
|
66
|
+
emoji_awards = api_client.fetch_awarded_emojis(failure.iid, project_id: project_id).find do |e|
|
64
67
|
e.name == emoji && e.to_h.dig('user', 'username') == username
|
65
68
|
end
|
66
69
|
|
@@ -70,26 +73,26 @@ module Dri
|
|
70
73
|
end
|
71
74
|
|
72
75
|
if @options[:urgent]
|
73
|
-
|
76
|
+
sorted_failures << [title, triaged, envs.first, author, url] if urgent
|
74
77
|
else
|
75
|
-
|
78
|
+
sorted_failures << [title, triaged, envs.first, author, url]
|
76
79
|
end
|
77
80
|
end
|
78
81
|
|
79
|
-
|
82
|
+
sorted_failures.sort_by! { |failure| failure[SORT_BY_OPTIONS[@options[:sort_by]&.to_sym || :environment]] }
|
80
83
|
end
|
81
84
|
|
82
85
|
msg = if @options[:urgent]
|
83
86
|
<<~MSG
|
84
|
-
Found: #{
|
87
|
+
Found: #{sorted_failures.size} urgent failures, occurring in both canary.gitlab.com and canary.staging.gitlab.com.
|
85
88
|
MSG
|
86
89
|
else
|
87
90
|
<<~MSG
|
88
|
-
Found: #{
|
91
|
+
Found: #{sorted_failures.size} failures, of these #{triaged_counter} have been triaged with a #{emoji}.
|
89
92
|
MSG
|
90
93
|
end
|
91
94
|
|
92
|
-
print_table(labels,
|
95
|
+
print_table(labels, sorted_failures, alignments: [:left, :center, :center, :left])
|
93
96
|
output.puts(msg)
|
94
97
|
end
|
95
98
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../../command'
|
4
4
|
require_relative '../../utils/table'
|
5
|
-
require_relative '../../utils/
|
5
|
+
require_relative '../../utils/constants'
|
6
6
|
require_relative '../../feature_flag_report'
|
7
7
|
|
8
8
|
module Dri
|
@@ -10,7 +10,7 @@ module Dri
|
|
10
10
|
class Fetch
|
11
11
|
class FeatureFlags < Dri::Command
|
12
12
|
include Dri::Utils::Table
|
13
|
-
include Dri::Utils::
|
13
|
+
include Dri::Utils::Constants::FeatureFlag
|
14
14
|
|
15
15
|
def initialize(options)
|
16
16
|
@options = options
|
@@ -10,6 +10,7 @@ module Dri
|
|
10
10
|
class Fetch
|
11
11
|
class Pipelines < Dri::Command # rubocop:disable Metrics/ClassLength
|
12
12
|
include Dri::Utils::Table
|
13
|
+
include Dri::Utils::Constants
|
13
14
|
using Refinements
|
14
15
|
|
15
16
|
NUM_OF_TESTS_LIVE_ENV = 1000
|
@@ -27,7 +28,7 @@ module Dri
|
|
27
28
|
table_labels = define_table_labels
|
28
29
|
|
29
30
|
spinner.run do
|
30
|
-
|
31
|
+
PIPELINE_ENVIRONMENTS.each do |environment, details|
|
31
32
|
logger.info "Fetching last executed #{environment} pipeline"
|
32
33
|
pipelines << fetch_pipeline(pipeline_name: environment.to_s, details: details)
|
33
34
|
logger.info "Fetching complete for #{environment} ✓"
|
@@ -61,7 +62,7 @@ module Dri
|
|
61
62
|
bridges = api_client.pipeline_bridges(project_id, pipeline_id)
|
62
63
|
return if bridges.empty? # If downstream pipeline doesn't exist, which triggers the QA tests, return
|
63
64
|
|
64
|
-
bridges.
|
65
|
+
bridges.find { |it| it.name == "e2e:package-and-test" }&.downstream_pipeline
|
65
66
|
end
|
66
67
|
|
67
68
|
# Get jobs from a pipeline
|
@@ -136,6 +137,14 @@ module Dri
|
|
136
137
|
pipeline_id: pipeline.id, ops: ops)
|
137
138
|
end
|
138
139
|
|
140
|
+
# Master pipeline run
|
141
|
+
#
|
142
|
+
# @param [String] pipeline_name
|
143
|
+
# @return [Boolean]
|
144
|
+
def master?(pipeline_name)
|
145
|
+
pipeline_name == "master"
|
146
|
+
end
|
147
|
+
|
139
148
|
# Constructs allure report url for each pipeline
|
140
149
|
# @param [String] pipeline_name
|
141
150
|
# @param [Integer] pipeline_id
|
@@ -151,7 +160,7 @@ module Dri
|
|
151
160
|
def allure_bucket_name(pipeline_name, sanity)
|
152
161
|
case pipeline_name
|
153
162
|
when "master"
|
154
|
-
"package-and-
|
163
|
+
"e2e-package-and-test"
|
155
164
|
when "nightly"
|
156
165
|
pipeline_name
|
157
166
|
when "pre_prod"
|
@@ -182,16 +191,19 @@ module Dri
|
|
182
191
|
url.include?("ops.gitlab.net")
|
183
192
|
end
|
184
193
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
194
|
+
# Slack notification job name
|
195
|
+
#
|
196
|
+
# @param [Boolean] ops
|
197
|
+
# @return [String]
|
198
|
+
def notify_job_name(ops)
|
199
|
+
ops ? "notify-slack-qa-fail" : "notify-slack-fail"
|
189
200
|
end
|
190
201
|
|
191
202
|
# Returns child pipeline if it is master pipeline
|
203
|
+
# @param [String] pipeline_name
|
192
204
|
# @param [Gitlab::ObjectifiedHash] pipeline
|
193
|
-
def pipeline_with_qa_tests(pipeline)
|
194
|
-
if
|
205
|
+
def pipeline_with_qa_tests(pipeline_name, pipeline)
|
206
|
+
if master?(pipeline_name)
|
195
207
|
bridge_pipeline(pipeline.project_id, pipeline.id)
|
196
208
|
else
|
197
209
|
pipeline
|
@@ -202,9 +214,13 @@ module Dri
|
|
202
214
|
# @param [Hash] details
|
203
215
|
# @param [Boolean] ops
|
204
216
|
def options(details, ops)
|
205
|
-
options = {
|
206
|
-
|
207
|
-
|
217
|
+
options = {
|
218
|
+
order_by: "updated_at",
|
219
|
+
scope: "finished",
|
220
|
+
ref: "master",
|
221
|
+
updated_after: past_timestamp(details[:search_hours_ago])
|
222
|
+
}
|
223
|
+
options.merge(username: "gitlab-bot") if ops || master?(details[:name])
|
208
224
|
options
|
209
225
|
end
|
210
226
|
|
@@ -218,7 +234,7 @@ module Dri
|
|
218
234
|
# @param [Hash] details Pipeline environment details
|
219
235
|
# @return [Array] Array of last executed pipeline details
|
220
236
|
# rubocop:disable Metrics/PerceivedComplexity
|
221
|
-
def fetch_pipeline(pipeline_name:, details:) # rubocop:disable Metrics/CyclomaticComplexity
|
237
|
+
def fetch_pipeline(pipeline_name:, details:) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
222
238
|
ops = ops_pipeline?(details[:url])
|
223
239
|
options = options(details, ops)
|
224
240
|
# instance is ops.gitlab.net or gitlab.com
|
@@ -228,18 +244,15 @@ module Dri
|
|
228
244
|
|
229
245
|
# Return empty data to the table if no matching pipelines were found from the query
|
230
246
|
response.each do |pipeline|
|
231
|
-
pipeline_to_scan = pipeline_with_qa_tests(pipeline) # Fetch child pipeline if it is master
|
247
|
+
pipeline_to_scan = pipeline_with_qa_tests(pipeline_name, pipeline) # Fetch child pipeline if it is master
|
232
248
|
next if pipeline_to_scan.nil?
|
233
249
|
|
234
250
|
pipeline_jobs = jobs(project_id: pipeline.project_id, pipeline_id: pipeline_to_scan.id, ops: ops)
|
235
|
-
next unless contains_job?(pipeline_jobs, job_name:
|
251
|
+
next unless master?(pipeline_name) || contains_job?(pipeline_jobs, job_name: notify_job_name(ops))
|
236
252
|
|
237
253
|
# Need to know if it is a sanity or a full run to construct allure report url
|
238
|
-
sanity = sanity?(pipeline_jobs: pipeline_jobs, pipeline: pipeline_to_scan,
|
239
|
-
ops: ops)
|
240
|
-
|
254
|
+
sanity = sanity?(pipeline_jobs: pipeline_jobs, pipeline: pipeline_to_scan, ops: ops)
|
241
255
|
next if sanity.nil? # To filter out some "clean up" pipelines present in live environments
|
242
|
-
|
243
256
|
next if sanity && @options[:full_runs_only] # Filter out sanity runs if --full-runs-only option is passed
|
244
257
|
|
245
258
|
name = ops ? "#{pipeline_name}_#{run_type(sanity)}" : pipeline_name
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
require_relative '../../command'
|
4
4
|
require_relative '../../utils/table'
|
5
|
+
require_relative '../../utils/constants'
|
5
6
|
|
6
7
|
module Dri
|
7
8
|
module Commands
|
8
9
|
class Fetch
|
9
10
|
class Quarantines < Dri::Command
|
10
11
|
include Dri::Utils::Table
|
12
|
+
include Dri::Utils::Constants::Triage::Labels
|
11
13
|
using Refinements
|
12
14
|
|
13
15
|
def initialize(options, search: '[QUARANTINE]')
|
@@ -30,7 +32,7 @@ module Dri
|
|
30
32
|
spinner.run do
|
31
33
|
response = api_client.fetch_mrs(
|
32
34
|
project_id: 'gitlab-org/gitlab',
|
33
|
-
labels:
|
35
|
+
labels: "#{QA},#{QUALITY}",
|
34
36
|
search: @search,
|
35
37
|
in: :title,
|
36
38
|
state: :opened
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
require_relative '../../command'
|
4
4
|
require_relative '../../utils/table'
|
5
|
+
require_relative '../../utils/constants'
|
5
6
|
|
6
7
|
module Dri
|
7
8
|
module Commands
|
8
9
|
class Fetch
|
9
10
|
class Triaged < Dri::Command
|
10
11
|
include Dri::Utils::Table
|
12
|
+
include Dri::Utils::Constants::Triage::Labels
|
11
13
|
using Refinements
|
12
14
|
|
13
15
|
def initialize(options)
|
@@ -27,21 +29,21 @@ module Dri
|
|
27
29
|
logger.info "Fetching your triaged failures..."
|
28
30
|
spinner.start
|
29
31
|
|
30
|
-
|
32
|
+
failures = api_client.fetch_all_triaged_failures(emoji: emoji, state: 'opened')
|
31
33
|
|
32
|
-
if
|
34
|
+
if failures.empty?
|
33
35
|
logger.info "There are no failures triaged yet with #{add_color(emoji, :black, :on_white)}."
|
34
36
|
exit 0
|
35
37
|
end
|
36
38
|
|
37
|
-
|
39
|
+
failures.each do |triaged|
|
38
40
|
title = triaged["title"].truncate(70)
|
39
41
|
url = triaged["web_url"]
|
40
42
|
labels = triaged["labels"]
|
41
43
|
type = ""
|
42
44
|
|
43
45
|
labels.each do |label|
|
44
|
-
type = label.gsub!(
|
46
|
+
type = label.gsub!(FAILURE, ' ').to_s if label.include? FAILURE
|
45
47
|
end
|
46
48
|
|
47
49
|
failures_triaged << [title, url, type]
|
data/lib/dri/commands/fetch.rb
CHANGED
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative '../command'
|
4
4
|
require_relative '../utils/table'
|
5
|
+
require_relative '../utils/constants'
|
5
6
|
|
6
7
|
module Dri
|
7
8
|
module Commands
|
8
9
|
class Incidents < Dri::Command
|
9
10
|
include Dri::Utils::Table
|
11
|
+
include Dri::Utils::Constants::Triage::Labels
|
10
12
|
using Refinements
|
11
13
|
|
12
14
|
def initialize(options)
|
@@ -42,8 +44,8 @@ module Dri
|
|
42
44
|
service = "N/A"
|
43
45
|
|
44
46
|
labels.each do |label|
|
45
|
-
status = label.gsub!(
|
46
|
-
service = label.gsub!(
|
47
|
+
status = label.gsub!(INCIDENT, ' ').to_s if label.include? INCIDENT
|
48
|
+
service = label.gsub!(SERVICE, ' ').to_s if label.include? SERVICE
|
47
49
|
end
|
48
50
|
|
49
51
|
incidents << [title, service, status, url]
|
data/lib/dri/commands/init.rb
CHANGED
@@ -34,6 +34,8 @@ module Dri
|
|
34
34
|
@ops_token = prompt.mask("Please provide your ops.gitlab.net personal access token:")
|
35
35
|
@timezone = prompt.select("Choose your current timezone?", %w[EMEA AMER APAC])
|
36
36
|
@emoji = prompt.ask("Have a triage emoji?")
|
37
|
+
@handover_report_path = prompt.ask("Please provide a path for handover report",
|
38
|
+
default: "#{Dir.pwd}/handover_reports")
|
37
39
|
|
38
40
|
if (@emoji || @token || @username || @ops_token).nil?
|
39
41
|
logger.error "Please provide a username, gitlab token, ops token, timezone and emoji used for triage."
|
@@ -45,6 +47,7 @@ module Dri
|
|
45
47
|
config.set(:settings, :ops_token, value: @ops_token)
|
46
48
|
config.set(:settings, :timezone, value: @timezone)
|
47
49
|
config.set(:settings, :emoji, value: @emoji)
|
50
|
+
config.set(:settings, :handover_report_path, value: @handover_report_path)
|
48
51
|
config.write(force: true)
|
49
52
|
|
50
53
|
logger.success "✅ We're ready to go 🚀"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../../command'
|
4
4
|
require_relative '../../utils/markdown_lists'
|
5
|
-
require_relative '../../utils/
|
5
|
+
require_relative '../../utils/constants'
|
6
6
|
require_relative '../../report'
|
7
7
|
require_relative '../../feature_flag_report'
|
8
8
|
|
@@ -14,7 +14,7 @@ module Dri
|
|
14
14
|
module Commands
|
15
15
|
class Publish
|
16
16
|
class Report < Dri::Command # rubocop:disable Metrics/ClassLength
|
17
|
-
include Dri::Utils::
|
17
|
+
include Dri::Utils::Constants::FeatureFlag
|
18
18
|
|
19
19
|
def initialize(options)
|
20
20
|
@options = options
|
@@ -28,20 +28,21 @@ module Dri
|
|
28
28
|
verify_config_exists
|
29
29
|
report = Dri::Report.new(config)
|
30
30
|
|
31
|
-
logger.info "Fetching triaged failures with award emoji #{emoji}..."
|
31
|
+
logger.info "Fetching triaged failures and incidents with award emoji #{emoji}..."
|
32
32
|
|
33
33
|
spinner.start
|
34
34
|
|
35
|
-
|
35
|
+
failures = api_client.fetch_all_triaged_failures(emoji: emoji, state: 'opened')
|
36
|
+
incidents = api_client.fetch_triaged_incidents(emoji: emoji)
|
36
37
|
|
37
38
|
spinner.stop
|
38
39
|
|
39
|
-
if
|
40
|
-
logger.warn "Found no
|
40
|
+
if failures.empty? && incidents.empty?
|
41
|
+
logger.warn "Found no failures nor incidents associated with \"#{emoji}\" emoji. Will exit. Bye 👋"
|
41
42
|
exit 1
|
42
43
|
end
|
43
44
|
|
44
|
-
logger.info 'Assembling the
|
45
|
+
logger.info 'Assembling the handover report... '
|
45
46
|
# sets each failure on the table
|
46
47
|
action_options = [
|
47
48
|
'pinged SET',
|
@@ -57,32 +58,52 @@ module Dri
|
|
57
58
|
|
58
59
|
spinner.start
|
59
60
|
|
60
|
-
|
61
|
+
failures.each do |failure|
|
61
62
|
actions = []
|
62
63
|
|
63
64
|
if @options[:actions]
|
64
65
|
actions = prompt.multi_select(
|
65
|
-
"Please mark the actions on #{add_color(
|
66
|
+
"Please mark the actions on #{add_color(failure.title, :yellow)}: ",
|
66
67
|
action_options,
|
67
68
|
per_page: 9
|
68
69
|
)
|
69
70
|
end
|
70
71
|
|
71
|
-
report.add_failure(
|
72
|
+
report.add_failure(failure, actions)
|
73
|
+
end
|
74
|
+
|
75
|
+
unless incidents.empty?
|
76
|
+
incidents.each do |issue|
|
77
|
+
report.add_incident(issue)
|
78
|
+
end
|
72
79
|
end
|
73
80
|
|
74
81
|
if @options[:format] == 'list'
|
75
82
|
# generates markdown list with failures
|
76
|
-
|
83
|
+
unless report.failures.empty?
|
84
|
+
failure_report = Utils::MarkdownLists.make_list(report.labels, report.failures)
|
85
|
+
end
|
86
|
+
# generates markdown list with incidents
|
87
|
+
unless report.incidents.empty?
|
88
|
+
incidents_report = Utils::MarkdownLists.make_list(report.labels_incidents, report.incidents)
|
89
|
+
end
|
77
90
|
else
|
78
91
|
# generates markdown table with rows as failures
|
79
92
|
unless report.failures.empty?
|
80
|
-
|
93
|
+
failure_report = MarkdownTables.make_table(
|
81
94
|
report.labels,
|
82
95
|
report.failures,
|
83
96
|
is_rows: true, align: %w[l l l l l]
|
84
97
|
)
|
85
98
|
end
|
99
|
+
# generates markdown table with rows as incidents
|
100
|
+
unless report.incidents.empty?
|
101
|
+
incidents_report = MarkdownTables.make_table(
|
102
|
+
report.labels_incidents,
|
103
|
+
report.incidents,
|
104
|
+
is_rows: true, align: %w[l l l l]
|
105
|
+
)
|
106
|
+
end
|
86
107
|
end
|
87
108
|
|
88
109
|
spinner.stop
|
@@ -131,7 +152,7 @@ module Dri
|
|
131
152
|
end
|
132
153
|
|
133
154
|
report.set_header(timezone, username)
|
134
|
-
note = "#{report.header}\n\n#{
|
155
|
+
note = "#{report.header}\n\n#{failure_report}\n\n#{incidents_report}"
|
135
156
|
|
136
157
|
note += feature_flag_note if @options[:feature_flags]
|
137
158
|
|
@@ -141,8 +162,8 @@ module Dri
|
|
141
162
|
|
142
163
|
spinner.start
|
143
164
|
|
144
|
-
FileUtils.mkdir_p(
|
145
|
-
report_path = "
|
165
|
+
FileUtils.mkdir_p(handover_report_path)
|
166
|
+
report_path = "#{handover_report_path.chomp('/')}/report-#{@date}-#{@time}.md"
|
146
167
|
|
147
168
|
File.open(report_path, 'a') do |out_file|
|
148
169
|
out_file.puts note
|
@@ -159,11 +180,29 @@ module Dri
|
|
159
180
|
issues = api_client.fetch_current_triage_issue
|
160
181
|
current_issue_iid = issues.first.iid
|
161
182
|
|
162
|
-
|
183
|
+
note_action = 'posted'
|
184
|
+
posted_note = nil
|
185
|
+
if @options[:update]
|
186
|
+
report_file = File.read("handover_reports/.tmp/report-#{@date}.json")
|
187
|
+
report_json = JSON.parse(report_file) if report_file
|
188
|
+
posted_note = api_client.update_triage_report_note(
|
189
|
+
iid: current_issue_iid, note_id: report_json['id'], body: note
|
190
|
+
)
|
191
|
+
note_action = 'updated'
|
192
|
+
else
|
193
|
+
posted_note = api_client.post_triage_report_note(iid: current_issue_iid, body: note)
|
194
|
+
|
195
|
+
FileUtils.mkdir_p("#{Dir.pwd}/handover_reports/.tmp")
|
196
|
+
report_path = "handover_reports/.tmp/report-#{@date}.json"
|
197
|
+
|
198
|
+
File.open(report_path, 'w') do |out_file|
|
199
|
+
out_file.write(posted_note.to_h.to_json)
|
200
|
+
end
|
201
|
+
end
|
163
202
|
|
164
203
|
output.puts "Done! ✅\n"
|
165
204
|
logger.success(<<~MSG)
|
166
|
-
Thanks @#{username}, your report was
|
205
|
+
Thanks @#{username}, your report was #{note_action} at https://gitlab.com/gitlab-org/quality/pipeline-triage/-/issues/#{current_issue_iid}#note_#{posted_note.id} 🎉
|
167
206
|
MSG
|
168
207
|
end
|
169
208
|
|
data/lib/dri/commands/publish.rb
CHANGED
@@ -16,6 +16,9 @@ module Dri
|
|
16
16
|
desc: 'Updates actions on failures'
|
17
17
|
method_option :feature_flags, type: :boolean,
|
18
18
|
desc: 'Adds summary of feature flag changes'
|
19
|
+
method_option :update, aliases: '-u', type: :boolean,
|
20
|
+
desc: 'Updates an existing report'
|
21
|
+
|
19
22
|
def report(*)
|
20
23
|
if options[:help]
|
21
24
|
invoke :help, ['report']
|
@@ -20,25 +20,35 @@ module Dri
|
|
20
20
|
exit 0
|
21
21
|
end
|
22
22
|
|
23
|
-
logger.info "Removing #{emoji} from issues..."
|
23
|
+
logger.info "Removing #{emoji} emoji from issues..."
|
24
24
|
|
25
25
|
spinner.start
|
26
26
|
|
27
|
-
|
27
|
+
failures_with_award_emoji = api_client.fetch_all_triaged_failures(emoji: emoji, state: 'opened')
|
28
|
+
incidents_with_award_emoji = api_client.fetch_triaged_incidents(emoji: emoji)
|
29
|
+
|
30
|
+
issues_with_award_emoji = failures_with_award_emoji + incidents_with_award_emoji
|
28
31
|
|
29
32
|
spinner.stop
|
30
33
|
|
34
|
+
cleared_issues_counter = 0
|
31
35
|
issues_with_award_emoji.each do |issue|
|
32
|
-
logger.info "Removing #{emoji} from #{issue.web_url}
|
33
|
-
|
34
|
-
response = api_client.fetch_awarded_emojis(issue.iid)
|
36
|
+
logger.info "Removing #{emoji} emoji from #{issue.web_url}"
|
35
37
|
|
38
|
+
response = api_client.fetch_awarded_emojis(issue.iid, project_id: issue.project_id)
|
36
39
|
emoji_found = response.find { |e| e.name == emoji && e.to_h.dig('user', 'username') == username }
|
37
40
|
|
38
|
-
|
41
|
+
if emoji_found.nil?
|
42
|
+
logger.error "Emoji #{add_color(emoji, :red)} not found for username: #{add_color(username, :red)}"
|
43
|
+
next
|
44
|
+
else
|
45
|
+
api_client.delete_award_emoji(issue.iid, emoji_id: emoji_found.id, project_id: issue.project_id)
|
46
|
+
cleared_issues_counter += 1
|
47
|
+
end
|
39
48
|
end
|
49
|
+
|
40
50
|
output.puts "Done! ✅"
|
41
|
-
logger.success "Removed #{emoji} from #{
|
51
|
+
logger.success "Removed #{emoji} from #{cleared_issues_counter} issue(s)."
|
42
52
|
end
|
43
53
|
end
|
44
54
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative './utils/
|
3
|
+
require_relative './utils/constants'
|
4
4
|
|
5
5
|
module Dri
|
6
6
|
class FeatureFlagReport
|
7
|
-
include Dri::Utils::
|
7
|
+
include Dri::Utils::Constants::FeatureFlag::Labels
|
8
8
|
|
9
9
|
attr_reader :header, :labels, :prod, :staging, :staging_ref, :preprod
|
10
10
|
|
data/lib/dri/report.rb
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative './utils/constants'
|
4
|
+
|
3
5
|
module Dri
|
4
6
|
class Report # rubocop:disable Metrics/ClassLength
|
7
|
+
include Dri::Utils::Constants::Triage::Labels
|
5
8
|
using Refinements
|
6
9
|
|
7
|
-
attr_reader :header, :failures, :labels
|
10
|
+
attr_reader :header, :failures, :labels, :labels_incidents, :incidents
|
8
11
|
|
9
12
|
def initialize(config)
|
10
13
|
@labels = ['Title', 'Issue', 'Pipelines', 'Stack Trace', 'Actions']
|
14
|
+
@labels_incidents = %w[Incident Service Status URL]
|
11
15
|
@failures = []
|
16
|
+
@incidents = []
|
12
17
|
@date = Date.today
|
13
18
|
@today = Date.today.strftime("%Y-%m-%d")
|
14
19
|
@weekday = Date.today.strftime("%A")
|
@@ -21,17 +26,31 @@ module Dri
|
|
21
26
|
@header = "# #{timezone}, #{@weekday} - #{@date}\n posted by: @#{username}"
|
22
27
|
end
|
23
28
|
|
29
|
+
def add_incident(incident)
|
30
|
+
title = incident["title"]
|
31
|
+
url = incident["web_url"]
|
32
|
+
labels = incident["labels"]
|
33
|
+
status = 'N/A'
|
34
|
+
service = 'N/A'
|
35
|
+
|
36
|
+
labels.each do |label|
|
37
|
+
status = label.gsub!(INCIDENT, ' ').to_s if label.include? INCIDENT
|
38
|
+
service = label.gsub!(SERVICE, ' ').to_s if label.include? SERVICE
|
39
|
+
end
|
40
|
+
|
41
|
+
@incidents << [title, service, status, url]
|
42
|
+
end
|
43
|
+
|
24
44
|
def add_failure(failure, actions_opts = [])
|
45
|
+
project_id = failure["project_id"]
|
25
46
|
iid = failure["iid"]
|
26
47
|
title = format_title(failure["title"])
|
27
48
|
link = failure["web_url"]
|
28
49
|
labels = failure["labels"]
|
29
|
-
created_at = failure["created_at"]
|
30
|
-
assignees = failure["assignees"]
|
31
50
|
description = failure["description"]
|
32
51
|
|
33
|
-
related_mrs = @api_client.fetch_related_mrs(iid)
|
34
|
-
emoji = classify_failure_emoji(created_at)
|
52
|
+
related_mrs = @api_client.fetch_related_mrs(project_id, iid)
|
53
|
+
emoji = classify_failure_emoji(failure["created_at"])
|
35
54
|
emojified_link = "#{emoji} #{link}"
|
36
55
|
|
37
56
|
stack_blob = if description.empty?
|
@@ -43,10 +62,10 @@ module Dri
|
|
43
62
|
stack_trace = ":link:[`#{stack_blob}...`](#{link}#stack-trace)"
|
44
63
|
|
45
64
|
failure_type = filter_failure_type_labels(labels)
|
46
|
-
assigned_status = assigned?(assignees)
|
65
|
+
assigned_status = assigned?(failure["assignees"])
|
47
66
|
pipelines = filter_pipeline_labels(labels)
|
48
67
|
|
49
|
-
linked_pipelines = link_pipelines(iid, pipelines, description)
|
68
|
+
linked_pipelines = link_pipelines(project_id, iid, pipelines, description)
|
50
69
|
|
51
70
|
actions_status = actions_status_template(failure_type, assigned_status, actions_opts)
|
52
71
|
actions_fixes = actions_fixes_template(related_mrs)
|
@@ -56,7 +75,7 @@ module Dri
|
|
56
75
|
|
57
76
|
private
|
58
77
|
|
59
|
-
def link_pipelines(iid, pipelines, description) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
78
|
+
def link_pipelines(project_id, iid, pipelines, description) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
60
79
|
linked = []
|
61
80
|
label_pipeline_map = {
|
62
81
|
'gitlab.com' => '/quality/production',
|
@@ -71,7 +90,7 @@ module Dri
|
|
71
90
|
'release' => '/quality/release'
|
72
91
|
}
|
73
92
|
|
74
|
-
failure_notes = @api_client.fetch_failure_notes(iid)
|
93
|
+
failure_notes = @api_client.fetch_failure_notes(project_id, iid)
|
75
94
|
|
76
95
|
return if pipelines.empty?
|
77
96
|
|
@@ -156,10 +175,10 @@ module Dri
|
|
156
175
|
pipelines = []
|
157
176
|
|
158
177
|
labels.each do |label|
|
159
|
-
matchers = {
|
178
|
+
matchers = { FOUND => ' ' }
|
160
179
|
|
161
|
-
if label.include?
|
162
|
-
pipeline = label.gsub(/
|
180
|
+
if label.include? FOUND
|
181
|
+
pipeline = label.gsub(/#{FOUND}/o) { |match| matchers[match] }
|
163
182
|
pipelines << pipeline.strip
|
164
183
|
end
|
165
184
|
end
|
@@ -168,7 +187,7 @@ module Dri
|
|
168
187
|
|
169
188
|
def filter_failure_type_labels(labels)
|
170
189
|
labels.each do |label|
|
171
|
-
@type = label.gsub!(
|
190
|
+
@type = label.gsub!(FAILURE, ' ').to_s if label.include? FAILURE
|
172
191
|
end
|
173
192
|
@type
|
174
193
|
end
|
data/lib/dri/utils/constants.rb
CHANGED
@@ -3,6 +3,39 @@
|
|
3
3
|
module Dri
|
4
4
|
module Utils
|
5
5
|
module Constants
|
6
|
+
module ProjectIDs
|
7
|
+
TESTCASES_PROJECT_ID = 11229385
|
8
|
+
TRIAGE_PROJECT_ID = 15291320
|
9
|
+
GITLAB_PROJECT_ID = 278964
|
10
|
+
CUSTOMERSDOT_PROJECT_ID = 2670515
|
11
|
+
FEATURE_FLAG_LOG_PROJECT_ID = 15208716
|
12
|
+
INFRA_TEAM_PROD_PROJECT_ID = 7444821
|
13
|
+
end
|
14
|
+
|
15
|
+
module Triage
|
16
|
+
module Labels
|
17
|
+
FOUND = 'found:'
|
18
|
+
FAILURE = 'failure::'
|
19
|
+
FAILURE_NEW = "#{FAILURE}new"
|
20
|
+
INCIDENT = 'Incident::'
|
21
|
+
SERVICE = 'Service::'
|
22
|
+
QA = 'QA'
|
23
|
+
QUALITY = 'Quality'
|
24
|
+
QUARANTINE = 'quarantine'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module FeatureFlag
|
29
|
+
module Labels
|
30
|
+
PRODUCTION = 'host::gitlab.com'
|
31
|
+
STAGING = 'host::staging.gitlab.com'
|
32
|
+
STAGING_REF = 'host::staging-ref.gitlab.com'
|
33
|
+
PREPROD = 'host::pre.gitlab.com'
|
34
|
+
end
|
35
|
+
|
36
|
+
TITLE_SUBSTRINGS = ["set to \"true\"", "set to \"false\""].freeze
|
37
|
+
end
|
38
|
+
|
6
39
|
PIPELINE_ENVIRONMENTS =
|
7
40
|
{
|
8
41
|
production: {
|
@@ -49,9 +82,9 @@ module Dri
|
|
49
82
|
},
|
50
83
|
master: {
|
51
84
|
name: "master",
|
52
|
-
url: "https://gitlab.com/gitlab-org/gitlab
|
53
|
-
project_id: "
|
54
|
-
search_hours_ago:
|
85
|
+
url: "https://gitlab.com/gitlab-org/gitlab",
|
86
|
+
project_id: "278964",
|
87
|
+
search_hours_ago: 3
|
55
88
|
}
|
56
89
|
}.freeze
|
57
90
|
end
|
data/lib/dri/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab Quality
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: amatch
|
@@ -355,7 +355,6 @@ files:
|
|
355
355
|
- lib/dri/refinements/truncate.rb
|
356
356
|
- lib/dri/report.rb
|
357
357
|
- lib/dri/utils/constants.rb
|
358
|
-
- lib/dri/utils/feature_flag_consts.rb
|
359
358
|
- lib/dri/utils/markdown_lists.rb
|
360
359
|
- lib/dri/utils/table.rb
|
361
360
|
- lib/dri/version.rb
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Dri
|
4
|
-
module Utils
|
5
|
-
module FeatureFlagConsts
|
6
|
-
PRODUCTION = 'host::gitlab.com'
|
7
|
-
STAGING = 'host::staging.gitlab.com'
|
8
|
-
STAGING_REF = 'host::staging-ref.gitlab.com'
|
9
|
-
PREPROD = 'host::pre.gitlab.com'
|
10
|
-
TITLE_SUBSTRINGS = ["set to \"true\"", "set to \"false\""].freeze
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|