gitlab-qa 10.4.1 → 11.1.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab/changelog_config.yml +13 -0
  3. data/.gitlab/merge_request_templates/Release.md +9 -36
  4. data/.rubocop_todo.yml +0 -12
  5. data/Dangerfile +1 -5
  6. data/Gemfile.lock +4 -4
  7. data/README.md +1 -2
  8. data/docs/running_against_remote_grid.md +39 -2
  9. data/gitlab-qa.gemspec +1 -1
  10. data/lib/gitlab/qa/component/gitaly_cluster.rb +0 -1
  11. data/lib/gitlab/qa/component/gitlab.rb +10 -9
  12. data/lib/gitlab/qa/component/selenoid.rb +8 -3
  13. data/lib/gitlab/qa/runtime/env.rb +21 -41
  14. data/lib/gitlab/qa/scenario/test/instance/airgapped.rb +0 -2
  15. data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +0 -2
  16. data/lib/gitlab/qa/scenario/test/integration/mtls.rb +0 -1
  17. data/lib/gitlab/qa/scenario/test/integration/praefect.rb +0 -2
  18. data/lib/gitlab/qa/scenario/test/integration/registry_with_cdn.rb +2 -2
  19. data/lib/gitlab/qa/version.rb +1 -1
  20. data/lib/gitlab/qa.rb +0 -1
  21. data/support/data/admin_access_token_seed.rb +4 -1
  22. metadata +5 -39
  23. data/bin/slack +0 -14
  24. data/exe/gitlab-qa-report +0 -10
  25. data/lib/gitlab/qa/report/base_test_results.rb +0 -39
  26. data/lib/gitlab/qa/report/find_set_dri.rb +0 -43
  27. data/lib/gitlab/qa/report/generate_test_session.rb +0 -275
  28. data/lib/gitlab/qa/report/gitlab_issue_client.rb +0 -190
  29. data/lib/gitlab/qa/report/gitlab_issue_dry_client.rb +0 -28
  30. data/lib/gitlab/qa/report/j_unit_test_results.rb +0 -27
  31. data/lib/gitlab/qa/report/json_test_results.rb +0 -29
  32. data/lib/gitlab/qa/report/prepare_stage_reports.rb +0 -86
  33. data/lib/gitlab/qa/report/relate_failure_issue.rb +0 -374
  34. data/lib/gitlab/qa/report/report_as_issue.rb +0 -176
  35. data/lib/gitlab/qa/report/report_results.rb +0 -64
  36. data/lib/gitlab/qa/report/results_in_issues.rb +0 -126
  37. data/lib/gitlab/qa/report/results_in_testcases.rb +0 -111
  38. data/lib/gitlab/qa/report/results_reporter_shared.rb +0 -70
  39. data/lib/gitlab/qa/report/summary_table.rb +0 -43
  40. data/lib/gitlab/qa/report/test_result.rb +0 -184
  41. data/lib/gitlab/qa/report/update_screenshot_path.rb +0 -63
  42. data/lib/gitlab/qa/reporter.rb +0 -131
  43. data/lib/gitlab/qa/runtime/token_finder.rb +0 -44
  44. data/lib/gitlab/qa/slack/post_to_slack.rb +0 -30
  45. data/lib/gitlab/qa/system_logs/finders/json_log_finder.rb +0 -65
  46. data/lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb +0 -21
  47. data/lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb +0 -21
  48. data/lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb +0 -21
  49. data/lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb +0 -21
  50. data/lib/gitlab/qa/system_logs/log_types/log.rb +0 -38
  51. data/lib/gitlab/qa/system_logs/log_types/rails/api_log.rb +0 -34
  52. data/lib/gitlab/qa/system_logs/log_types/rails/application_log.rb +0 -27
  53. data/lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb +0 -23
  54. data/lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb +0 -30
  55. data/lib/gitlab/qa/system_logs/shared_fields.rb +0 -29
  56. data/lib/gitlab/qa/system_logs/system_logs_formatter.rb +0 -65
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: 10.4.1
4
+ version: 11.1.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: 2023-05-18 00:00:00.000000000 Z
11
+ date: 2023-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: 4.18.0
201
+ version: '4.19'
202
202
  type: :runtime
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
- version: 4.18.0
208
+ version: '4.19'
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: http
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -313,13 +313,13 @@ email:
313
313
  - gitlab-qa@gmail.com
