gitlab_quality-test_tooling 3.22.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 753fbf9038d32ba4c43b76dbeac70b9a7bec17cd58e62b92f1c6c6279c1105a6
4
- data.tar.gz: 6d10b736a6a40453ccc70edce8aad4c360a50df4d27a662cde93d38fd107de59
3
+ metadata.gz: 635939993ec2f8ac5d2593a070f8494cf9953510c3d2b1f659a86afadd57ff66
4
+ data.tar.gz: 7a75e161d96b24793411864ab93a467bad63bab716d2b1e2a5d1ab272583a9b9
5
5
  SHA512:
6
- metadata.gz: 54cd62d62cbcb29923e63ebafeccfa3911086a37220a59b16efe2d2b652587c598731360a827f79a27fe0a92f8e702c4943b3e03810c8e51ac1052d6a7bacba3
7
- data.tar.gz: 2991e98253c031c1cf0d98e04178d09c53f4c331e1b23c244e567cfcb79552da6c104f91fb3ad42c23284f0654bb192367823e7159db2c06c7aaa5d387c3757d
6
+ metadata.gz: 47a4fb04a69850d455d1dde34a2fdf3026183590d839301c07bad0685c41a8c244e128a40006dd7b90fcf83175e873b01f258945073d03e1cc9c77fe3ee6f37a
7
+ data.tar.gz: bf09187090fd25886a6c4a0eb320b1d431db0df8a6eca497f09b178245ffb9c229a8ba0c84107016a036eb5f095b01e709dfadc136a0393864ef1b45445df65d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab_quality-test_tooling (3.22.1)
4
+ gitlab_quality-test_tooling (3.23.0)
5
5
  activesupport (>= 7.0)
6
6
  amatch (~> 0.4.1)
7
7
  csv (~> 3.0)
@@ -19,30 +19,33 @@ PATH
19
19
  GEM
20
20
  remote: https://rubygems.org/
21
21
  specs:
22
- activesupport (7.1.4)
22
+ activesupport (7.2.4)
23
23
  base64
24
+ benchmark (>= 0.3)
24
25
  bigdecimal
25
- concurrent-ruby (~> 1.0, >= 1.0.2)
26
- connection_pool (>= 2.2.5)
26
+ concurrent-ruby (~> 1.0, >= 1.3.1)
27
+ connection_pool (>= 2.2.5, < 3)
27
28
  drb
28
29
  i18n (>= 1.6, < 2)
29
- minitest (>= 5.1)
30
- mutex_m
31
- tzinfo (~> 2.0)
32
- addressable (2.8.7)
33
- public_suffix (>= 2.0.2, < 7.0)
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)
34
36
  amatch (0.4.1)
35
37
  mize
36
38
  tins (~> 1.0)
37
39
  ast (2.4.2)
38
40
  backport (1.2.0)
39
- base64 (0.2.0)
41
+ base64 (0.3.0)
40
42
  benchmark (0.3.0)
41
- bigdecimal (3.1.8)
43
+ bigdecimal (4.1.3)
42
44
  binding_of_caller (1.0.1)
43
45
  debug_inspector (>= 1.2.0)
44
46
  builder (3.3.0)
45
- byebug (11.1.3)
47
+ byebug (13.0.0)
48
+ reline (>= 0.6.0)
46
49
  claide (1.1.0)
47
50
  claide-plugins (0.9.2)
48
51
  cork
@@ -51,14 +54,14 @@ GEM
51
54
  climate_control (1.2.0)
52
55
  coderay (1.1.3)
53
56
  colored2 (3.1.2)
54
- concurrent-ruby (1.3.4)
55
- connection_pool (2.4.1)
57
+ concurrent-ruby (1.3.8)
58
+ connection_pool (2.5.5)
56
59
  cork (0.3.0)
57
60
  colored2 (~> 3.1)
58
61
  crack (1.0.0)
59
62
  bigdecimal
60
63
  rexml
61
- csv (3.3.0)
64
+ csv (3.3.6)
62
65
  danger (9.5.0)
63
66
  claide (~> 1.0)
64
67
  claide-plugins (>= 0.9.2)
@@ -79,18 +82,20 @@ GEM
79
82
  diff-lcs (1.5.1)
80
83
  docile (1.4.1)
81
84
  domain_name (0.6.20240107)
82
- drb (2.2.1)
85
+ drb (2.2.3)
83
86
  e2mmap (0.1.0)
