gitlab-qa 5.4.2 → 5.4.3
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/lib/gitlab/qa/report/results_in_issues.rb +80 -23
- data/lib/gitlab/qa/runtime/env.rb +4 -0
- data/lib/gitlab/qa/slack/post_to_slack.rb +7 -5
- data/lib/gitlab/qa/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b104344d3af630c69b69edb56915220bacf32e86a2b2d02159bef044112763d
|
4
|
+
data.tar.gz: b98743c7f6c138379c2350e29295c5c0e48b6156319651032c3877d3da0e70d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35ec93687d9dbbf06c8593b2de3080f2c75fe0f6110f2fa5c1c2b988c5b09efea5562073b38d455480f93172b574bc00fd2cc8a4971a74a76d719c9be43a5eb2
|
7
|
+
data.tar.gz: ad0ad93bbcf79ba906c80b46de51a790459a124460ddeff922bdca63f2aa44b42ca1366ddaab0d471197605519203cbfe177acf939ae8e86d59c9db6a90a21f9
|
@@ -27,11 +27,14 @@ module Gitlab
|
|
27
27
|
class ResultsInIssues
|
28
28
|
MAINTAINER_ACCESS_LEVEL = 40
|
29
29
|
MAX_TITLE_LENGTH = 255
|
30
|
+
RETRY_BACK_OFF_DELAY = 60
|
31
|
+
MAX_RETRY_ATTEMPTS = 3
|
30
32
|
|
31
33
|
def initialize(token:, input_files:, project: nil)
|
32
34
|
@token = token
|
33
35
|
@files = Array(input_files)
|
34
36
|
@project = project
|
37
|
+
@retry_backoff = 0
|
35
38
|
end
|
36
39
|
|
37
40
|
def invoke!
|
@@ -72,10 +75,12 @@ module Gitlab
|
|
72
75
|
end
|
73
76
|
|
74
77
|
def assert_user_permission!
|
75
|
-
|
76
|
-
|
78
|
+
handle_gitlab_client_exceptions do
|
79
|
+
user = Gitlab.user
|
80
|
+
member = Gitlab.team_member(project, user.id)
|
77
81
|
|
78
|
-
|
82
|
+
abort_not_permitted if member.access_level < MAINTAINER_ACCESS_LEVEL
|
83
|
+
end
|
79
84
|
rescue Gitlab::Error::NotFound
|
80
85
|
abort_not_permitted
|
81
86
|
end
|
@@ -85,9 +90,11 @@ module Gitlab
|
|
85
90
|
end
|
86
91
|
|
87
92
|
def configure_gitlab_client
|
88
|
-
|
89
|
-
|
90
|
-
|
93
|
+
handle_gitlab_client_exceptions do
|
94
|
+
Gitlab.configure do |config|
|
95
|
+
config.endpoint = Runtime::Env.gitlab_api_base
|
96
|
+
config.private_token = token
|
97
|
+
end
|
91
98
|
end
|
92
99
|
end
|
93
100
|
|
@@ -113,21 +120,25 @@ module Gitlab
|
|
113
120
|
def create_issue(test)
|
114
121
|
puts "Creating issue for file: #{test['file']} | name: #{test['name']}"
|
115
122
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
123
|
+
handle_gitlab_client_exceptions do
|
124
|
+
Gitlab.create_issue(
|
125
|
+
project,
|
126
|
+
title_from_test(test),
|
127
|
+
{ description: "### Full description\n\n#{search_safe(test['name'])}\n\n### File path\n\n#{test['file']}", labels: 'status::automated' }
|
128
|
+
)
|
129
|
+
end
|
121
130
|
end
|
122
131
|
|
123
132
|
def find_issue(test)
|
124
|
-
|
125
|
-
.
|
126
|
-
|
133
|
+
handle_gitlab_client_exceptions do
|
134
|
+
issues = Gitlab.issues(project, { search: search_term(test) })
|
135
|
+
.auto_paginate
|
136
|
+
.select { |issue| issue.state == 'opened' && issue.title.strip == title_from_test(test) }
|
127
137
|
|
128
|
-
|
138
|
+
warn(%(Too many issues found with the file path "#{test['file']}" and name "#{test['name']}")) if issues.many?
|
129
139
|
|
130
|
-
|
140
|
+
issues.first
|
141
|
+
end
|
131
142
|
end
|
132
143
|
|
133
144
|
def search_term(test)
|
@@ -151,11 +162,13 @@ module Gitlab
|
|
151
162
|
|
152
163
|
note = note_content(test)
|
153
164
|
|
154
|
-
|
155
|
-
|
156
|
-
|
165
|
+
handle_gitlab_client_exceptions do
|
166
|
+
Gitlab.issue_discussions(project, issue.iid, order_by: 'created_at', sort: 'asc').each do |discussion|
|
167
|
+
return add_note_to_discussion(issue.iid, discussion.id) if new_note_matches_discussion?(note, discussion)
|
168
|
+
end
|
157
169
|
|
158
|
-
|
170
|
+
Gitlab.create_issue_note(project, issue.iid, note)
|
171
|
+
end
|
159
172
|
end
|
160
173
|
|
161
174
|
def note_content(test)
|
@@ -205,7 +218,9 @@ module Gitlab
|
|
205
218
|
end
|
206
219
|
|
207
220
|
def add_note_to_discussion(issue_iid, discussion_id)
|
208
|
-
|
221
|
+
handle_gitlab_client_exceptions do
|
222
|
+
Gitlab.add_note_to_issue_discussion_as_thread(project, issue_iid, discussion_id, body: failure_summary)
|
223
|
+
end
|
209
224
|
end
|
210
225
|
|
211
226
|
def update_labels(issue, test)
|
@@ -214,7 +229,9 @@ module Gitlab
|
|
214
229
|
labels << (failures(test).empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
|
215
230
|
quarantine_job? ? labels << "quarantine" : labels.delete("quarantine")
|
216
231
|
|
217
|
-
|
232
|
+
handle_gitlab_client_exceptions do
|
233
|
+
Gitlab.edit_issue(project, issue.iid, labels: labels)
|
234
|
+
end
|
218
235
|
end
|
219
236
|
|
220
237
|
def failures(test)
|
@@ -234,7 +251,47 @@ module Gitlab
|
|
234
251
|
# because the other pipelines will be monitored by the author of the MR that triggered them.
|
235
252
|
# So we assume that we're reporting a master pipeline if the project name is 'gitlab-qa'.
|
236
253
|
|
237
|
-
Runtime::Env.
|
254
|
+
Runtime::Env.pipeline_from_project_name
|
255
|
+
end
|
256
|
+
|
257
|
+
def handle_gitlab_client_exceptions
|
258
|
+
yield
|
259
|
+
rescue Gitlab::Error::NotFound
|
260
|
+
# This error could be raised in assert_user_permission!
|
261
|
+
# If so, we want it to terminate at that point
|
262
|
+
raise
|
263
|
+
rescue Errno::ETIMEDOUT, OpenSSL::SSL::SSLError, Net::ReadTimeout => e
|
264
|
+
@retry_backoff += RETRY_BACK_OFF_DELAY
|
265
|
+
|
266
|
+
raise if @retry_backoff > RETRY_BACK_OFF_DELAY * MAX_RETRY_ATTEMPTS
|
267
|
+
|
268
|
+
warn_exception(e)
|
269
|
+
warn("Sleeping for #{@retry_backoff} seconds before retrying...")
|
270
|
+
sleep @retry_backoff
|
271
|
+
|
272
|
+
retry
|
273
|
+
rescue StandardError => e
|
274
|
+
pipeline = QA::Runtime::Env.pipeline_from_project_name
|
275
|
+
channel = pipeline == "canary" ? "qa-production" : "qa-#{pipeline}"
|
276
|
+
error_msg = warn_exception(e)
|
277
|
+
slack_options = {
|
278
|
+
channel: channel,
|
279
|
+
icon_emoji: ':ci_failing:',
|
280
|
+
message: <<~MSG
|
281
|
+
An unexpected error occurred while reporting test results in issues.
|
282
|
+
The error occurred in job: #{QA::Runtime::Env.ci_job_url}
|
283
|
+
`#{error_msg}`
|
284
|
+
MSG
|
285
|
+
}
|
286
|
+
puts "Posting Slack message to channel: #{channel}"
|
287
|
+
|
288
|
+
Gitlab::QA::Slack::PostToSlack.new(**slack_options).invoke!
|
289
|
+
end
|
290
|
+
|
291
|
+
def warn_exception(error)
|
292
|
+
error_msg = "#{error.class.name} #{error.message}"
|
293
|
+
warn(error_msg)
|
294
|
+
error_msg
|
238
295
|
end
|
239
296
|
end
|
240
297
|
end
|
@@ -2,23 +2,25 @@ module Gitlab
|
|
2
2
|
module QA
|
3
3
|
module Slack
|
4
4
|
class PostToSlack
|
5
|
-
def initialize(message:)
|
5
|
+
def initialize(message:, icon_emoji: Runtime::Env.slack_icon_emoji, channel: Runtime::Env.slack_qa_channel)
|
6
|
+
@channel = channel
|
6
7
|
@message = message
|
8
|
+
@icon_emoji = icon_emoji
|
7
9
|
end
|
8
10
|
|
9
11
|
def invoke!
|
10
|
-
Runtime::Env.require_slack_qa_channel!
|
12
|
+
Runtime::Env.require_slack_qa_channel! unless @channel
|
11
13
|
Runtime::Env.require_ci_slack_webhook_url!
|
12
14
|
|
13
15
|
params = {}
|
14
|
-
params['channel'] =
|
16
|
+
params['channel'] = @channel
|
15
17
|
params['username'] = "GitLab QA Bot"
|
16
|
-
params['icon_emoji'] =
|
18
|
+
params['icon_emoji'] = @icon_emoji
|
17
19
|
params['text'] = @message
|
18
20
|
|
19
21
|
url = Runtime::Env.ci_slack_webhook_url
|
20
22
|
|
21
|
-
Support::HttpRequest.make_http_request(method: 'post', url: url, params: params)
|
23
|
+
Support::HttpRequest.make_http_request(method: 'post', url: url, params: params, show_response: true)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
data/lib/gitlab/qa/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-qa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.4.
|
4
|
+
version: 5.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grzegorz Bizon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|