314
314
  executables:
315
315
  - gitlab-qa
316
- - gitlab-qa-report
317
316
  extensions: []
318
317
  extra_rdoc_files: []
319
318
  files:
320
319
  - ".dockerignore"
321
320
  - ".gitignore"
322
321
  - ".gitlab-ci.yml"
322
+ - ".gitlab/changelog_config.yml"
323
323
  - ".gitlab/issue_templates/Default.md"
324
324
  - ".gitlab/merge_request_templates/Default.md"
325
325
  - ".gitlab/merge_request_templates/Release.md"
@@ -339,7 +339,6 @@ files:
339
339
  - bin/gen-cert.sh
340
340
  - bin/merge_html_reports
341
341
  - bin/setup
342
- - bin/slack
343
342
  - docs/README.md
344
343
  - docs/architecture.md
345
344
  - docs/configuring_omnibus.md
@@ -355,7 +354,6 @@ files:
355
354
  - docs/waits.md
356
355
  - docs/what_tests_can_be_run.md
357
356
  - exe/gitlab-qa
358
- - exe/gitlab-qa-report
359
357
  - fixtures/ldap/1_add_nodes.ldif
360
358
  - fixtures/ldap/2_add_users.ldif
361
359
  - fixtures/ldap/3_add_groups.ldif
@@ -393,24 +391,6 @@ files:
393
391
  - lib/gitlab/qa/docker/engine.rb
394
392
  - lib/gitlab/qa/docker/volumes.rb
395
393
  - lib/gitlab/qa/release.rb
396
- - lib/gitlab/qa/report/base_test_results.rb
397
- - lib/gitlab/qa/report/find_set_dri.rb
398
- - lib/gitlab/qa/report/generate_test_session.rb
399
- - lib/gitlab/qa/report/gitlab_issue_client.rb
400
- - lib/gitlab/qa/report/gitlab_issue_dry_client.rb
401
- - lib/gitlab/qa/report/j_unit_test_results.rb
402
- - lib/gitlab/qa/report/json_test_results.rb
403
- - lib/gitlab/qa/report/prepare_stage_reports.rb
404
- - lib/gitlab/qa/report/relate_failure_issue.rb
405
- - lib/gitlab/qa/report/report_as_issue.rb
406
- - lib/gitlab/qa/report/report_results.rb
407
- - lib/gitlab/qa/report/results_in_issues.rb
408
- - lib/gitlab/qa/report/results_in_testcases.rb
409
- - lib/gitlab/qa/report/results_reporter_shared.rb
410
- - lib/gitlab/qa/report/summary_table.rb
411
- - lib/gitlab/qa/report/test_result.rb
412
- - lib/gitlab/qa/report/update_screenshot_path.rb
413
- - lib/gitlab/qa/reporter.rb
414
394
  - lib/gitlab/qa/runner.rb
415
395
  - lib/gitlab/qa/runtime/env.rb
416
396
  - lib/gitlab/qa/runtime/logger.rb
@@ -424,7 +404,6 @@ files:
424
404
  - lib/gitlab/qa/runtime/omnibus_configurations/packages.rb
425
405
  - lib/gitlab/qa/runtime/omnibus_configurations/registry_object_storage.rb
426
406
  - lib/gitlab/qa/runtime/scenario.rb
427
- - lib/gitlab/qa/runtime/token_finder.rb
428
407
  - lib/gitlab/qa/scenario/actable.rb
429
408
  - lib/gitlab/qa/scenario/cli_commands.rb
430
409
  - lib/gitlab/qa/scenario/template.rb
@@ -478,7 +457,6 @@ files:
478
457
  - lib/gitlab/qa/service/cluster_provider/base.rb
479
458
  - lib/gitlab/qa/service/cluster_provider/k3d.rb
480
459
  - lib/gitlab/qa/service/kubernetes_cluster.rb
481
- - lib/gitlab/qa/slack/post_to_slack.rb
482
460
  - lib/gitlab/qa/support/config_scripts.rb
