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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ce58eec53ccc54effca3fc1b94070e6ec6f930c13e11aef8dafb600c59feb59
4
- data.tar.gz: 97437cf5d0bed65931c57af0dc459d6097f37f3787ba8498f9784d4c45158d2a
3
+ metadata.gz: 5b104344d3af630c69b69edb56915220bacf32e86a2b2d02159bef044112763d
4
+ data.tar.gz: b98743c7f6c138379c2350e29295c5c0e48b6156319651032c3877d3da0e70d7
5
5
  SHA512:
6
- metadata.gz: 5ecabb59dd4285a6a0923a680390e6ba7f87eeb85b58827279ebb06870ea32695218ded6a8b78bdaec1d6c4a522d5ed60d888859b6c0dd45c56aa9611a782350
7
- data.tar.gz: 46970e6a919d479d104dc664f249b7aa03543e4e95499e7e7912381e02cb383085ea837b61b1e3dfb74eeb6cf50c12ee9ee46e4a5b25a7e4448427fe1bd02622
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
- user = Gitlab.user
76
- member = Gitlab.team_member(project, user.id)
78
+ handle_gitlab_client_exceptions do
79
+ user = Gitlab.user
80
+ member = Gitlab.team_member(project, user.id)
77
81
 
78
- abort_not_permitted if member.access_level < MAINTAINER_ACCESS_LEVEL
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
- Gitlab.configure do |config|
89
- config.endpoint = Runtime::Env.gitlab_api_base
90
- config.private_token = token
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
- Gitlab.create_issue(
117
- project,
118
- title_from_test(test),
119
- { description: "### Full description\n\n#{search_safe(test['name'])}\n\n### File path\n\n#{test['file']}", labels: 'status::automated' }
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
- issues = Gitlab.issues(project, { search: search_term(test) })
125
- .auto_paginate
126
- .select { |issue| issue.state == 'opened' && issue.title.strip == title_from_test(test) }
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
- warn(%(Too many issues found with the file path "#{test['file']}" and name "#{test['name']}")) if issues.many?
138
+ warn(%(Too many issues found with the file path "#{test['file']}" and name "#{test['name']}")) if issues.many?
129
139
 
130
- issues.first
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
- Gitlab.issue_discussions(project, issue.iid, order_by: 'created_at', sort: 'asc').each do |discussion|
155
- return add_note_to_discussion(issue.iid, discussion.id) if new_note_matches_discussion?(note, discussion)
156
- end
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
- Gitlab.create_issue_note(project, issue.iid, note)
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
- Gitlab.add_note_to_issue_discussion_as_thread(project, issue_iid, discussion_id, body: failure_summary)
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
- Gitlab.edit_issue(project, issue.iid, labels: labels)
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.ci_project_name.to_s.start_with?('gitlab-qa') ? 'master' : Runtime::Env.ci_project_name
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
@@ -97,6 +97,10 @@ module Gitlab
97
97
  ENV['CI_SLACK_WEBHOOK_URL']
98
98
  end
99
99
 
100
+ def pipeline_from_project_name
101
+ ci_project_name.to_s.start_with?('gitlab-qa') ? 'master' : ci_project_name
102
+ end
103
+
100
104
  def slack_qa_channel
101
105
  ENV['SLACK_QA_CHANNEL']
102
106
  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'] = Runtime::Env.slack_qa_channel
16
+ params['channel'] = @channel
15
17
  params['username'] = "GitLab QA Bot"
16
- params['icon_emoji'] = Runtime::Env.slack_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
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module QA
3
- VERSION = '5.4.2'.freeze
3
+ VERSION = '5.4.3'.freeze
4
4
  end
5
5
  end
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.2
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-02 00:00:00.000000000 Z
11
+ date: 2020-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control