gitlab_quality-test_tooling 1.14.0 → 1.17.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/Gemfile.lock +73 -70
- data/exe/flaky-test-issues +4 -4
- data/lefthook.yml +13 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/branches_client.rb +1 -1
- data/lib/gitlab_quality/test_tooling/gitlab_client/commits_client.rb +6 -4
- data/lib/gitlab_quality/test_tooling/gitlab_client/gitlab_client.rb +12 -13
- data/lib/gitlab_quality/test_tooling/gitlab_client/issues_client.rb +6 -6
- data/lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_client.rb +6 -3
- data/lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_dry_client.rb +4 -2
- data/lib/gitlab_quality/test_tooling/report/concerns/issue_reports.rb +41 -28
- data/lib/gitlab_quality/test_tooling/report/concerns/utils.rb +1 -1
- data/lib/gitlab_quality/test_tooling/report/flaky_test_issue.rb +78 -43
- data/lib/gitlab_quality/test_tooling/report/generate_test_session.rb +1 -4
- data/lib/gitlab_quality/test_tooling/report/knapsack_report_issue.rb +0 -3
- data/lib/gitlab_quality/test_tooling/report/relate_failure_issue.rb +4 -8
- data/lib/gitlab_quality/test_tooling/report/report_as_issue.rb +5 -3
- data/lib/gitlab_quality/test_tooling/report/slow_test_issue.rb +71 -78
- data/lib/gitlab_quality/test_tooling/runtime/env.rb +5 -1
- data/lib/gitlab_quality/test_tooling/test_meta/processor/add_to_blocking_processor.rb +33 -16
- data/lib/gitlab_quality/test_tooling/test_meta/processor/add_to_quarantine_processor.rb +34 -19
- data/lib/gitlab_quality/test_tooling/test_meta/processor/meta_processor.rb +21 -0
- data/lib/gitlab_quality/test_tooling/test_meta/test_meta_updater.rb +70 -9
- data/lib/gitlab_quality/test_tooling/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8709476aafe6dc96d2b49d1d74b18b2e3dbf6c37cb8ebb0acd631d05dbfe2ac
|
|
4
|
+
data.tar.gz: 26d4d54613a522014b5f3b93f38c0cb62027c2e209573727265a5c2b630a6d9d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 194294ffed245e88a96e35480485f98c1748a8417766cdca1cf737ece2b090a4e29efc444fa449f5f569e292333ba50954f7c07a72fbb2f9225c9195c4b6f411
|
|
7
|
+
data.tar.gz: 30cc7f3a5da1c15b5c3508e0850c007bddf9f22a85c9ec1361821be7bc330afd3869cd9fe74d3b424afc2d0ad2d180c4c0649b5f502f4740ca68f1b2c8119933
|
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
gitlab_quality-test_tooling (1.
|
|
5
|
-
activesupport (>= 6.1, < 7.
|
|
4
|
+
gitlab_quality-test_tooling (1.17.0)
|
|
5
|
+
activesupport (>= 6.1, < 7.1)
|
|
6
6
|
amatch (~> 0.4.1)
|
|
7
7
|
gitlab (~> 4.19)
|
|
8
8
|
http (~> 5.0)
|
|
@@ -21,15 +21,14 @@ GEM
|
|
|
21
21
|
i18n (>= 1.6, < 2)
|
|
22
22
|
minitest (>= 5.1)
|
|
23
23
|
tzinfo (~> 2.0)
|
|
24
|
-
|
|
25
|
-
addressable (2.8.4)
|
|
24
|
+
addressable (2.8.6)
|
|
26
25
|
public_suffix (>= 2.0.2, < 6.0)
|
|
27
26
|
amatch (0.4.1)
|
|
28
27
|
mize
|
|
29
28
|
tins (~> 1.0)
|
|
30
29
|
ast (2.4.2)
|
|
31
30
|
backport (1.2.0)
|
|
32
|
-
benchmark (0.
|
|
31
|
+
benchmark (0.3.0)
|
|
33
32
|
binding_of_caller (1.0.0)
|
|
34
33
|
debug_inspector (>= 0.0.1)
|
|
35
34
|
byebug (11.1.3)
|
|
@@ -41,23 +40,23 @@ GEM
|
|
|
41
40
|
climate_control (1.2.0)
|
|
42
41
|
coderay (1.1.3)
|
|
43
42
|
colored2 (3.1.2)
|
|
44
|
-
concurrent-ruby (1.2.
|
|
43
|
+
concurrent-ruby (1.2.3)
|
|
45
44
|
cork (0.3.0)
|
|
46
45
|
colored2 (~> 3.1)
|
|
47
46
|
crack (0.4.5)
|
|
48
47
|
rexml
|
|
49
|
-
danger (9.
|
|
48
|
+
danger (9.4.2)
|
|
50
49
|
claide (~> 1.0)
|
|
51
50
|
claide-plugins (>= 0.9.2)
|
|
52
51
|
colored2 (~> 3.1)
|
|
53
52
|
cork (~> 0.1)
|
|
54
53
|
faraday (>= 0.9.0, < 3.0)
|
|
55
54
|
faraday-http-cache (~> 2.0)
|
|
56
|
-
git (~> 1.13
|
|
55
|
+
git (~> 1.13)
|
|
57
56
|
kramdown (~> 2.3)
|
|
58
57
|
kramdown-parser-gfm (~> 1.0)
|
|
59
58
|
no_proxy_fix
|
|
60
|
-
octokit (
|
|
59
|
+
octokit (>= 4.0)
|
|
61
60
|
terminal-table (>= 1, < 4)
|
|
62
61
|
danger-gitlab (8.0.0)
|
|
63
62
|
danger
|
|
@@ -65,37 +64,36 @@ GEM
|
|
|
65
64
|
debug_inspector (1.2.0)
|
|
66
65
|
diff-lcs (1.5.0)
|
|
67
66
|
docile (1.4.0)
|
|
68
|
-
domain_name (0.
|
|
69
|
-
unf (>= 0.0.5, < 1.0.0)
|
|
67
|
+
domain_name (0.6.20240107)
|
|
70
68
|
e2mmap (0.1.0)
|
|
71
|
-
faraday (2.
|
|
72
|
-
faraday-net_http (>= 2.0, < 3.
|
|
73
|
-
|
|
74
|
-
faraday-http-cache (2.5.0)
|
|
69
|
+
faraday (2.9.0)
|
|
70
|
+
faraday-net_http (>= 2.0, < 3.2)
|
|
71
|
+
faraday-http-cache (2.5.1)
|
|
75
72
|
faraday (>= 0.8)
|
|
76
|
-
faraday-net_http (3.0
|
|
77
|
-
|
|
73
|
+
faraday-net_http (3.1.0)
|
|
74
|
+
net-http
|
|
75
|
+
ffi (1.16.3)
|
|
78
76
|
ffi-compiler (1.0.1)
|
|
79
77
|
ffi (>= 1.0.0)
|
|
80
78
|
rake
|
|
81
79
|
formatador (1.1.0)
|
|
82
|
-
git (1.
|
|
80
|
+
git (1.19.1)
|
|
83
81
|
addressable (~> 2.8)
|
|
84
82
|
rchardet (~> 1.8)
|
|
85
83
|
gitlab (4.19.0)
|
|
86
84
|
httparty (~> 0.20)
|
|
87
85
|
terminal-table (>= 1.5.1)
|
|
88
|
-
gitlab-dangerfiles (3.
|
|
86
|
+
gitlab-dangerfiles (3.13.0)
|
|
89
87
|
danger (>= 8.4.5)
|
|
90
88
|
danger-gitlab (>= 8.0.0)
|
|
91
89
|
rake
|
|
92
|
-
gitlab-styles (10.
|
|
93
|
-
rubocop (~> 1.
|
|
90
|
+
gitlab-styles (10.1.0)
|
|
91
|
+
rubocop (~> 1.50.2)
|
|
94
92
|
rubocop-graphql (~> 0.18)
|
|
95
93
|
rubocop-performance (~> 1.15)
|
|
96
94
|
rubocop-rails (~> 2.17)
|
|
97
|
-
rubocop-rspec (~> 2.
|
|
98
|
-
guard (2.18.
|
|
95
|
+
rubocop-rspec (~> 2.22)
|
|
96
|
+
guard (2.18.1)
|
|
99
97
|
formatador (>= 0.2.4)
|
|
100
98
|
listen (>= 2.7, < 4.0)
|
|
101
99
|
lumberjack (>= 1.0.12, < 2.0)
|
|
@@ -109,7 +107,7 @@ GEM
|
|
|
109
107
|
guard (~> 2.1)
|
|
110
108
|
guard-compat (~> 1.1)
|
|
111
109
|
rspec (>= 2.99.0, < 4.0)
|
|
112
|
-
hashdiff (1.0
|
|
110
|
+
hashdiff (1.1.0)
|
|
113
111
|
http (5.1.1)
|
|
114
112
|
addressable (~> 2.8)
|
|
115
113
|
http-cookie (~> 1.0)
|
|
@@ -121,45 +119,48 @@ GEM
|
|
|
121
119
|
httparty (0.21.0)
|
|
122
120
|
mini_mime (>= 1.0.0)
|
|
123
121
|
multi_xml (>= 0.5.2)
|
|
124
|
-
i18n (1.
|
|
122
|
+
i18n (1.14.1)
|
|
125
123
|
concurrent-ruby (~> 1.0)
|
|
126
|
-
jaro_winkler (1.5.
|
|
127
|
-
json (2.
|
|
124
|
+
jaro_winkler (1.5.6)
|
|
125
|
+
json (2.7.1)
|
|
128
126
|
kramdown (2.4.0)
|
|
129
127
|
rexml
|
|
130
128
|
kramdown-parser-gfm (1.1.0)
|
|
131
129
|
kramdown (~> 2.0)
|
|
132
|
-
lefthook (1.
|
|
130
|
+
lefthook (1.6.1)
|
|
133
131
|
listen (3.8.0)
|
|
134
132
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
135
133
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
136
134
|
llhttp-ffi (0.4.0)
|
|
137
135
|
ffi-compiler (~> 1.0)
|
|
138
136
|
rake (~> 13.0)
|
|
139
|
-
lumberjack (1.2.
|
|
137
|
+
lumberjack (1.2.10)
|
|
140
138
|
method_source (1.0.0)
|
|
141
|
-
mini_mime (1.1.
|
|
142
|
-
mini_portile2 (2.8.
|
|
143
|
-
minitest (5.
|
|
139
|
+
mini_mime (1.1.5)
|
|
140
|
+
mini_portile2 (2.8.5)
|
|
141
|
+
minitest (5.21.2)
|
|
144
142
|
mize (0.4.1)
|
|
145
143
|
protocol (~> 2.0)
|
|
146
144
|
multi_xml (0.6.0)
|
|
147
145
|
nap (1.1.0)
|
|
148
146
|
nenv (0.3.0)
|
|
147
|
+
net-http (0.4.1)
|
|
148
|
+
uri
|
|
149
149
|
no_proxy_fix (0.1.2)
|
|
150
|
-
nokogiri (1.
|
|
151
|
-
mini_portile2 (~> 2.8.
|
|
150
|
+
nokogiri (1.16.0)
|
|
151
|
+
mini_portile2 (~> 2.8.2)
|
|
152
152
|
racc (~> 1.4)
|
|
153
153
|
notiffany (0.1.3)
|
|
154
154
|
nenv (~> 0.1)
|
|
155
155
|
shellany (~> 0.0)
|
|
156
|
-
octokit (
|
|
156
|
+
octokit (8.0.0)
|
|
157
157
|
faraday (>= 1, < 3)
|
|
158
158
|
sawyer (~> 0.9)
|
|
159
159
|
open4 (1.3.4)
|
|
160
|
-
parallel (1.
|
|
161
|
-
parser (3.
|
|
160
|
+
parallel (1.24.0)
|
|
161
|
+
parser (3.3.0.5)
|
|
162
162
|
ast (~> 2.4.1)
|
|
163
|
+
racc
|
|
163
164
|
proc_to_ast (0.1.0)
|
|
164
165
|
coderay
|
|
165
166
|
parser
|
|
@@ -172,20 +173,20 @@ GEM
|
|
|
172
173
|
pry-byebug (3.10.1)
|
|
173
174
|
byebug (~> 11.0)
|
|
174
175
|
pry (>= 0.13, < 0.15)
|
|
175
|
-
public_suffix (5.0.
|
|
176
|
-
racc (1.
|
|
177
|
-
rack (3.0.
|
|
176
|
+
public_suffix (5.0.4)
|
|
177
|
+
racc (1.7.3)
|
|
178
|
+
rack (3.0.8)
|
|
178
179
|
rainbow (3.1.1)
|
|
179
|
-
rake (13.0
|
|
180
|
+
rake (13.1.0)
|
|
180
181
|
rb-fsevent (0.11.2)
|
|
181
182
|
rb-inotify (0.10.1)
|
|
182
183
|
ffi (~> 1.0)
|
|
183
184
|
rbs (2.8.4)
|
|
184
185
|
rchardet (1.8.0)
|
|
185
|
-
regexp_parser (2.
|
|
186
|
+
regexp_parser (2.9.0)
|
|
186
187
|
reverse_markdown (2.1.1)
|
|
187
188
|
nokogiri
|
|
188
|
-
rexml (3.2.
|
|
189
|
+
rexml (3.2.6)
|
|
189
190
|
rspec (3.12.0)
|
|
190
191
|
rspec-core (~> 3.12.0)
|
|
191
192
|
rspec-expectations (~> 3.12.0)
|
|
@@ -195,7 +196,7 @@ GEM
|
|
|
195
196
|
rspec-expectations (3.12.3)
|
|
196
197
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
197
198
|
rspec-support (~> 3.12.0)
|
|
198
|
-
rspec-mocks (3.12.
|
|
199
|
+
rspec-mocks (3.12.6)
|
|
199
200
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
200
201
|
rspec-support (~> 3.12.0)
|
|
201
202
|
rspec-parameterized (1.0.0)
|
|
@@ -209,41 +210,45 @@ GEM
|
|
|
209
210
|
rspec-parameterized-table_syntax (1.0.1)
|
|
210
211
|
binding_of_caller
|
|
211
212
|
rspec-parameterized-core (< 2)
|
|
212
|
-
rspec-support (3.12.
|
|
213
|
-
rubocop (1.
|
|
213
|
+
rspec-support (3.12.1)
|
|
214
|
+
rubocop (1.50.2)
|
|
214
215
|
json (~> 2.3)
|
|
215
216
|
parallel (~> 1.10)
|
|
216
217
|
parser (>= 3.2.0.0)
|
|
217
218
|
rainbow (>= 2.2.2, < 4.0)
|
|
218
219
|
regexp_parser (>= 1.8, < 3.0)
|
|
219
220
|
rexml (>= 3.2.5, < 4.0)
|
|
220
|
-
rubocop-ast (>= 1.
|
|
221
|
+
rubocop-ast (>= 1.28.0, < 2.0)
|
|
221
222
|
ruby-progressbar (~> 1.7)
|
|
222
223
|
unicode-display_width (>= 2.4.0, < 3.0)
|
|
223
|
-
rubocop-ast (1.
|
|
224
|
+
rubocop-ast (1.30.0)
|
|
224
225
|
parser (>= 3.2.1.0)
|
|
225
|
-
rubocop-capybara (2.
|
|
226
|
+
rubocop-capybara (2.20.0)
|
|
227
|
+
rubocop (~> 1.41)
|
|
228
|
+
rubocop-factory_bot (2.25.1)
|
|
226
229
|
rubocop (~> 1.41)
|
|
227
230
|
rubocop-graphql (0.19.0)
|
|
228
231
|
rubocop (>= 0.87, < 2)
|
|
229
|
-
rubocop-performance (1.
|
|
230
|
-
rubocop (>= 1.
|
|
231
|
-
rubocop-ast (>=
|
|
232
|
-
rubocop-rails (2.
|
|
232
|
+
rubocop-performance (1.20.2)
|
|
233
|
+
rubocop (>= 1.48.1, < 2.0)
|
|
234
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
235
|
+
rubocop-rails (2.23.1)
|
|
233
236
|
activesupport (>= 4.2.0)
|
|
234
237
|
rack (>= 1.1)
|
|
235
238
|
rubocop (>= 1.33.0, < 2.0)
|
|
236
|
-
|
|
237
|
-
|
|
239
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
240
|
+
rubocop-rspec (2.26.1)
|
|
241
|
+
rubocop (~> 1.40)
|
|
238
242
|
rubocop-capybara (~> 2.17)
|
|
243
|
+
rubocop-factory_bot (~> 2.22)
|
|
239
244
|
ruby-progressbar (1.13.0)
|
|
240
|
-
|
|
241
|
-
|
|
245
|
+
ruby_parser (3.21.0)
|
|
246
|
+
racc (~> 1.5)
|
|
242
247
|
sexp_processor (~> 4.16)
|
|
243
248
|
sawyer (0.9.2)
|
|
244
249
|
addressable (>= 2.3.5)
|
|
245
250
|
faraday (>= 0.17.3, < 3)
|
|
246
|
-
sexp_processor (4.17.
|
|
251
|
+
sexp_processor (4.17.1)
|
|
247
252
|
shellany (0.0.1)
|
|
248
253
|
simplecov (0.22.0)
|
|
249
254
|
docile (~> 1.1)
|
|
@@ -254,7 +259,7 @@ GEM
|
|
|
254
259
|
simplecov (~> 0.19)
|
|
255
260
|
simplecov-html (0.12.3)
|
|
256
261
|
simplecov_json_formatter (0.1.4)
|
|
257
|
-
solargraph (0.
|
|
262
|
+
solargraph (0.50.0)
|
|
258
263
|
backport (~> 1.2)
|
|
259
264
|
benchmark
|
|
260
265
|
bundler (~> 2.0)
|
|
@@ -274,26 +279,24 @@ GEM
|
|
|
274
279
|
table_print (1.5.7)
|
|
275
280
|
terminal-table (3.0.2)
|
|
276
281
|
unicode-display_width (>= 1.1.1, < 3)
|
|
277
|
-
thor (1.
|
|
278
|
-
tilt (2.
|
|
279
|
-
timecop (0.9.
|
|
282
|
+
thor (1.3.0)
|
|
283
|
+
tilt (2.3.0)
|
|
284
|
+
timecop (0.9.8)
|
|
280
285
|
tins (1.32.1)
|
|
281
286
|
sync
|
|
282
287
|
tzinfo (2.0.6)
|
|
283
288
|
concurrent-ruby (~> 1.0)
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
unf_ext (0.0.8.2)
|
|
287
|
-
unicode-display_width (2.4.2)
|
|
288
|
-
unparser (0.6.8)
|
|
289
|
+
unicode-display_width (2.5.0)
|
|
290
|
+
unparser (0.6.12)
|
|
289
291
|
diff-lcs (~> 1.3)
|
|
290
|
-
parser (>= 3.2.
|
|
292
|
+
parser (>= 3.2.2.4)
|
|
293
|
+
uri (0.13.0)
|
|
291
294
|
webmock (3.7.0)
|
|
292
295
|
addressable (>= 2.3.6)
|
|
293
296
|
crack (>= 0.3.2)
|
|
294
297
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
295
298
|
yard (0.9.34)
|
|
296
|
-
zeitwerk (2.6.
|
|
299
|
+
zeitwerk (2.6.12)
|
|
297
300
|
|
|
298
301
|
PLATFORMS
|
|
299
302
|
ruby
|
|
@@ -315,4 +318,4 @@ DEPENDENCIES
|
|
|
315
318
|
webmock (= 3.7.0)
|
|
316
319
|
|
|
317
320
|
BUNDLED WITH
|
|
318
|
-
2.4
|
|
321
|
+
2.5.4
|
data/exe/flaky-test-issues
CHANGED
|
@@ -19,10 +19,6 @@ options = OptionParser.new do |opts|
|
|
|
19
19
|
params[:project] = project
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
opts.on('-m', '--merge_request_iid MERGE_REQUEST_IID', String, 'An integer merge request IID') do |merge_request_iid|
|
|
23
|
-
params[:merge_request_iid] = merge_request_iid
|
|
24
|
-
end
|
|
25
|
-
|
|
26
22
|
opts.on('--base-issue-labels BASE_ISSUE_LABELS', String,
|
|
27
23
|
'Comma-separated labels (without tilde) to add to new flaky test issues') do |base_issue_labels|
|
|
28
24
|
params[:base_issue_labels] = base_issue_labels.split(',')
|
|
@@ -32,6 +28,10 @@ options = OptionParser.new do |opts|
|
|
|
32
28
|
params[:token] = token
|
|
33
29
|
end
|
|
34
30
|
|
|
31
|
+
opts.on('-r', '--related-issues-file RELATED_ISSUES_FILE', String, 'The file path for the related issues') do |related_issues_file|
|
|
32
|
+
params[:related_issues_file] = related_issues_file
|
|
33
|
+
end
|
|
34
|
+
|
|
35
35
|
opts.on('--dry-run', "Perform a dry-run (don't create issues)") do
|
|
36
36
|
params[:dry_run] = true
|
|
37
37
|
end
|
data/lefthook.yml
CHANGED
|
@@ -13,3 +13,16 @@ pre-push:
|
|
|
13
13
|
rubocop:
|
|
14
14
|
run: bundle exec rubocop
|
|
15
15
|
glob: '*.rb'
|
|
16
|
+
|
|
17
|
+
# Changelog git trailer for the first commit of the branch
|
|
18
|
+
changelog-on-first-commit:
|
|
19
|
+
run: |
|
|
20
|
+
first_commit_message=$(git log --format=%B -n 1 $(git log main..HEAD --pretty=format:"%h" | tail -1))
|
|
21
|
+
if ! echo ${first_commit_message} | grep "Changelog:"; then
|
|
22
|
+
echo Could not find a Changelog: git trailer on the first commit for this branch.
|
|
23
|
+
echo
|
|
24
|
+
echo Please add a trailer by amending the git commit message.
|
|
25
|
+
echo
|
|
26
|
+
echo See https://docs.gitlab.com/ee/development/changelog.html#overview for more info.
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
@@ -9,7 +9,7 @@ module GitlabQuality
|
|
|
9
9
|
client.create_branch(project, branch_name, ref)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
Runtime::Logger.debug("Created branch #{branch['name']} (#{branch['web_url']})")
|
|
12
|
+
Runtime::Logger.debug("Created branch #{branch['name']} (#{branch['web_url']})") if branch
|
|
13
13
|
branch
|
|
14
14
|
end
|
|
15
15
|
end
|
|
@@ -5,11 +5,13 @@ module GitlabQuality
|
|
|
5
5
|
module GitlabClient
|
|
6
6
|
class CommitsClient < GitlabClient
|
|
7
7
|
def create(branch_name, file_path, new_content, message)
|
|
8
|
-
commit =
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
commit = handle_gitlab_client_exceptions do
|
|
9
|
+
client.create_commit(project, branch_name, message, [
|
|
10
|
+
{ action: :update, file_path: file_path, content: new_content }
|
|
11
|
+
])
|
|
12
|
+
end
|
|
11
13
|
|
|
12
|
-
Runtime::Logger.debug("Created commit #{commit['id']} (#{commit['web_url']}) on #{branch_name}")
|
|
14
|
+
Runtime::Logger.debug("Created commit #{commit['id']} (#{commit['web_url']}) on #{branch_name}") if commit
|
|
13
15
|
commit
|
|
14
16
|
end
|
|
15
17
|
end
|
|
@@ -15,24 +15,32 @@ module GitlabQuality
|
|
|
15
15
|
@retry_backoff = 0
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def handle_gitlab_client_exceptions
|
|
18
|
+
def handle_gitlab_client_exceptions
|
|
19
19
|
yield
|
|
20
20
|
rescue Gitlab::Error::NotFound
|
|
21
21
|
# This error could be raised in assert_user_permission!
|
|
22
22
|
# If so, we want it to terminate at that point
|
|
23
23
|
raise
|
|
24
24
|
rescue SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout,
|
|
25
|
-
Gitlab::Error::InternalServerError, Gitlab::Error::Parsing => e
|
|
25
|
+
Gitlab::Error::InternalServerError, Gitlab::Error::BadRequest, Gitlab::Error::ResponseError, Gitlab::Error::Parsing => e
|
|
26
26
|
@retry_backoff += RETRY_BACK_OFF_DELAY
|
|
27
27
|
|
|
28
28
|
raise if @retry_backoff > RETRY_BACK_OFF_DELAY * MAX_RETRY_ATTEMPTS
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
warn("#{error.class.name} #{error.message}")
|
|
31
31
|
warn("Sleeping for #{@retry_backoff} seconds before retrying...")
|
|
32
32
|
sleep @retry_backoff
|
|
33
33
|
|
|
34
34
|
retry
|
|
35
35
|
rescue StandardError => e
|
|
36
|
+
post_exception_to_slack(e) if Runtime::Env.ci_commit_ref_name == Runtime::Env.default_branch
|
|
37
|
+
|
|
38
|
+
raise e
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def post_exception_to_slack(error)
|
|
42
|
+
return unless ENV['CI_SLACK_WEBHOOK_URL']
|
|
43
|
+
|
|
36
44
|
pipeline = Runtime::Env.pipeline_from_project_name
|
|
37
45
|
channel = case pipeline
|
|
38
46
|
when "canary"
|
|
@@ -42,9 +50,6 @@ module GitlabQuality
|
|
|
42
50
|
else
|
|
43
51
|
"qa-#{pipeline}"
|
|
44
52
|
end
|
|
45
|
-
error_msg = warn_exception(e)
|
|
46
|
-
|
|
47
|
-
return unless Runtime::Env.ci_commit_ref_name == Runtime::Env.default_branch
|
|
48
53
|
|
|
49
54
|
slack_options = {
|
|
50
55
|
slack_webhook_url: ENV.fetch('CI_SLACK_WEBHOOK_URL', nil),
|
|
@@ -54,7 +59,7 @@ module GitlabQuality
|
|
|
54
59
|
message: <<~MSG
|
|
55
60
|
An unexpected error occurred while reporting test results in issues.
|
|
56
61
|
The error occurred in job: #{Runtime::Env.ci_job_url}
|
|
57
|
-
`#{
|
|
62
|
+
`#{error.class.name} #{error.message}`
|
|
58
63
|
MSG
|
|
59
64
|
}
|
|
60
65
|
puts "Posting Slack message to channel: #{channel}"
|
|
@@ -79,12 +84,6 @@ module GitlabQuality
|
|
|
79
84
|
private_token: token
|
|
80
85
|
)
|
|
81
86
|
end
|
|
82
|
-
|
|
83
|
-
def warn_exception(error)
|
|
84
|
-
error_msg = "#{error.class.name} #{error.message}"
|
|
85
|
-
warn(error_msg)
|
|
86
|
-
error_msg
|
|
87
|
-
end
|
|
88
87
|
end
|
|
89
88
|
end
|
|
90
89
|
end
|
|
@@ -48,6 +48,12 @@ module GitlabQuality
|
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def find_issue_notes(iid:)
|
|
52
|
+
handle_gitlab_client_exceptions do
|
|
53
|
+
client.issue_notes(project, iid, order_by: 'created_at', sort: 'asc').auto_paginate
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
51
57
|
def find_issue_discussions(iid:)
|
|
52
58
|
handle_gitlab_client_exceptions do
|
|
53
59
|
client.issue_discussions(project, iid, order_by: 'created_at', sort: 'asc').auto_paginate
|
|
@@ -75,12 +81,6 @@ module GitlabQuality
|
|
|
75
81
|
end
|
|
76
82
|
end
|
|
77
83
|
|
|
78
|
-
def find_issue_notes(iid:)
|
|
79
|
-
handle_gitlab_client_exceptions do
|
|
80
|
-
client.issue_notes(project, iid, order_by: 'created_at', sort: 'asc')&.auto_paginate
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
84
|
def create_issue_note(iid:, note:)
|
|
85
85
|
handle_gitlab_client_exceptions do
|
|
86
86
|
client.create_issue_note(project, iid, note)
|
|
@@ -5,10 +5,12 @@ module GitlabQuality
|
|
|
5
5
|
module GitlabClient
|
|
6
6
|
class MergeRequestsClient < GitlabClient
|
|
7
7
|
def find_merge_request_changes(merge_request_iid:)
|
|
8
|
-
|
|
8
|
+
handle_gitlab_client_exceptions do
|
|
9
|
+
client.merge_request_changes(project, merge_request_iid)
|
|
10
|
+
end
|
|
9
11
|
end
|
|
10
12
|
|
|
11
|
-
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id: nil)
|
|
13
|
+
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id: nil, reviewer_ids: [])
|
|
12
14
|
attrs = {
|
|
13
15
|
source_branch: source_branch,
|
|
14
16
|
target_branch: target_branch,
|
|
@@ -16,7 +18,8 @@ module GitlabQuality
|
|
|
16
18
|
labels: labels,
|
|
17
19
|
assignee_id: assignee_id,
|
|
18
20
|
squash: true,
|
|
19
|
-
remove_source_branch: true
|
|
21
|
+
remove_source_branch: true,
|
|
22
|
+
reviewer_ids: reviewer_ids
|
|
20
23
|
}.compact
|
|
21
24
|
|
|
22
25
|
merge_request = handle_gitlab_client_exceptions do
|
|
@@ -26,9 +26,11 @@ module GitlabQuality
|
|
|
26
26
|
puts "The following note would have been updated id: #{id} with body: #{note} for mr_iid: #{merge_request_iid}"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:)
|
|
29
|
+
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id:, reviewer_ids:)
|
|
30
30
|
puts "A merge request would be created with title: #{title} " \
|
|
31
|
-
"source_branch: #{source_branch} target_branch: #{target_branch}
|
|
31
|
+
"source_branch: #{source_branch} target_branch: #{target_branch} " \
|
|
32
|
+
"description: #{description} labels: #{labels}, assignee_id: #{assignee_id}" \
|
|
33
|
+
"reviewer_ids: #{reviewer_ids}"
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
end
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_support/core_ext/object/blank'
|
|
4
|
+
|
|
3
5
|
module GitlabQuality
|
|
4
6
|
module TestTooling
|
|
5
7
|
module Report
|
|
6
8
|
module Concerns
|
|
7
9
|
module IssueReports
|
|
8
|
-
JOB_URL_REGEX
|
|
10
|
+
JOB_URL_REGEX = %r{(?<job_url>https://(?<host>[\w.]+)/(?<project_path>[\w\-./]+)/-/jobs/\d+)}
|
|
9
11
|
FAILED_JOB_DESCRIPTION_REGEX = /First happened in #{JOB_URL_REGEX}\./m
|
|
10
|
-
REPORT_ITEM_REGEX
|
|
12
|
+
REPORT_ITEM_REGEX = /^1\. \d{4}-\d{2}-\d{2}: #{JOB_URL_REGEX} \((?<pipeline_url>\S+)\)/
|
|
13
|
+
LATEST_REPORTS_TO_SHOW = 10
|
|
11
14
|
|
|
12
15
|
def initial_reports_section(test)
|
|
13
16
|
<<~REPORTS
|
|
@@ -17,22 +20,21 @@ module GitlabQuality
|
|
|
17
20
|
REPORTS
|
|
18
21
|
end
|
|
19
22
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.scan(REPORT_ITEM_REGEX)
|
|
29
|
-
.size.to_i + 1
|
|
30
|
-
issue_description.sub(/^### Reports.*$/, "### Reports (#{reports_count})")
|
|
31
|
-
else # For issue with the legacy format, we add the Reports section
|
|
32
|
-
update_legacy_issue_description(issue_description)
|
|
33
|
-
end
|
|
23
|
+
def increment_reports(
|
|
24
|
+
current_reports_content:,
|
|
25
|
+
test:,
|
|
26
|
+
reports_section_header: '### Reports',
|
|
27
|
+
item_extra_content: nil,
|
|
28
|
+
reports_extra_content: nil)
|
|
29
|
+
preserved_content = current_reports_content.split(reports_section_header).first&.strip
|
|
30
|
+
reports = report_lines(current_reports_content) + [report_list_item(test, item_extra_content: item_extra_content)]
|
|
34
31
|
|
|
35
|
-
[
|
|
32
|
+
[
|
|
33
|
+
preserved_content,
|
|
34
|
+
"#{reports_section_header} (#{reports.size})",
|
|
35
|
+
reports_list(reports),
|
|
36
|
+
reports_extra_content
|
|
37
|
+
].reject(&:blank?).compact.join("\n\n")
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
def failed_issue_job_url(issue)
|
|
@@ -49,8 +51,28 @@ module GitlabQuality
|
|
|
49
51
|
|
|
50
52
|
private
|
|
51
53
|
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
+
def report_lines(content)
|
|
55
|
+
content.lines.grep(REPORT_ITEM_REGEX).map(&:strip)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def reports_list(reports)
|
|
59
|
+
sorted_reports = reports.sort.reverse
|
|
60
|
+
|
|
61
|
+
if sorted_reports.size > LATEST_REPORTS_TO_SHOW
|
|
62
|
+
[
|
|
63
|
+
"Last 10 reports:",
|
|
64
|
+
sorted_reports[...LATEST_REPORTS_TO_SHOW].join("\n"),
|
|
65
|
+
"<details><summary>See #{sorted_reports.size - LATEST_REPORTS_TO_SHOW} more reports</summary>",
|
|
66
|
+
sorted_reports[LATEST_REPORTS_TO_SHOW..].join("\n"),
|
|
67
|
+
"</details>"
|
|
68
|
+
].join("\n\n")
|
|
69
|
+
else
|
|
70
|
+
sorted_reports.join("\n")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def report_list_item(test, item_extra_content: nil)
|
|
75
|
+
"1. #{Time.new.utc.strftime('%F')}: #{test.ci_job_url} (#{ENV.fetch('CI_PIPELINE_URL', 'pipeline url is missing')}) #{item_extra_content}".strip
|
|
54
76
|
end
|
|
55
77
|
|
|
56
78
|
def job_urls_from_description(issue_description, regex)
|
|
@@ -60,15 +82,6 @@ module GitlabQuality
|
|
|
60
82
|
end
|
|
61
83
|
end
|
|
62
84
|
|
|
63
|
-
def update_legacy_issue_description(issue_description)
|
|
64
|
-
test_captures = issue_description.scan(JOB_URL_REGEX)
|
|
65
|
-
reports_count = test_captures.size.to_i + 1
|
|
66
|
-
|
|
67
|
-
updated_description = "#{issue_description}\n\n### Reports (#{reports_count})\n"
|
|
68
|
-
updated_description = [updated_description, *test_captures_to_report_items(test_captures)].join("\n") unless test_captures.empty?
|
|
69
|
-
updated_description
|
|
70
|
-
end
|
|
71
|
-
|
|
72
85
|
def test_captures_to_report_items(test_captures)
|
|
73
86
|
test_captures.map do |ci_job_url, _, _|
|
|
74
87
|
report_list_item(GitlabQuality::TestTooling::TestResult::JsonTestResult.new(
|