483
461
  - lib/gitlab/qa/support/get_request.rb
484
462
  - lib/gitlab/qa/support/gitlab_upgrade_path.rb
@@ -487,18 +465,6 @@ files:
487
465
  - lib/gitlab/qa/support/invalid_response_error.rb
488
466
  - lib/gitlab/qa/support/shell_command.rb
489
467
  - lib/gitlab/qa/support/shellout.rb
490
- - lib/gitlab/qa/system_logs/finders/json_log_finder.rb
491
- - lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb
492
- - lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb
493
- - lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb
494
- - lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb
495
- - lib/gitlab/qa/system_logs/log_types/log.rb
496
- - lib/gitlab/qa/system_logs/log_types/rails/api_log.rb
497
- - lib/gitlab/qa/system_logs/log_types/rails/application_log.rb
498
- - lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb
499
- - lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb
500
- - lib/gitlab/qa/system_logs/shared_fields.rb
501
- - lib/gitlab/qa/system_logs/system_logs_formatter.rb
502
468
  - lib/gitlab/qa/test_logger.rb
503
469
  - lib/gitlab/qa/version.rb
504
470
  - scripts/build-package-and-test-env
data/bin/slack DELETED
@@ -1,14 +0,0 @@
1
- #!/bin/bash
2
- # Sends Slack notification MSG to CI_SLACK_WEBHOOK_URL (which needs to be set).
3
- # ICON_EMOJI needs to be set to an icon emoji name (without the `:` around it).
4
-
5
- CHANNEL=$1
6
- MSG=$2
7
- ICON_EMOJI=$3
8
-
9
- if [ -z "$CHANNEL" ] || [ -z "$CI_SLACK_WEBHOOK_URL" ] || [ -z "$MSG" ] || [ -z "$ICON_EMOJI" ]; then
10
- echo "Missing argument(s) - Use: $0 channel message icon_emoji"
11
- echo "and set CI_SLACK_WEBHOOK_URL environment variable."
12
- else
13
- curl -X POST --data-urlencode 'payload={"channel": "#'"$CHANNEL"'", "username": "GitLab QA Bot", "text": "'"$MSG"'", "icon_emoji": "'":$ICON_EMOJI:"'"}' "$CI_SLACK_WEBHOOK_URL"
14
- fi
data/exe/gitlab-qa-report DELETED
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- lib = File.expand_path('../lib', __dir__)
5
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
-
7
- require 'bundler/setup'
8
- require 'gitlab/qa'
9
-
10
- Gitlab::QA::Reporter.invoke(ARGV)
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Gitlab
4
- module QA
5
- module Report
6
- class BaseTestResults
7
- include Enumerable
8
-
9
- attr_reader :path
10
-
11
- def initialize(path)
12
- @path = path
13
- @results = parse
14
- @testcases = process
15
- end
16
-
17
- def each(&block)
18
- testcases.each(&block)
19
- end
20
-
21
- def write
22
- raise NotImplementedError
23
- end
24
-
25
- private
26
-
27
- attr_reader :results, :testcases
28
-
29
- def parse
30
- raise NotImplementedError
31
- end
32
-
33
- def process
34
- raise NotImplementedError
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
-
5
- module Gitlab
6
- module QA
7
- module Report
8
- module FindSetDri
9
- def set_dri_via_group(product_group, test)
10
- parse_json_with_sets
11
- fetch_stage_sets(test)
12
-
13
- return @sets.sample['username'] if @stage_sets.empty?
14
-
15
- fetch_group_sets(product_group)
16
-
17
- if @group_sets.empty?
18
- @stage_sets.sample['username']
19
- else
20
- @group_sets.sample['username']
21
- end
22
- end
23
-
24
- private
25
-
26
- def parse_json_with_sets
27
- response = Support::HttpRequest.make_http_request(
28
- url: 'https://gitlab-org.gitlab.io/gitlab-roulette/roulette.json'
29
- )
30
- @sets = JSON.parse(response.body).select { |user| user['role'].include?('software-engineer-in-test') }
31
- end
32
-
33
- def fetch_stage_sets(test)
34
- @stage_sets = @sets.select { |user| user['role'].include?(test.stage.split("_").map(&:capitalize).join(" ")) }
35
- end
36
-
37
- def fetch_group_sets(product_group)
38
- @group_sets = @stage_sets.select { |user| user['role'].include?(product_group.split("_").map { |word| word == 'and' ? word : word.capitalize }.join(" ")) }
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,275 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'erb'
4
- require 'date'
5
-
6
- module Gitlab
7
- module QA
8
- module Report
9
- class GenerateTestSession < ReportAsIssue
10
- def initialize(**kwargs)
11
- super
12
- @issue_type = 'issue'
13
- end
14
-
15
- private
16
-
17
- # rubocop:disable Metrics/AbcSize
18
- def run!
19
- puts "Generating test results in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
20
-
21
- tests = Dir.glob(files).flat_map do |path|
22
- puts "Loading tests in #{path}"
23
-
24
- Report::JsonTestResults.new(path).to_a
25
- end
26
-
27
- issue = gitlab.create_issue(
28
- title: "#{Time.now.strftime('%Y-%m-%d')} Test session report | #{Runtime::Env.qa_run_type}",
29
- description: generate_description(tests),
30
- labels: ['Quality', 'QA', 'triage report', pipeline_name_label]
31
- )
32
-
33
- # Workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/295493
34
- unless Runtime::Env.qa_issue_url.to_s.empty?
35
- gitlab.create_issue_note(
36
- iid: issue.iid,
37
- note: "/relate #{Runtime::Env.qa_issue_url}")
38
- end
39
-
40
- File.write('REPORT_ISSUE_URL', issue.web_url)
41
- end
42
- # rubocop:enable Metrics/AbcSize
43
-
44
- def generate_description(tests)
45
- <<~MARKDOWN.rstrip
46
- ## Session summary
47
-
48
- * Deploy version: #{Runtime::Env.deploy_version}
49
- * Deploy environment: #{Runtime::Env.deploy_environment}
50
- * Pipeline: #{Runtime::Env.pipeline_from_project_name} [#{Runtime::Env.ci_pipeline_id}](#{Runtime::Env.ci_pipeline_url})
51
- #{generate_summary(tests: tests)}
52
-
53
- #{generate_failed_jobs_listing}
54
-
55
- #{generate_stages_listing(tests)}
56
-
57
- #{generate_qa_issue_relation}
58
-
59
- #{generate_link_to_dashboard}
60
- MARKDOWN
61
- end
62
-
63
- def generate_summary(tests:, tests_by_status: nil)
64
- tests_by_status ||= tests.group_by(&:status)
65
- total = tests.size
66
- passed = tests_by_status['passed']&.size || 0
67
- failed = tests_by_status['failed']&.size || 0
68
- others = total - passed - failed
69
-
70
- <<~MARKDOWN.chomp
71
- * Total #{total} tests
72
- * Passed #{passed} tests
73
- * Failed #{failed} tests
74
- * #{others} other tests (usually skipped)
75
- MARKDOWN
76
- end
77
-
78
- def generate_failed_jobs_listing
79
- failed_jobs = []
80
-
81
- client = Gitlab.client(
82
- endpoint: Runtime::Env.ci_api_v4_url,
83
- private_token: Runtime::Env.gitlab_ci_api_token)
84
-
85
- gitlab.handle_gitlab_client_exceptions do
86
- failed_jobs = client.pipeline_jobs(
87
- Runtime::Env.ci_project_id,
88
- Runtime::Env.ci_pipeline_id,
89
- scope: 'failed')
90
- end
91
-
92
- listings = failed_jobs.map do |job|
93
- allowed_to_fail = ' (allowed to fail)' if job.allow_failure
94
-
95
- "* [#{job.name}](#{job.web_url})#{allowed_to_fail}"
96
- end.join("\n")
97
-
98
- <<~MARKDOWN.chomp if failed_jobs.any?
99
- ## Failed jobs
100
-
101
- #{listings}
102
- MARKDOWN
103
- end
104
-
105
- def generate_stages_listing(tests)
106
- generate_tests_by_stage(tests).map do |stage, tests_for_stage|
107
- tests_by_status = tests_for_stage.group_by(&:status)
108
-
109
- <<~MARKDOWN.chomp
110
- ### #{stage&.capitalize || 'Unknown'}
111
-
112
- #{generate_summary(
113
- tests: tests_for_stage, tests_by_status: tests_by_status)}
114
-
115
- #{generate_testcase_listing_by_status(
116
- tests: tests_for_stage, tests_by_status: tests_by_status)}
117
- MARKDOWN
118
- end.join("\n\n")
119
- end
120
-
121
- def generate_tests_by_stage(tests)
122
- # https://about.gitlab.com/handbook/product/product-categories/#devops-stages
123
- ordering = %w[
124
- manage
125
- plan
126
- create
127
- verify
128
- package
129
- release
130
- configure
131
- monitor
132
- secure
133
- defend
134
- growth
135
- fulfillment
136
- enablement
137
- ]
138
-
139
- tests.sort_by do |test|
140
- ordering.index(test.stage) || ordering.size
141
- end.group_by(&:stage)
142
- end
143
-
144
- def generate_testcase_listing_by_status(tests:, tests_by_status:)
145
- failed_tests = tests_by_status['failed']
146
- passed_tests = tests_by_status['passed']
147
- other_tests = tests.reject do |test|
148
- test.status == 'failed' || test.status == 'passed'
149
- end
150
-
151
- [
152
- (failed_listings(failed_tests) if failed_tests),
153
- (passed_listings(passed_tests) if passed_tests),
154
- (other_listings(other_tests) if other_tests.any?)
155
- ].compact.join("\n\n")
156
- end
157
-
158
- def failed_listings(failed_tests)
159
- generate_testcase_listing(failed_tests)
160
- end
161
-
162
- def passed_listings(passed_tests)
163
- <<~MARKDOWN.chomp
164
- <details><summary>Passed tests:</summary>
165
-
166
- #{generate_testcase_listing(passed_tests, passed: true)}
167
-
168
- </details>
169
- MARKDOWN
170
- end
171
-
172
- def other_listings(other_tests)
173
- <<~MARKDOWN.chomp
174
- <details><summary>Other tests:</summary>
175
-
176
- #{generate_testcase_listing(other_tests)}
177
-
178
- </details>
179
- MARKDOWN
180
- end
181
-
182
- def generate_testcase_listing(tests, passed: false)
183
- body = tests.group_by(&:testcase).map do |testcase, tests_with_same_testcase|
184
- tests_with_same_testcase.sort_by!(&:name)
185
- [
186
- generate_test_text(testcase, tests_with_same_testcase, passed),
187
- generate_test_job(tests_with_same_testcase),
188
- generate_test_status(tests_with_same_testcase),
189
- generate_test_actions(tests_with_same_testcase)
190
- ].join(' | ')
191
- end.join("\n")
192
-
193
- <<~MARKDOWN.chomp
194
- | Test | Job | Status | Action |
195
- | - | - | - | - |
196
- #{body}
197
- MARKDOWN
198
- end
199
-
200
- def generate_test_text(testcase, tests_with_same_testcase, passed)
201
- text = tests_with_same_testcase.map(&:name).uniq.join(', ')
202
- encoded_text = ERB::Util.url_encode(text)
203
-
204
- if testcase && !passed
205
- # Workaround for reducing system notes on testcase issues
206
- # The first regex extracts the link to the issues list page from a link to a single issue show page by removing the issue id.
207
- "[#{text}](#{testcase.match(%r{[\s\S]+\/[^\/\d]+})}?state=opened&search=#{encoded_text})"
208
- else
209
- text
210
- end
211
- end
212
-
213
- def generate_test_job(tests_with_same_testcase)
214
- tests_with_same_testcase.map do |test|
215
- ci_job_id = test.ci_job_url[/\d+\z/]
216
-
217
- "[#{ci_job_id}](#{test.ci_job_url})#{' ~"quarantine"' if test.quarantine?}"
218
- end.uniq.join(', ')
219
- end
220
-
221
- def generate_test_status(tests_with_same_testcase)
222
- tests_with_same_testcase.map(&:status).uniq.map do |status|
223
- %(~"#{status}")
224
- end.join(', ')
225
- end
226
-
227
- def generate_test_actions(tests_with_same_testcase)
228
- # All failed tests would be grouped together, meaning that
229
- # if one failed, all the tests here would be failed too.
230
- # So this check is safe. Same applies to 'passed'.
231
- # But all other status might be mixing together,
232
- # we cannot assume other statuses.
233
- if tests_with_same_testcase.first.status == 'failed'
234
- tests_having_failure_issue =
235
- tests_with_same_testcase.select(&:failure_issue)
236
-
237
- if tests_having_failure_issue.any?
238
- items = tests_having_failure_issue.uniq(&:failure_issue).map do |test|
239
- "<li>[ ] [failure issue](#{test.failure_issue})</li>"
240
- end.join(' ')
241
-
242
- "<ul>#{items}</ul>"
243
- else
244
- '<ul><li>[ ] failure issue exists or was created</li></ul>'
245
- end
246
- else
247
- '-'
248
- end
249
- end
250
-
251
- def generate_qa_issue_relation
252
- return unless Runtime::Env.qa_issue_url
253
-
254
- <<~MARKDOWN.chomp
255
- ## Release QA issue
256
-
257
- * #{Runtime::Env.qa_issue_url}
258
-
259
- /relate #{Runtime::Env.qa_issue_url}
260
- MARKDOWN
261
- end
262
-
263
- def generate_link_to_dashboard
264
- return unless Runtime::Env.qa_run_type
265
-
266
- <<~MARKDOWN.chomp
267
- ## Link to Grafana dashboard for run-type of #{Runtime::Env.qa_run_type}
268
-
269
- * https://dashboards.quality.gitlab.net/d/kuNYMgDnz/test-run-metrics?orgId=1&refresh=1m&var-run_type=#{Runtime::Env.qa_run_type}
270
- MARKDOWN
271
- end
272
- end
273
- end
274
- end
275
- end
@@ -1,190 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'gitlab'
4
-
5
- module Gitlab
6
- # Monkey patch the Gitlab client to use the correct API path and add required methods
7
- class Client
8
- def team_member(project, id)
9
- get("/projects/#{url_encode(project)}/members/all/#{id}")
10
- end
11
-
12
- def issue_discussions(project, issue_id, options = {})
13
- get("/projects/#{url_encode(project)}/issues/#{issue_id}/discussions", query: options)
14
- end
15
-
16
- def add_note_to_issue_discussion_as_thread(project, issue_id, discussion_id, options = {})
17
- post("/projects/#{url_encode(project)}/issues/#{issue_id}/discussions/#{discussion_id}/notes", query: options)
18
- end
19
- end
20
-
21
- module QA
22
- module Report
23
- # The GitLab client is used for API access: https://github.com/NARKOZ/gitlab
24
- class GitlabIssueClient
25
- MAINTAINER_ACCESS_LEVEL = 40
26
- RETRY_BACK_OFF_DELAY = 60
27
- MAX_RETRY_ATTEMPTS = 3
28
-
29
- def initialize(token:, project:)
30
- @token = token
31
- @project = project
32
- @retry_backoff = 0
33
-
34
- configure_gitlab_client
35
- end
36
-
37
- def assert_user_permission!
38
- handle_gitlab_client_exceptions do
39
- user = Gitlab.user
40
- member = Gitlab.team_member(project, user.id)
41
-
42
- abort_not_permitted if member.access_level < MAINTAINER_ACCESS_LEVEL
43
- end
44
- rescue Gitlab::Error::NotFound
45
- abort_not_permitted
46
- end
47
-
48
- def find_issues(iid: nil, options: {}, &select)
49
- select ||= :itself
50
-
51
- handle_gitlab_client_exceptions do
52
- return [Gitlab.issue(project, iid)].select(&select) if iid
53
-
54
- Gitlab.issues(project, options)
55
- .auto_paginate
56
- .select(&select)
57
- end
58
- end
59
-
60
- def find_issue_discussions(iid:)
61
- handle_gitlab_client_exceptions do
62
- Gitlab.issue_discussions(project, iid, order_by: 'created_at', sort: 'asc').auto_paginate
63
- end
64
- end
65
-
66
- def create_issue(title:, description:, labels:, issue_type: 'issue')
67
- attrs = { issue_type: issue_type, description: description, labels: labels }
68
-
69
- handle_gitlab_client_exceptions do
70
- Gitlab.create_issue(project, title, attrs)
71
- end
72
- end
73
-
74
- def edit_issue(iid:, options: {})
75
- handle_gitlab_client_exceptions do
76
- Gitlab.edit_issue(project, iid, options)
77
- end
78
- end
79
-
80
- def find_issue_notes(iid:)
81
- handle_gitlab_client_exceptions do
82
- Gitlab.issue_notes(project, iid, order_by: 'created_at', sort: 'asc')&.auto_paginate
83
- end
84
- end
85
-
86
- def create_issue_note(iid:, note:)
87
- handle_gitlab_client_exceptions do
88
- Gitlab.create_issue_note(project, iid, note)
89
- end
90
- end
91
-
92
- def edit_issue_note(issue_iid:, note_id:, note:)
93
- handle_gitlab_client_exceptions do
94
- Gitlab.edit_issue_note(project, issue_iid, note_id, note)
95
- end
96
- end
97
-
98
- def add_note_to_issue_discussion_as_thread(iid:, discussion_id:, body:)
99
- handle_gitlab_client_exceptions do
100
- Gitlab.add_note_to_issue_discussion_as_thread(project, iid, discussion_id, body: body)
101
- end
102
- end
103
-
104
- def find_user_id(username:)
105
- handle_gitlab_client_exceptions do
106
- user = Gitlab.users(username: username)&.first
107
- user['id'] unless user.nil?
108
- end
109
- end
110
-
111
- def upload_file(file_fullpath:)
112
- ignore_gitlab_client_exceptions do
113
- Gitlab.upload_file(project, file_fullpath)
114
- end
115
- end
116
-
117
- def ignore_gitlab_client_exceptions
118
- yield
119
- rescue StandardError, SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::Error => e
120
- puts "Ignoring the following error: #{e}"
121
- end
122
-
123
- def handle_gitlab_client_exceptions
124
- yield
125
- rescue Gitlab::Error::NotFound
126
- # This error could be raised in assert_user_permission!
127
- # If so, we want it to terminate at that point
128
- raise
129
- rescue SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::InternalServerError, Gitlab::Error::Parsing => e
130
- @retry_backoff += RETRY_BACK_OFF_DELAY
131
-
132
- raise if @retry_backoff > RETRY_BACK_OFF_DELAY * MAX_RETRY_ATTEMPTS
133
-
134
- warn_exception(e)
135
- warn("Sleeping for #{@retry_backoff} seconds before retrying...")
136
- sleep @retry_backoff
137
-
138
- retry
139
- rescue StandardError => e
140
- pipeline = QA::Runtime::Env.pipeline_from_project_name
141
- channel = case pipeline
142
- when "canary"
143
- "qa-production"
144
- when "staging-canary"
145
- "qa-staging"
146
- else
147
- "qa-#{pipeline}"
148
- end
149
- error_msg = warn_exception(e)
150
-
151
- return unless QA::Runtime::Env.ci_commit_ref_name == QA::Runtime::Env.default_branch
152
-
153
- slack_options = {
154
- channel: channel,
155
- icon_emoji: ':ci_failing:',
156
- message: <<~MSG
157
- An unexpected error occurred while reporting test results in issues.
158
- The error occurred in job: #{QA::Runtime::Env.ci_job_url}
159
- `#{error_msg}`
160
- MSG
161
- }
162
- puts "Posting Slack message to channel: #{channel}"
163
-
164
- Gitlab::QA::Slack::PostToSlack.new(**slack_options).invoke!
165
- end
166
-
167
- private
168
-
169
- attr_reader :token, :project
170
-
171
- def configure_gitlab_client
172
- Gitlab.configure do |config|
173
- config.endpoint = Runtime::Env.gitlab_api_base
174
- config.private_token = token
175
- end
176
- end
177
-
178
- def abort_not_permitted
179
- abort "You must have at least Maintainer access to the project to use this feature."
180
- end
181
-
182
- def warn_exception(error)
183
- error_msg = "#{error.class.name} #{error.message}"
184
- warn(error_msg)
185
- error_msg
186
- end
187
- end
188
- end
189
- end
190
- end