84
87
  excon (1.6.0)
85
88
  logger
86
- faraday (2.12.0)
87
- faraday-net_http (>= 2.0, < 3.4)
89
+ faraday (2.14.4)
90
+ faraday-net_http (>= 2.0, < 3.5)
88
91
  json
89
92
  logger
93
+ faraday-follow_redirects (0.5.0)
94
+ faraday (>= 1, < 3)
90
95
  faraday-http-cache (2.5.1)
91
96
  faraday (>= 0.8)
92
- faraday-net_http (3.3.0)
93
- net-http
97
+ faraday-net_http (3.4.4)
98
+ net-http (~> 0.5)
94
99
  ffi (1.17.0)
95
100
  ffi-compiler (1.3.2)
96
101
  ffi (>= 1.15.5)
@@ -139,16 +144,17 @@ GEM
139
144
  rubocop-rails (~> 2.26.0)
140
145
  rubocop-rspec (~> 3.0.4)
141
146
  rubocop-rspec_rails (~> 2.30.0)
142
- google-apis-compute_v1 (0.108.0)
147
+ google-apis-compute_v1 (0.155.0)
143
148
  google-apis-core (>= 0.15.0, < 2.a)
144
- google-apis-core (0.15.1)
145
- addressable (~> 2.5, >= 2.5.1)
146
- googleauth (~> 1.9)
147
- httpclient (>= 2.8.3, < 3.a)
148
- mini_mime (~> 1.0)
149
- mutex_m
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)
150
156
  representable (~> 3.0)
151
- retriable (>= 2.0, < 4.a)
157
+ retriable (>= 3.1, < 5.0)
152
158
  google-apis-dns_v1 (0.44.0)
153
159
  google-apis-core (>= 0.15.0, < 2.a)
154
160
  google-apis-iamcredentials_v1 (0.21.0)
@@ -163,12 +169,14 @@ GEM
163
169
  google-apis-core (>= 0.15.0, < 2.a)
164
170
  google-cloud-env (2.2.1)
165
171
  faraday (>= 1.0, < 3.a)
166
- googleauth (1.11.1)
172
+ google-logging-utils (0.2.0)
173
+ googleauth (1.17.4)
167
174
  faraday (>= 1.0, < 3.a)
168
- google-cloud-env (~> 2.1)
169
- jwt (>= 1.4, < 3.0)
170
- multi_json (~> 1.11)
175
+ google-cloud-env (~> 2.2)
176
+ google-logging-utils (~> 0.1)
177
+ jwt (>= 1.4, < 4.0)
171
178
  os (>= 0.9, < 2.0)
179
+ pstore (~> 0.1)
172
180
  signet (>= 0.16, < 2.a)
173
181
  guard (2.18.1)
174
182
  formatador (>= 0.2.4)
@@ -195,16 +203,16 @@ GEM
195
203
  http-cookie (1.0.7)
196
204
  domain_name (~> 0.5)
197
205
  http-form_data (2.3.0)
198
- httparty (0.22.0)
206
+ httparty (0.24.3)
199
207
  csv
200
208
  mini_mime (>= 1.0.0)
201
209
  multi_xml (>= 0.5.2)
202
- httpclient (2.8.3)
203
- i18n (1.14.6)
210
+ i18n (1.15.2)
204
211
  concurrent-ruby (~> 1.0)
212
+ io-console (0.9.4)
205
213
  jaro_winkler (1.6.0)
206
- json (2.7.2)
207
- jwt (2.9.3)
214
+ json (2.21.2)
215
+ jwt (3.3.0)
208
216
  base64
209
217
  kramdown (2.4.0)
210
218
  rexml
@@ -218,7 +226,7 @@ GEM
218
226
  llhttp-ffi (0.5.0)
219
227
  ffi-compiler (~> 1.0)
220
228
  rake (~> 13.0)
221
- logger (1.6.1)
229
+ logger (1.7.0)
222
230
  lumberjack (1.2.10)
223
231
  method_source (1.1.0)
224
232
  mime-types (3.6.0)
@@ -226,19 +234,18 @@ GEM
226
234
  mime-types-data (~> 3.2015)
227
235
  mime-types-data (3.2024.1001)
228
236
  mini_mime (1.1.5)
229
- mini_portile2 (2.8.7)
230
- minitest (5.25.1)
237
+ mini_portile2 (2.8.9)
238
+ minitest (5.27.0)
231
239
  mize (0.6.0)
