gitlab_quality-test_tooling 3.22.0 → 3.23.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 +71 -60
- data/README.md +1 -0
- data/exe/post-to-slack +5 -0
- data/lib/gitlab_quality/test_tooling/code_coverage/click_house/test_health_risk_aggregation.sql +14 -14
- data/lib/gitlab_quality/test_tooling/code_coverage/click_house/test_health_risk_aggregator.rb +3 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/gitlab_client.rb +5 -1
- data/lib/gitlab_quality/test_tooling/report/report_as_issue.rb +1 -1
- data/lib/gitlab_quality/test_tooling/slack/post_to_slack.rb +29 -2
- data/lib/gitlab_quality/test_tooling/test_meta/test_meta_updater.rb +1 -0
- data/lib/gitlab_quality/test_tooling/version.rb +1 -1
- metadata +20 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 635939993ec2f8ac5d2593a070f8494cf9953510c3d2b1f659a86afadd57ff66
|
|
4
|
+
data.tar.gz: 7a75e161d96b24793411864ab93a467bad63bab716d2b1e2a5d1ab272583a9b9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47a4fb04a69850d455d1dde34a2fdf3026183590d839301c07bad0685c41a8c244e128a40006dd7b90fcf83175e873b01f258945073d03e1cc9c77fe3ee6f37a
|
|
7
|
+
data.tar.gz: bf09187090fd25886a6c4a0eb320b1d431db0df8a6eca497f09b178245ffb9c229a8ba0c84107016a036eb5f095b01e709dfadc136a0393864ef1b45445df65d
|
data/Gemfile.lock
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
gitlab_quality-test_tooling (3.
|
|
4
|
+
gitlab_quality-test_tooling (3.23.0)
|
|
5
5
|
activesupport (>= 7.0)
|
|
6
6
|
amatch (~> 0.4.1)
|
|
7
|
+
csv (~> 3.0)
|
|
7
8
|
fog-google (~> 1.25)
|
|
8
9
|
gitlab (>= 4.19, < 7.0)
|
|
9
10
|
http (~> 5.0)
|
|
@@ -18,30 +19,33 @@ PATH
|
|
|
18
19
|
GEM
|
|
19
20
|
remote: https://rubygems.org/
|
|
20
21
|
specs:
|
|
21
|
-
activesupport (7.
|
|
22
|
+
activesupport (7.2.4)
|
|
22
23
|
base64
|
|
24
|
+
benchmark (>= 0.3)
|
|
23
25
|
bigdecimal
|
|
24
|
-
concurrent-ruby (~> 1.0, >= 1.
|
|
25
|
-
connection_pool (>= 2.2.5)
|
|
26
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
27
|
+
connection_pool (>= 2.2.5, < 3)
|
|
26
28
|
drb
|
|
27
29
|
i18n (>= 1.6, < 2)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
logger (>= 1.4.2)
|
|
31
|
+
minitest (>= 5.1, < 6)
|
|
32
|
+
securerandom (>= 0.3)
|
|
33
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
34
|
+
addressable (2.9.0)
|
|
35
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
33
36
|
amatch (0.4.1)
|
|
34
37
|
mize
|
|
35
38
|
tins (~> 1.0)
|
|
36
39
|
ast (2.4.2)
|
|
37
40
|
backport (1.2.0)
|
|
38
|
-
base64 (0.
|
|
41
|
+
base64 (0.3.0)
|
|
39
42
|
benchmark (0.3.0)
|
|
40
|
-
bigdecimal (
|
|
43
|
+
bigdecimal (4.1.3)
|
|
41
44
|
binding_of_caller (1.0.1)
|
|
42
45
|
debug_inspector (>= 1.2.0)
|
|
43
46
|
builder (3.3.0)
|
|
44
|
-
byebug (
|
|
47
|
+
byebug (13.0.0)
|
|
48
|
+
reline (>= 0.6.0)
|
|
45
49
|
claide (1.1.0)
|
|
46
50
|
claide-plugins (0.9.2)
|
|
47
51
|
cork
|
|
@@ -50,14 +54,14 @@ GEM
|
|
|
50
54
|
climate_control (1.2.0)
|
|
51
55
|
coderay (1.1.3)
|
|
52
56
|
colored2 (3.1.2)
|
|
53
|
-
concurrent-ruby (1.3.
|
|
54
|
-
connection_pool (2.
|
|
57
|
+
concurrent-ruby (1.3.8)
|
|
58
|
+
connection_pool (2.5.5)
|
|
55
59
|
cork (0.3.0)
|
|
56
60
|
colored2 (~> 3.1)
|
|
57
61
|
crack (1.0.0)
|
|
58
62
|
bigdecimal
|
|
59
63
|
rexml
|
|
60
|
-
csv (3.3.
|
|
64
|
+
csv (3.3.6)
|
|
61
65
|
danger (9.5.0)
|
|
62
66
|
claide (~> 1.0)
|
|
63
67
|
claide-plugins (>= 0.9.2)
|
|
@@ -78,18 +82,20 @@ GEM
|
|
|
78
82
|
diff-lcs (1.5.1)
|
|
79
83
|
docile (1.4.1)
|
|
80
84
|
domain_name (0.6.20240107)
|
|
81
|
-
drb (2.2.
|
|
85
|
+
drb (2.2.3)
|
|
82
86
|
e2mmap (0.1.0)
|
|
83
87
|
excon (1.6.0)
|
|
84
88
|
logger
|
|
85
|
-
faraday (2.
|
|
86
|
-
faraday-net_http (>= 2.0, < 3.
|
|
89
|
+
faraday (2.14.4)
|
|
90
|
+
faraday-net_http (>= 2.0, < 3.5)
|
|
87
91
|
json
|
|
88
92
|
logger
|
|
93
|
+
faraday-follow_redirects (0.5.0)
|
|
94
|
+
faraday (>= 1, < 3)
|
|
89
95
|
faraday-http-cache (2.5.1)
|
|
90
96
|
faraday (>= 0.8)
|
|
91
|
-
faraday-net_http (3.
|
|
92
|
-
net-http
|
|
97
|
+
faraday-net_http (3.4.4)
|
|
98
|
+
net-http (~> 0.5)
|
|
93
99
|
ffi (1.17.0)
|
|
94
100
|
ffi-compiler (1.3.2)
|
|
95
101
|
ffi (>= 1.15.5)
|
|
@@ -138,16 +144,17 @@ GEM
|
|
|
138
144
|
rubocop-rails (~> 2.26.0)
|
|
139
145
|
rubocop-rspec (~> 3.0.4)
|
|
140
146
|
rubocop-rspec_rails (~> 2.30.0)
|
|
141
|
-
google-apis-compute_v1 (0.
|
|
147
|
+
google-apis-compute_v1 (0.155.0)
|
|
142
148
|
google-apis-core (>= 0.15.0, < 2.a)
|
|
143
|
-
google-apis-core (
|
|
144
|
-
addressable (~> 2.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
google-apis-core (1.2.2)
|
|
150
|
+
addressable (~> 2.8, >= 2.8.7)
|
|
151
|
+
faraday (~> 2.13)
|
|
152
|
+
faraday-follow_redirects (~> 0.3)
|
|
153
|
+
googleauth (~> 1.14)
|
|
154
|
+
mini_mime (~> 1.1)
|
|
155
|
+
multi_json (~> 1.11)
|
|
149
156
|
representable (~> 3.0)
|
|
150
|
-
retriable (>=
|
|
157
|
+
retriable (>= 3.1, < 5.0)
|
|
151
158
|
google-apis-dns_v1 (0.44.0)
|
|
152
159
|
google-apis-core (>= 0.15.0, < 2.a)
|
|
153
160
|
google-apis-iamcredentials_v1 (0.21.0)
|
|
@@ -162,12 +169,14 @@ GEM
|
|
|
162
169
|
google-apis-core (>= 0.15.0, < 2.a)
|
|
163
170
|
google-cloud-env (2.2.1)
|
|
164
171
|
faraday (>= 1.0, < 3.a)
|
|
165
|
-
|
|
172
|
+
google-logging-utils (0.2.0)
|
|
173
|
+
googleauth (1.17.4)
|
|
166
174
|
faraday (>= 1.0, < 3.a)
|
|
167
|
-
google-cloud-env (~> 2.
|
|
168
|
-
|
|
169
|
-
|
|
175
|
+
google-cloud-env (~> 2.2)
|
|
176
|
+
google-logging-utils (~> 0.1)
|
|
177
|
+
jwt (>= 1.4, < 4.0)
|
|
170
178
|
os (>= 0.9, < 2.0)
|
|
179
|
+
pstore (~> 0.1)
|
|
171
180
|
signet (>= 0.16, < 2.a)
|
|
172
181
|
guard (2.18.1)
|
|
173
182
|
formatador (>= 0.2.4)
|
|
@@ -194,16 +203,16 @@ GEM
|
|
|
194
203
|
http-cookie (1.0.7)
|
|
195
204
|
domain_name (~> 0.5)
|
|
196
205
|
http-form_data (2.3.0)
|
|
197
|
-
httparty (0.
|
|
206
|
+
httparty (0.24.3)
|
|
198
207
|
csv
|
|
199
208
|
mini_mime (>= 1.0.0)
|
|
200
209
|
multi_xml (>= 0.5.2)
|
|
201
|
-
|
|
202
|
-
i18n (1.14.6)
|
|
210
|
+
i18n (1.15.2)
|
|
203
211
|
concurrent-ruby (~> 1.0)
|
|
212
|
+
io-console (0.9.4)
|
|
204
213
|
jaro_winkler (1.6.0)
|
|
205
|
-
json (2.
|
|
206
|
-
jwt (
|
|
214
|
+
json (2.21.2)
|
|
215
|
+
jwt (3.3.0)
|
|
207
216
|
base64
|
|
208
217
|
kramdown (2.4.0)
|
|
209
218
|
rexml
|
|
@@ -217,7 +226,7 @@ GEM
|
|
|
217
226
|
llhttp-ffi (0.5.0)
|
|
218
227
|
ffi-compiler (~> 1.0)
|
|
219
228
|
rake (~> 13.0)
|
|
220
|
-
logger (1.
|
|
229
|
+
logger (1.7.0)
|
|
221
230
|
lumberjack (1.2.10)
|
|
222
231
|
method_source (1.1.0)
|
|
223
232
|
mime-types (3.6.0)
|
|
@@ -225,19 +234,18 @@ GEM
|
|
|
225
234
|
mime-types-data (~> 3.2015)
|
|
226
235
|
mime-types-data (3.2024.1001)
|
|
227
236
|
mini_mime (1.1.5)
|
|
228
|
-
mini_portile2 (2.8.
|
|
229
|
-
minitest (5.
|
|
237
|
+
mini_portile2 (2.8.9)
|
|
238
|
+
minitest (5.27.0)
|
|
230
239
|
mize (0.6.0)
|
|
231
240
|
multi_json (1.15.0)
|
|
232
|
-
multi_xml (0.
|
|
233
|
-
bigdecimal (
|
|
234
|
-
mutex_m (0.2.0)
|
|
241
|
+
multi_xml (0.9.1)
|
|
242
|
+
bigdecimal (>= 3.1, < 5)
|
|
235
243
|
nap (1.1.0)
|
|
236
244
|
nenv (0.3.0)
|
|
237
|
-
net-http (0.
|
|
238
|
-
uri
|
|
245
|
+
net-http (0.9.1)
|
|
246
|
+
uri (>= 0.11.1)
|
|
239
247
|
netrc (0.11.0)
|
|
240
|
-
nokogiri (1.
|
|
248
|
+
nokogiri (1.19.4)
|
|
241
249
|
mini_portile2 (~> 2.8.2)
|
|
242
250
|
racc (~> 1.4)
|
|
243
251
|
notiffany (0.1.3)
|
|
@@ -259,12 +267,13 @@ GEM
|
|
|
259
267
|
pry (0.14.2)
|
|
260
268
|
coderay (~> 1.1)
|
|
261
269
|
method_source (~> 1.0)
|
|
262
|
-
pry-byebug (3.
|
|
263
|
-
byebug (~>
|
|
264
|
-
pry (>= 0.13, < 0.
|
|
265
|
-
|
|
270
|
+
pry-byebug (3.12.0)
|
|
271
|
+
byebug (~> 13.0)
|
|
272
|
+
pry (>= 0.13, < 0.17)
|
|
273
|
+
pstore (0.2.1)
|
|
274
|
+
public_suffix (7.0.5)
|
|
266
275
|
racc (1.8.1)
|
|
267
|
-
rack (3.2.
|
|
276
|
+
rack (3.2.7)
|
|
268
277
|
rainbow (3.1.1)
|
|
269
278
|
rake (13.2.1)
|
|
270
279
|
rb-fsevent (0.11.2)
|
|
@@ -273,6 +282,8 @@ GEM
|
|
|
273
282
|
rbs (2.8.4)
|
|
274
283
|
rchardet (1.8.0)
|
|
275
284
|
regexp_parser (2.11.2)
|
|
285
|
+
reline (0.7.0)
|
|
286
|
+
io-console (~> 0.5)
|
|
276
287
|
representable (3.2.0)
|
|
277
288
|
declarative (< 0.1.0)
|
|
278
289
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
|
@@ -285,7 +296,7 @@ GEM
|
|
|
285
296
|
retriable (3.1.2)
|
|
286
297
|
reverse_markdown (2.1.1)
|
|
287
298
|
nokogiri
|
|
288
|
-
rexml (3.
|
|
299
|
+
rexml (3.4.4)
|
|
289
300
|
rouge (4.4.0)
|
|
290
301
|
rspec (3.13.0)
|
|
291
302
|
rspec-core (~> 3.13.0)
|
|
@@ -348,12 +359,12 @@ GEM
|
|
|
348
359
|
sawyer (0.9.2)
|
|
349
360
|
addressable (>= 2.3.5)
|
|
350
361
|
faraday (>= 0.17.3, < 3)
|
|
362
|
+
securerandom (0.4.1)
|
|
351
363
|
shellany (0.0.1)
|
|
352
|
-
signet (0.
|
|
364
|
+
signet (0.22.0)
|
|
353
365
|
addressable (~> 2.8)
|
|
354
366
|
faraday (>= 0.17.5, < 3.a)
|
|
355
|
-
jwt (>= 1.5, <
|
|
356
|
-
multi_json (~> 1.10)
|
|
367
|
+
jwt (>= 1.5, < 4.0)
|
|
357
368
|
simplecov (0.22.0)
|
|
358
369
|
docile (~> 1.1)
|
|
359
370
|
simplecov-html (~> 0.11)
|
|
@@ -397,9 +408,9 @@ GEM
|
|
|
397
408
|
unparser (0.6.15)
|
|
398
409
|
diff-lcs (~> 1.3)
|
|
399
410
|
parser (>= 3.3.0)
|
|
400
|
-
uri (
|
|
401
|
-
webmock (3.
|
|
402
|
-
addressable (>= 2.
|
|
411
|
+
uri (1.1.1)
|
|
412
|
+
webmock (3.26.4)
|
|
413
|
+
addressable (>= 2.8.0)
|
|
403
414
|
crack (>= 0.3.2)
|
|
404
415
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
405
416
|
yard (0.9.37)
|
|
@@ -416,7 +427,7 @@ DEPENDENCIES
|
|
|
416
427
|
gitlab_quality-test_tooling!
|
|
417
428
|
guard-rspec (~> 4.7)
|
|
418
429
|
lefthook (~> 1.3)
|
|
419
|
-
pry-byebug (= 3.
|
|
430
|
+
pry-byebug (= 3.12.0)
|
|
420
431
|
rake (~> 13.0)
|
|
421
432
|
rest-client (~> 2.1.0)
|
|
422
433
|
rspec (~> 3.12)
|
|
@@ -425,7 +436,7 @@ DEPENDENCIES
|
|
|
425
436
|
simplecov-cobertura (~> 2.1)
|
|
426
437
|
solargraph (~> 0.41)
|
|
427
438
|
timecop (~> 0.9.5)
|
|
428
|
-
webmock (= 3.
|
|
439
|
+
webmock (= 3.26.4)
|
|
429
440
|
|
|
430
441
|
BUNDLED WITH
|
|
431
442
|
2.7.2
|
data/README.md
CHANGED
|
@@ -51,6 +51,7 @@ Purpose: Post a message to Slack, and optionally add a test summary table based
|
|
|
51
51
|
Usage: exe/post-to-slack [options]
|
|
52
52
|
-w SLACK_WEBHOOK_URL, Slack webhook URL
|
|
53
53
|
--slack-webhook-url
|
|
54
|
+
-b, --slack-bot-token TOKEN Slack bot token, used instead of the webhook URL when set
|
|
54
55
|
-c, --channel CHANNEL Slack channel to post the message to
|
|
55
56
|
-m, --message MESSAGE Post message to Slack
|
|
56
57
|
-t FILES, Add a test summary table based on RSpec report files (JUnit XML)
|
data/exe/post-to-slack
CHANGED
|
@@ -19,6 +19,11 @@ options = OptionParser.new do |opts|
|
|
|
19
19
|
params[:slack_webhook_url] = slack_webhook_url
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
# No String type: OptionParser's String rejects "", and CI passes an unset variable as "".
|
|
23
|
+
opts.on('-b', '--slack-bot-token TOKEN', 'Slack bot token, used instead of the webhook URL when set') do |token|
|
|
24
|
+
params[:slack_bot_token] = token unless token.empty?
|
|
25
|
+
end
|
|
26
|
+
|
|
22
27
|
opts.on('-a', '--gitlab-api-token TOKEN', String, 'GitLab API token') do |token|
|
|
23
28
|
gitlab_api_token = token unless token.empty?
|
|
24
29
|
end
|
data/lib/gitlab_quality/test_tooling/code_coverage/click_house/test_health_risk_aggregation.sql
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
-- Parameters use `{name}` braces, substituted as literal text by gsub in
|
|
10
10
|
-- TestHealthRiskAggregator#build_sql after validation. A typoed placeholder
|
|
11
11
|
-- silently survives gsub, so match the names exactly.
|
|
12
|
-
-- {snapshot_date}
|
|
13
|
-
-- {coverage_start}
|
|
14
|
-
-- {risk_window}
|
|
12
|
+
-- {snapshot_date} date stamp for this run
|
|
13
|
+
-- {coverage_start} day of the most recent full per-test capture
|
|
14
|
+
-- {risk_window} flaky and ownership lookback, default '30 DAY'
|
|
15
|
+
-- {quarantine_window} default-branch quarantine lookback, fixed at '3 DAY'
|
|
15
16
|
--
|
|
16
17
|
-- The INSERT is unconditional. Idempotency comes from the target table's
|
|
17
18
|
-- ReplacingMergeTree(version) engine keyed by the row tuple: re-runs and
|
|
@@ -26,17 +27,16 @@
|
|
|
26
27
|
INSERT INTO code_coverage.test_health_risk_per_group
|
|
27
28
|
WITH
|
|
28
29
|
quarantine_status AS (
|
|
29
|
-
--
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
--
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
HAVING is_quarantined
|
|
30
|
+
-- The same source and window the Quarantine score counts from, so both
|
|
31
|
+
-- agree on which specs are quarantined. The MV keeps default-branch
|
|
32
|
+
-- pipelines only; test_file_quarantine_summary also counts stable-branch
|
|
33
|
+
-- and backport pipelines, which keep a spec quarantined long after master
|
|
34
|
+
-- has fixed it.
|
|
35
|
+
SELECT DISTINCT
|
|
36
|
+
file_path AS test_file,
|
|
37
|
+
TRUE AS is_quarantined
|
|
38
|
+
FROM test_metrics.quarantined_tests_hourly_mv
|
|
39
|
+
WHERE hour_timestamp >= now() - INTERVAL {quarantine_window}
|
|
40
40
|
),
|
|
41
41
|
flaky_status AS (
|
|
42
42
|
SELECT
|
data/lib/gitlab_quality/test_tooling/code_coverage/click_house/test_health_risk_aggregator.rb
CHANGED
|
@@ -39,6 +39,8 @@ module GitlabQuality
|
|
|
39
39
|
# denominator built from sparse data.
|
|
40
40
|
DEFAULT_ANCHOR_LOOKBACK = '21 DAY'
|
|
41
41
|
DEFAULT_RISK_WINDOW = '30 DAY'
|
|
42
|
+
# Must match the Quarantine score's window in the runbooks Test Health views.
|
|
43
|
+
QUARANTINE_WINDOW = '3 DAY'
|
|
42
44
|
|
|
43
45
|
# `snapshot_date` is YYYY-MM-DD; intervals are `<integer> <unit>`
|
|
44
46
|
# (singular or plural).
|
|
@@ -126,6 +128,7 @@ module GitlabQuality
|
|
|
126
128
|
.gsub('{snapshot_date}', validate_date(snapshot_date))
|
|
127
129
|
.gsub('{coverage_start}', coverage_start)
|
|
128
130
|
.gsub('{risk_window}', validate_interval(risk_window))
|
|
131
|
+
.gsub('{quarantine_window}', QUARANTINE_WINDOW)
|
|
129
132
|
end
|
|
130
133
|
|
|
131
134
|
# DateTime/Time `to_s` includes the time portion and is rejected.
|
|
@@ -40,13 +40,14 @@ module GitlabQuality
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def post_exception_to_slack(error)
|
|
43
|
-
return
|
|
43
|
+
return if ENV.values_at('CI_SLACK_BOT_TOKEN', 'CI_SLACK_WEBHOOK_URL').all? { |value| value.to_s.empty? }
|
|
44
44
|
|
|
45
45
|
pipeline = Runtime::Env.pipeline_from_project_name
|
|
46
46
|
channel = Runtime::Env.slack_alerts_channel
|
|
47
47
|
|
|
48
48
|
slack_options = {
|
|
49
49
|
slack_webhook_url: ENV.fetch('CI_SLACK_WEBHOOK_URL', nil),
|
|
50
|
+
slack_bot_token: ENV.fetch('CI_SLACK_BOT_TOKEN', nil),
|
|
50
51
|
channel: channel,
|
|
51
52
|
username: "GitLab Quality Test Tooling",
|
|
52
53
|
icon_emoji: ':ci_failing:',
|
|
@@ -59,6 +60,9 @@ module GitlabQuality
|
|
|
59
60
|
puts "Posting Slack message to channel: #{channel}"
|
|
60
61
|
|
|
61
62
|
GitlabQuality::TestTooling::Slack::PostToSlack.new(**slack_options).invoke!
|
|
63
|
+
# The caller re-raises the GitLab error after this, so a failed alert must not replace it.
|
|
64
|
+
rescue StandardError => e
|
|
65
|
+
warn("Failed to post the error to Slack: #{e.message}")
|
|
62
66
|
end
|
|
63
67
|
|
|
64
68
|
def ignore_gitlab_client_exceptions
|
|
@@ -122,7 +122,7 @@ module GitlabQuality
|
|
|
122
122
|
issue_attrs = {}
|
|
123
123
|
|
|
124
124
|
new_description = new_issue_description(test)
|
|
125
|
-
issue_attrs[:description] = new_description
|
|
125
|
+
issue_attrs[:description] = new_description unless issue.description.to_s.include?(new_description.strip)
|
|
126
126
|
|
|
127
127
|
new_labels = up_to_date_labels(test: test, issue: issue).to_a
|
|
128
128
|
issue_attrs[:add_labels] = new_labels if (new_labels - issue.labels).any?
|
|
@@ -8,9 +8,12 @@ module GitlabQuality
|
|
|
8
8
|
class PostToSlack
|
|
9
9
|
MAX_PATTERN_MESSAGE_LENGTH = 150
|
|
10
10
|
MAX_GROUPED_FAILURES_TO_DISPLAY = 10
|
|
11
|
+
POST_MESSAGE_URL = 'https://slack.com/api/chat.postMessage'
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
# Posts with slack_bot_token when it is set and not empty, otherwise to slack_webhook_url.
|
|
14
|
+
def initialize(channel:, message:, username:, icon_emoji:, slack_webhook_url: nil, slack_bot_token: nil, environment_issues_file: nil)
|
|
13
15
|
@slack_webhook_url = slack_webhook_url
|
|
16
|
+
@slack_bot_token = slack_bot_token
|
|
14
17
|
@channel = channel
|
|
15
18
|
@message = message
|
|
16
19
|
@username = username
|
|
@@ -25,6 +28,8 @@ module GitlabQuality
|
|
|
25
28
|
params['icon_emoji'] = icon_emoji
|
|
26
29
|
params['text'] = build_message
|
|
27
30
|
|
|
31
|
+
return post_with_token(params) unless slack_bot_token.to_s.empty?
|
|
32
|
+
|
|
28
33
|
Support::HttpRequest.make_http_request(
|
|
29
34
|
method: 'post',
|
|
30
35
|
url: slack_webhook_url,
|
|
@@ -35,7 +40,29 @@ module GitlabQuality
|
|
|
35
40
|
|
|
36
41
|
private
|
|
37
42
|
|
|
38
|
-
attr_reader :slack_webhook_url, :channel, :message, :username, :icon_emoji, :environment_issues_file
|
|
43
|
+
attr_reader :slack_webhook_url, :slack_bot_token, :channel, :message, :username, :icon_emoji, :environment_issues_file
|
|
44
|
+
|
|
45
|
+
# chat.postMessage answers HTTP 200 with {"ok":false,...} on errors, so the body decides.
|
|
46
|
+
def post_with_token(params)
|
|
47
|
+
response = Support::HttpRequest.make_http_request(
|
|
48
|
+
method: 'post',
|
|
49
|
+
url: POST_MESSAGE_URL,
|
|
50
|
+
params: params,
|
|
51
|
+
headers: { 'Authorization' => "Bearer #{slack_bot_token}" },
|
|
52
|
+
show_response: true
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
raise "Slack did not accept the message: #{response.body}" unless accepted?(response.body.to_s)
|
|
56
|
+
|
|
57
|
+
response
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def accepted?(body)
|
|
61
|
+
parsed = JSON.parse(body)
|
|
62
|
+
parsed.is_a?(Hash) && parsed['ok'] == true
|
|
63
|
+
rescue JSON::ParserError
|
|
64
|
+
false
|
|
65
|
+
end
|
|
39
66
|
|
|
40
67
|
def build_message
|
|
41
68
|
messages = []
|
|
@@ -295,6 +295,7 @@ module GitlabQuality
|
|
|
295
295
|
channel = Runtime::Env.slack_alerts_channel
|
|
296
296
|
slack_options = {
|
|
297
297
|
slack_webhook_url: ENV.fetch('CI_SLACK_WEBHOOK_URL', nil),
|
|
298
|
+
slack_bot_token: ENV.fetch('CI_SLACK_BOT_TOKEN', nil),
|
|
298
299
|
channel: channel,
|
|
299
300
|
username: "GitLab Quality Test Tooling",
|
|
300
301
|
icon_emoji: ':warning:',
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gitlab_quality-test_tooling
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.23.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: 2026-
|
|
11
|
+
date: 2026-10-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: climate_control
|
|
@@ -86,14 +86,14 @@ dependencies:
|
|
|
86
86
|
requirements:
|
|
87
87
|
- - '='
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 3.
|
|
89
|
+
version: 3.12.0
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - '='
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 3.
|
|
96
|
+
version: 3.12.0
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: rake
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -212,14 +212,14 @@ dependencies:
|
|
|
212
212
|
requirements:
|
|
213
213
|
- - '='
|
|
214
214
|
- !ruby/object:Gem::Version
|
|
215
|
-
version: 3.
|
|
215
|
+
version: 3.26.4
|
|
216
216
|
type: :development
|
|
217
217
|
prerelease: false
|
|
218
218
|
version_requirements: !ruby/object:Gem::Requirement
|
|
219
219
|
requirements:
|
|
220
220
|
- - '='
|
|
221
221
|
- !ruby/object:Gem::Version
|
|
222
|
-
version: 3.
|
|
222
|
+
version: 3.26.4
|
|
223
223
|
- !ruby/object:Gem::Dependency
|
|
224
224
|
name: activesupport
|
|
225
225
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -248,6 +248,20 @@ dependencies:
|
|
|
248
248
|
- - "~>"
|
|
249
249
|
- !ruby/object:Gem::Version
|
|
250
250
|
version: 0.4.1
|
|
251
|
+
- !ruby/object:Gem::Dependency
|
|
252
|
+
name: csv
|
|
253
|
+
requirement: !ruby/object:Gem::Requirement
|
|
254
|
+
requirements:
|
|
255
|
+
- - "~>"
|
|
256
|
+
- !ruby/object:Gem::Version
|
|
257
|
+
version: '3.0'
|
|
258
|
+
type: :runtime
|
|
259
|
+
prerelease: false
|
|
260
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
261
|
+
requirements:
|
|
262
|
+
- - "~>"
|
|
263
|
+
- !ruby/object:Gem::Version
|
|
264
|
+
version: '3.0'
|
|
251
265
|
- !ruby/object:Gem::Dependency
|
|
252
266
|
name: fog-google
|
|
253
267
|
requirement: !ruby/object:Gem::Requirement
|