232
240
  multi_json (1.15.0)
233
- multi_xml (0.7.1)
234
- bigdecimal (~> 3.1)
235
- mutex_m (0.2.0)
241
+ multi_xml (0.9.1)
242
+ bigdecimal (>= 3.1, < 5)
236
243
  nap (1.1.0)
237
244
  nenv (0.3.0)
238
- net-http (0.4.1)
239
- uri
245
+ net-http (0.9.1)
246
+ uri (>= 0.11.1)
240
247
  netrc (0.11.0)
241
- nokogiri (1.16.7)
248
+ nokogiri (1.19.4)
242
249
  mini_portile2 (~> 2.8.2)
243
250
  racc (~> 1.4)
244
251
  notiffany (0.1.3)
@@ -260,12 +267,13 @@ GEM
260
267
  pry (0.14.2)
261
268
  coderay (~> 1.1)
262
269
  method_source (~> 1.0)
263
- pry-byebug (3.10.1)
264
- byebug (~> 11.0)
265
- pry (>= 0.13, < 0.15)
266
- public_suffix (6.0.1)
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)
267
275
  racc (1.8.1)
268
- rack (3.2.1)
276
+ rack (3.2.7)
269
277
  rainbow (3.1.1)
270
278
  rake (13.2.1)
271
279
  rb-fsevent (0.11.2)
@@ -274,6 +282,8 @@ GEM
274
282
  rbs (2.8.4)
275
283
  rchardet (1.8.0)
276
284
  regexp_parser (2.11.2)
285
+ reline (0.7.0)
286
+ io-console (~> 0.5)
277
287
  representable (3.2.0)
278
288
  declarative (< 0.1.0)
279
289
  trailblazer-option (>= 0.1.1, < 0.2.0)
@@ -286,7 +296,7 @@ GEM
286
296
  retriable (3.1.2)
287
297
  reverse_markdown (2.1.1)
288
298
  nokogiri
289
- rexml (3.3.8)
299
+ rexml (3.4.4)
290
300
  rouge (4.4.0)
291
301
  rspec (3.13.0)
292
302
  rspec-core (~> 3.13.0)
@@ -349,12 +359,12 @@ GEM
349
359
  sawyer (0.9.2)
350
360
  addressable (>= 2.3.5)
351
361
  faraday (>= 0.17.3, < 3)
362
+ securerandom (0.4.1)
352
363
  shellany (0.0.1)
353
- signet (0.19.0)
364
+ signet (0.22.0)
354
365
  addressable (~> 2.8)
355
366
  faraday (>= 0.17.5, < 3.a)
356
- jwt (>= 1.5, < 3.0)
357
- multi_json (~> 1.10)
367
+ jwt (>= 1.5, < 4.0)
358
368
  simplecov (0.22.0)
359
369
  docile (~> 1.1)
360
370
  simplecov-html (~> 0.11)
@@ -398,7 +408,7 @@ GEM
398
408
  unparser (0.6.15)
399
409
  diff-lcs (~> 1.3)
400
410
  parser (>= 3.3.0)
401
- uri (0.13.1)
411
+ uri (1.1.1)
402
412
  webmock (3.26.4)
403
413
  addressable (>= 2.8.0)
404
414
  crack (>= 0.3.2)
@@ -417,7 +427,7 @@ DEPENDENCIES
417
427
  gitlab_quality-test_tooling!
418
428
  guard-rspec (~> 4.7)
419
429
  lefthook (~> 1.3)
420
- pry-byebug (= 3.10.1)
430
+ pry-byebug (= 3.12.0)
421
431
  rake (~> 13.0)
422
432
  rest-client (~> 2.1.0)
423
433
  rspec (~> 3.12)
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
@@ -40,13 +40,14 @@ module GitlabQuality
40
40
  end
41
41
 
42
42
  def post_exception_to_slack(error)
43
- return unless ENV['CI_SLACK_WEBHOOK_URL']
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 if issue.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
- def initialize(slack_webhook_url:, channel:, message:, username:, icon_emoji:, environment_issues_file: nil)
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:',
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitlabQuality
4
4
  module TestTooling
5
- VERSION = "3.22.1"
5
+ VERSION = "3.23.0"
6
6
  end
7
7
  end
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.22.1
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-10-07 00:00:00.000000000 Z
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.10.1
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.10.1
96
+ version: 3.12.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement