gitlab-qa 7.15.1 → 7.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eff5b2a5b6b59f95a7ce622eb57a6157dc7492af83be416d3b8950ba527c3495
4
- data.tar.gz: 6da73f8680896f2875e4899ea21b3272c418ee0140ae9d1a54b5117e870f5e5a
3
+ metadata.gz: '090fb8d7830e6cfd3ee6978b9f7ba4ad6eb4ba5ceec37921e5cde75285fd4015'
4
+ data.tar.gz: '058a34d1526fc7ae37df2c8b75e3e0888c15785c5bb2d3954b0b72e6a6d653d8'
5
5
  SHA512:
6
- metadata.gz: 6110c4e993d4ff262476a637e7fad86a32561c29609bd6a5341cf8d14a53de73a0c7301763a71a3674551cd36385d67ed42db86de2c434cd938c13cbb98a0afa
7
- data.tar.gz: 43db85b7549e3b3296df9f1d2c8534724d7c908ecaa11b300fe64f8a7b0f4297fbf88e704c8431fa2da4ce5a5247788136a6b66972cbbf7fd6dd1a6de3956dff
6
+ metadata.gz: de89ce6d1c4a5cf43aebd3510af3f758dc1e8f2d8063878ec6a74d5530d9af9ffa903ad77267caed55ad77125ecb2aa044523cb9366144c82637f02bb765778f
7
+ data.tar.gz: 9a68591bf7a1a774dbee63a5f0374c0b46df7029e4e90419f184be961cfbddb7d31589e7603299bb1b7f59af20ceb7f2eb5f4071315389dc97958946bc246801
data/.gitlab-ci.yml CHANGED
@@ -46,7 +46,8 @@ variables:
46
46
  QA_CAN_TEST_GIT_PROTOCOL_V2: "true"
47
47
  QA_CAN_TEST_PRAEFECT: "false"
48
48
  QA_GENERATE_ALLURE_REPORT: "true"
49
- QA_TESTCASES_REPORTING_PROJECT: "gitlab-org/quality/testcases"
49
+ QA_TESTCASES_REPORTING_PROJECT: "gitlab-org/gitlab"
50
+ QA_TEST_RESULTS_ISSUES_PROJECT: "gitlab-org/quality/testcases"
50
51
  QA_TESTCASE_SESSIONS_PROJECT: "gitlab-org/quality/testcase-sessions"
51
52
  # QA_DEFAULT_BRANCH is the default branch name of the instance under test.
52
53
  QA_DEFAULT_BRANCH: "master"
@@ -84,7 +85,7 @@ rspec:
84
85
  - bundle exec exe/gitlab-qa ${QA_SCENARIO:=Test::Instance::Image} ${RELEASE:=$DEFAULT_RELEASE} $GITLAB_QA_OPTIONS -- $QA_TESTS $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS || test_run_exit_code=$?
85
86
  - bundle exec exe/gitlab-qa-report --update-screenshot-path "gitlab-qa-run-*/**/rspec-*.xml"
86
87
  - export GITLAB_QA_ACCESS_TOKEN="$GITLAB_QA_PRODUCTION_ACCESS_TOKEN"
87
- - if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-in-issues "gitlab-qa-run-*/**/rspec-*.json" --project "$QA_TESTCASES_REPORTING_PROJECT" || true; fi
88
+ - if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-results "gitlab-qa-run-*/**/rspec-*.json" --test-case-project "$QA_TESTCASES_REPORTING_PROJECT" --results-issue-project "$QA_TEST_RESULTS_ISSUES_PROJECT" || true; fi
88
89
  - exit $test_run_exit_code
89
90
 
90
91
  # For jobs that shouldn't report results in issues, e.g., manually run custom jobs
@@ -107,7 +108,7 @@ rspec:
107
108
  - bundle exec exe/gitlab-qa Test::Omnibus::Update ${RELEASE:=$DEFAULT_RELEASE} ${RELEASE:=$DEFAULT_RELEASE} $GITLAB_QA_OPTIONS -- $QA_TESTS $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS || test_run_exit_code=$?
108
109
  - bundle exec exe/gitlab-qa-report --update-screenshot-path "gitlab-qa-run-*/**/rspec-*.xml"
109
110
  - export GITLAB_QA_ACCESS_TOKEN="$GITLAB_QA_PRODUCTION_ACCESS_TOKEN"
110
- - if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-in-issues "gitlab-qa-run-*/**/rspec-*.json" --project "$QA_TESTCASES_REPORTING_PROJECT" || true; fi
111
+ - if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-results "gitlab-qa-run-*/**/rspec-*.json" --test-case-project "$QA_TESTCASES_REPORTING_PROJECT" --results-issue-project "$QA_TEST_RESULTS_ISSUES_PROJECT" || true; fi
111
112
  - exit $test_run_exit_code
112
113
 
113
114
  .ce-variables:
@@ -6,6 +6,11 @@ module Gitlab
6
6
  module QA
7
7
  module Report
8
8
  class GenerateTestSession < ReportAsIssue
9
+ def initialize(**kwargs)
10
+ super
11
+ @issue_type = 'issue'
12
+ end
13
+
9
14
  private
10
15
 
11
16
  # rubocop:disable Metrics/AbcSize
@@ -19,6 +19,7 @@ module Gitlab
19
19
  def initialize(max_diff_ratio: DEFAULT_MAX_DIFF_RATIO_FOR_DETECTION, **kwargs)
20
20
  super
21
21
  @max_diff_ratio = max_diff_ratio.to_f
22
+ @issue_type = 'issue'
22
23
  end
23
24
 
24
25
  private
@@ -63,7 +64,7 @@ module Gitlab
63
64
  puts " => Found issue #{issue.web_url} for test '#{test.name}' with a diff ratio of #{(diff_ratio * 100).round(2)}%."
64
65
  else
65
66
  issue = create_issue(test)
66
- puts " => Created new issue: #{issue.web_url} for test '#{test.name}'." if issue
67
+ puts "for test '#{test.name}'."
67
68
  end
68
69
 
69
70
  issue
@@ -22,7 +22,7 @@ module Gitlab
22
22
 
23
23
  private
24
24
 
25
- attr_reader :gitlab, :files, :project
25
+ attr_reader :gitlab, :files, :project, :issue_type
26
26
 
27
27
  def run!
28
28
  raise NotImplementedError
@@ -77,11 +77,18 @@ module Gitlab
77
77
  end
78
78
 
79
79
  def create_issue(test)
80
- gitlab.create_issue(
80
+ issue = gitlab.create_issue(
81
81
  title: title_from_test(test),
82
82
  description: new_issue_description(test),
83
- labels: new_issue_labels(test).to_a
83
+ labels: new_issue_labels(test).to_a,
84
+ issue_type: issue_type
84
85
  )
86
+
87
+ new_link = issue_type == 'test_case' ? issue.web_url.sub('/issues/', '/quality/test_cases/') : issue.web_url
88
+
89
+ puts "Created new #{issue_type}: #{new_link}"
90
+
91
+ issue
85
92
  end
86
93
 
87
94
  def issue_labels(issue)
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Report
6
+ # Uses the API to create or update GitLab test cases and issues with the results of tests from RSpec report files.
7
+ class ReportResults < ReportAsIssue
8
+ # TODO: Remove old_testcase_project_reporter once all test case links are updated to the gitlab project. See https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1079
9
+ attr_accessor :testcase_project_reporter, :results_issue_project_reporter, :files, :test_case_project, :results_issue_project, :gitlab, :old_testcase_project_reporter
10
+
11
+ def initialize(token:, input_files:, test_case_project:, results_issue_project:, dry_run: false, **kwargs)
12
+ @testcase_project_reporter = Gitlab::QA::Report::ResultsInTestCases.new(token: token, input_files: input_files, project: test_case_project, dry_run: dry_run, **kwargs)
13
+ # TODO: Remove the line below once all test case links are updated to the gitlab project. See https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1079
14
+ @old_testcase_project_reporter = Gitlab::QA::Report::ResultsInTestCases.new(token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
15
+ @results_issue_project_reporter = Gitlab::QA::Report::ResultsInIssues.new(token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
16
+ @test_case_project = test_case_project
17
+ @results_issue_project = results_issue_project
18
+ @files = Array(input_files)
19
+ @gitlab = testcase_project_reporter.gitlab
20
+ end
21
+
22
+ def assert_project!
23
+ return if test_case_project && results_issue_project
24
+
25
+ abort "Please provide valid project IDs or paths with the `--results-issue-project` and `--test-case-project` options!"
26
+ end
27
+
28
+ def run!
29
+ puts "Reporting test results in `#{files.join(',')}` as test cases in project `#{test_case_project}`"\
30
+ " and issues in project `#{results_issue_project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
31
+
32
+ test_results_per_file do |test_results|
33
+ puts "Reporting tests in #{test_results.path}"
34
+
35
+ test_results.each do |test|
36
+ puts "Reporting test: #{test.file} | #{test.name}\n"
37
+
38
+ report_test(test) unless test.skipped
39
+ end
40
+
41
+ test_results.write
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def report_test(test)
48
+ # TODO: Remove the line below and replace correct_testcase_project_reporter with testcase_project_reporter
49
+ # once all test case links are updated to the gitlab project. See https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1079
50
+ correct_testcase_project_reporter = using_old_testcase_link(test) ? old_testcase_project_reporter : testcase_project_reporter
51
+
52
+ testcase = correct_testcase_project_reporter.find_or_create_testcase(test)
53
+ # The API returns the test case with an issue URL since it is technically a type of issue.
54
+ # This updates the URL to a valid test case link.
55
+ test.testcase = testcase.web_url.sub('/issues/', '/quality/test_cases/')
56
+
57
+ issue, is_new = results_issue_project_reporter.get_related_issue(testcase, test)
58
+
59
+ correct_testcase_project_reporter.add_issue_link_to_testcase(testcase, issue, test) if is_new
60
+
61
+ correct_testcase_project_reporter.update_testcase(testcase, test)
62
+ results_issue_project_reporter.update_issue(issue, test)
63
+ end
64
+
65
+ def using_old_testcase_link(test)
66
+ test.testcase.include?(results_issue_project)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,124 +1,62 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'nokogiri'
4
- require 'active_support/core_ext/enumerable'
5
-
6
3
  module Gitlab
7
4
  module QA
8
5
  module Report
9
- # Uses the API to create or update GitLab issues with the results of tests from RSpec report files.
6
+ # Uses the API to create or update GitLab test result issues with the results of tests from RSpec report files.
10
7
  class ResultsInIssues < ReportAsIssue
11
- private
12
-
13
- RESULTS_SECTION_TEMPLATE = "\n\n### DO NOT EDIT BELOW THIS LINE\n\nActive and historical test results:"
14
-
15
- def run!
16
- puts "Reporting test results in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
17
-
18
- test_results_per_file do |test_results|
19
- puts "Reporting tests in #{test_results.path}"
8
+ include ResultsReporterShared
20
9
 
21
- test_results.each do |test|
22
- puts "Reporting test: #{test.file} | #{test.name}\n"
23
-
24
- report_test(test) unless test.skipped
25
- end
26
-
27
- test_results.write
28
- end
10
+ def initialize(**kwargs)
11
+ super
12
+ @issue_type = 'issue'
29
13
  end
30
14
 
31
- def report_test(test)
32
- testcase = find_testcase(test) || create_testcase(test)
33
- test.testcase ||= testcase.web_url.sub('/issues/', '/quality/test_cases/')
34
-
15
+ def get_related_issue(testcase, test)
35
16
  issue = find_linked_results_issue_by_iid(testcase, test)
17
+ is_new = false
36
18
 
37
19
  if issue
38
- issue = update_issue_title(issue, test, 'issue') if issue_title_needs_updating?(issue, test)
20
+ issue = update_issue_title(issue, test) if issue_title_needs_updating?(issue, test)
39
21
  else
40
22
  puts "No valid issue link found"
41
23
  issue = find_or_create_results_issue(test)
42
-
43
- add_issue_to_testcase(testcase, issue)
24
+ is_new = true
44
25
  end
45
26
 
46
- update_labels(testcase, test)
47
- update_issue(issue, test)
27
+ [issue, is_new]
48
28
  end
49
29
 
50
- def find_testcase(test)
51
- testcase = find_testcase_by_iid(test)
30
+ def update_issue(issue, test)
31
+ new_labels = issue_labels(issue)
32
+ new_labels |= ['Testcase Linked']
33
+
34
+ labels_updated = update_labels(issue, test, new_labels)
35
+ note_posted = note_status(issue, test)
52
36
 
53
- if testcase
54
- testcase = update_issue_title(testcase, test, 'test_case') if issue_title_needs_updating?(testcase, test)
37
+ if labels_updated || note_posted
38
+ puts "Issue updated."
55
39
  else
56
- testcase = find_issue(test, 'test_case')
40
+ puts "Test passed, no results issue update needed."
57
41
  end
58
-
59
- testcase
60
42
  end
61
43
 
62
- def find_testcase_by_iid(test)
63
- iid = testcase_iid_from_url(test.testcase)
64
-
65
- return unless iid
66
-
67
- find_issue_by_iid(iid, 'test_case')
68
- end
69
-
70
- def issue_title_needs_updating?(issue, test)
71
- issue.title.strip != title_from_test(test) && !%w[canary production preprod release].include?(pipeline)
72
- end
44
+ private
73
45
 
74
46
  def find_linked_results_issue_by_iid(testcase, test)
75
47
  iid = issue_iid_from_testcase(testcase)
76
48
 
77
49
  return unless iid
78
50
 
79
- find_issue_by_iid(iid, 'issue')
51
+ find_issue_by_iid(iid)
80
52
  end
81
53
 
82
- def find_issue_by_iid(iid, issue_type)
83
- issues = gitlab.find_issues(iid: iid) do |issue|
84
- issue.state == 'opened' && issue.issue_type == issue_type
85
- end
86
-
87
- warn(%(#{issue_type} iid "#{iid}" not valid)) if issues.empty?
88
-
89
- issues.first
90
- end
91
-
92
- def update_issue_title(issue, test, issue_type)
93
- warn(%(#{issue_type} title needs to be updated from '#{issue.title.strip}' to '#{title_from_test(test)}'))
94
-
95
- gitlab.edit_issue(iid: issue.iid, options: { title: title_from_test(test) })
96
- end
97
-
98
- def create_testcase(test)
99
- title = title_from_test(test)
100
- puts "Creating test case '#{title}' ..."
101
-
102
- gitlab.create_issue(
103
- title: title,
104
- description: new_testcase_description(test),
105
- labels: new_issue_labels(test),
106
- issue_type: 'test_case'
107
- )
108
- end
109
-
110
- def testcase_iid_from_url(url)
111
- return warn(%(\nPlease update #{url} to test case url")) if url&.include?('/-/issues/')
112
-
113
- url && url.split('/').last.to_i
114
- end
115
-
116
- def new_testcase_description(test)
117
- "#{new_issue_description(test)}#{RESULTS_SECTION_TEMPLATE}"
54
+ def find_or_create_results_issue(test)
55
+ find_issue(test) || create_issue(test)
118
56
  end
119
57
 
120
58
  def issue_iid_from_testcase(testcase)
121
- results = testcase.description.partition(RESULTS_SECTION_TEMPLATE).last if testcase.description.include?(RESULTS_SECTION_TEMPLATE)
59
+ results = testcase.description.partition(TEST_CASE_RESULTS_SECTION_TEMPLATE).last if testcase.description.include?(TEST_CASE_RESULTS_SECTION_TEMPLATE)
122
60
 
123
61
  return puts "No issue link found" unless results
124
62
 
@@ -127,66 +65,6 @@ module Gitlab
127
65
  issue_iid&.to_i
128
66
  end
129
67
 
130
- def find_or_create_results_issue(test)
131
- issue = find_issue(test, 'issue')
132
-
133
- if issue
134
- puts "Found existing issue: #{issue.web_url}"
135
- else
136
- issue = create_issue(test)
137
- puts "Created new issue: #{issue.web_url}"
138
- end
139
-
140
- issue
141
- end
142
-
143
- def find_issue(test, issue_type)
144
- issues = gitlab.find_issues(options: { search: search_term(test) }) do |issue|
145
- issue.state == 'opened' && issue.issue_type == issue_type && issue.title.strip == title_from_test(test)
146
- end
147
-
148
- warn(%(Too many #{issue_type}s found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
149
-
150
- issues.first
151
- end
152
-
153
- def add_issue_to_testcase(testcase, issue)
154
- results_section = testcase.description.include?(RESULTS_SECTION_TEMPLATE) ? '' : RESULTS_SECTION_TEMPLATE
155
-
156
- gitlab.edit_issue(iid: testcase.iid, options: { description: (testcase.description + results_section + "\n\n#{issue.web_url}") })
157
-
158
- puts "Added issue #{issue.web_url} to testcase #{testcase.web_url}"
159
- end
160
-
161
- def update_issue(issue, test)
162
- new_labels = issue_labels(issue)
163
- new_labels |= ['Testcase Linked']
164
-
165
- labels_updated = update_labels(issue, test, new_labels)
166
- note_posted = note_status(issue, test)
167
-
168
- if labels_updated || note_posted
169
- puts "Issue updated."
170
- else
171
- puts "Test passed, no update needed."
172
- end
173
- end
174
-
175
- def new_issue_labels(test)
176
- ['Quality', "devops::#{test.stage}", 'status::automated']
177
- end
178
-
179
- def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
180
- labels = super
181
- labels |= new_issue_labels(test).to_set
182
- labels.delete_if { |label| label.start_with?("#{pipeline}::") }
183
- labels << (test.failures.empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
184
- end
185
-
186
- def search_term(test)
187
- %("#{partial_file_path(test.file)}" "#{search_safe(test.name)}")
188
- end
189
-
190
68
  def note_status(issue, test)
191
69
  return false if test.skipped
192
70
  return false if test.failures.empty?
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Report
6
+ # Uses the API to create or update GitLab test cases with the results of tests from RSpec report files.
7
+ class ResultsInTestCases < ReportAsIssue
8
+ attr_reader :issue_type, :gitlab
9
+
10
+ include ResultsReporterShared
11
+
12
+ def initialize(**kwargs)
13
+ super
14
+ @issue_type = 'test_case'
15
+ end
16
+
17
+ def find_or_create_testcase(test)
18
+ find_testcase(test) || create_issue(test)
19
+ end
20
+
21
+ def add_issue_link_to_testcase(testcase, issue, test)
22
+ results_section = testcase.description.include?(TEST_CASE_RESULTS_SECTION_TEMPLATE) ? '' : TEST_CASE_RESULTS_SECTION_TEMPLATE
23
+
24
+ gitlab.edit_issue(iid: testcase.iid, options: { description: (testcase.description + results_section + "\n\n#{issue.web_url}") })
25
+ # We are using test.testcase for the url here instead of testcase.web_url since it has the updated test case path
26
+ puts "Added results issue #{issue.web_url} link to test case #{test.testcase}"
27
+ end
28
+
29
+ def update_testcase(testcase, test)
30
+ puts "Test case labels updated." if update_labels(testcase, test)
31
+ end
32
+
33
+ private
34
+
35
+ def find_testcase(test)
36
+ testcase = find_testcase_by_iid(test)
37
+
38
+ if testcase
39
+ testcase = update_issue_title(testcase, test) if issue_title_needs_updating?(testcase, test)
40
+ else
41
+ testcase = find_issue(test)
42
+ end
43
+
44
+ testcase
45
+ end
46
+
47
+ def find_testcase_by_iid(test)
48
+ iid = testcase_iid_from_url(test.testcase)
49
+
50
+ return unless iid
51
+
52
+ find_issue_by_iid(iid)
53
+ end
54
+
55
+ def testcase_iid_from_url(url)
56
+ return warn(%(\nPlease update #{url} to test case url")) if url&.include?('/-/issues/')
57
+
58
+ url && url.split('/').last.to_i
59
+ end
60
+
61
+ def new_issue_description(test)
62
+ "#{super}#{TEST_CASE_RESULTS_SECTION_TEMPLATE}"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/enumerable'
4
+
5
+ module Gitlab
6
+ module QA
7
+ module Report
8
+ module ResultsReporterShared
9
+ TEST_CASE_RESULTS_SECTION_TEMPLATE = "\n\n### DO NOT EDIT BELOW THIS LINE\n\nActive and historical test results:"
10
+
11
+ def find_issue(test)
12
+ issues = search_for_issues(test)
13
+
14
+ warn(%(Too many #{issue_type}s found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
15
+ puts "Found existing #{issue_type}: #{issues.first.web_url}" unless issues.empty?
16
+
17
+ issues.first
18
+ end
19
+
20
+ def find_issue_by_iid(iid)
21
+ issues = gitlab.find_issues(iid: iid) do |issue|
22
+ issue.state == 'opened' && issue.issue_type == issue_type
23
+ end
24
+
25
+ warn(%(#{issue_type} iid "#{iid}" not valid)) if issues.empty?
26
+
27
+ issues.first
28
+ end
29
+
30
+ def issue_title_needs_updating?(issue, test)
31
+ issue.title.strip != title_from_test(test) && !%w[canary production preprod release].include?(pipeline)
32
+ end
33
+
34
+ def new_issue_labels(test)
35
+ ['Quality', "devops::#{test.stage}", 'status::automated']
36
+ end
37
+
38
+ def search_term(test)
39
+ %("#{partial_file_path(test.file)}" "#{search_safe(test.name)}")
40
+ end
41
+
42
+ def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
43
+ labels = super
44
+ labels |= new_issue_labels(test).to_set
45
+ labels.delete_if { |label| label.start_with?("#{pipeline}::") }
46
+ labels << (test.failures.empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
47
+ end
48
+
49
+ def update_issue_title(issue, test)
50
+ warn(%(#{issue_type} title needs to be updated from '#{issue.title.strip}' to '#{title_from_test(test)}'))
51
+
52
+ gitlab.edit_issue(iid: issue.iid, options: { title: title_from_test(test) })
53
+ end
54
+
55
+ private
56
+
57
+ def search_for_issues(test)
58
+ gitlab.find_issues(options: { search: search_term(test) }) do |issue|
59
+ issue.state == 'opened' && issue.issue_type == issue_type && issue.title.strip == title_from_test(test)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -17,8 +17,8 @@ module Gitlab
17
17
  report_options[:input_files] = files if files
18
18
  end
19
19
 
20
- opts.on('--report-in-issues FILES', String, 'Report test results from JUnit XML files in GitLab issues') do |files|
21
- report_options[:report_in_issues] = true
20
+ opts.on('--report-results FILES', String, 'Report test results from JUnit XML files in GitLab test cases and results issues') do |files|
21
+ report_options[:report_results] = true
22
22
  report_options[:input_files] = files if files
23
23
  end
24
24
 
@@ -31,16 +31,24 @@ module Gitlab
31
31
  report_options[:max_diff_ratio] = value
32
32
  end
33
33
 
34
- opts.on('-p', '--project PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --report-in-issues and --relate-failure-issue') do |value|
34
+ opts.on('-p', '--project PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --relate-failure-issue') do |value|
35
35
  report_options[:project] = value
36
36
  end
37
37
 
38
+ opts.on('--results-issue-project RESULTS_ISSUE_PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --report-results') do |value|
39
+ report_options[:results_issue_project] = value
40
+ end
41
+
42
+ opts.on('--test-case-project TEST_CASE_PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --report-results') do |value|
43
+ report_options[:test_case_project] = value
44
+ end
45
+
38
46
  opts.on('--generate-test-session FILES', String, 'Generate test session report') do |files|
39
47
  report_options[:generate_test_session] = true
40
48
  report_options[:input_files] = files if files
41
49
  end
42
50
 
43
- opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token. Required by --report-in-issues and --relate-failure-issue') do |value|
51
+ opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token. Required by --report-results and --relate-failure-issue') do |value|
44
52
  report_options[:token] = value
45
53
  end
46
54
 
@@ -60,7 +68,7 @@ module Gitlab
60
68
  report_options[:files] = files
61
69
  end
62
70
 
63
- opts.on('--dry-run', "Perform a dry-run (don't create or update issues)") do |files|
71
+ opts.on('--dry-run', "Perform a dry-run (don't create or update issues or test cases)") do |files|
64
72
  report_options[:dry_run] = true
65
73
  end
66
74
 
@@ -86,9 +94,9 @@ module Gitlab
86
94
  report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
87
95
  Gitlab::QA::Report::RelateFailureIssue.new(**report_options).invoke!
88
96
 
89
- elsif report_options.delete(:report_in_issues)
97
+ elsif report_options.delete(:report_results)
90
98
  report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
91
- Gitlab::QA::Report::ResultsInIssues.new(**report_options).invoke!
99
+ Gitlab::QA::Report::ReportResults.new(**report_options).invoke!
92
100
 
93
101
  elsif report_options.delete(:generate_test_session)
94
102
  report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module QA
3
- VERSION = '7.15.1'.freeze
3
+ VERSION = '7.16.0'.freeze
4
4
  end
5
5
  end
data/lib/gitlab/qa.rb CHANGED
@@ -123,7 +123,10 @@ module Gitlab
123
123
  autoload :JUnitTestResults, 'gitlab/qa/report/junit_test_results'
124
124
  autoload :PrepareStageReports, 'gitlab/qa/report/prepare_stage_reports'
125
125
  autoload :ReportAsIssue, 'gitlab/qa/report/report_as_issue'
126
+ autoload :ReportResults, 'gitlab/qa/report/report_results'
126
127
  autoload :ResultsInIssues, 'gitlab/qa/report/results_in_issues'
128
+ autoload :ResultsInTestCases, 'gitlab/qa/report/results_in_testcases'
129
+ autoload :ResultsReporterShared, 'gitlab/qa/report/results_reporter_shared'
127
130
  autoload :GenerateTestSession, 'gitlab/qa/report/generate_test_session'
128
131
  autoload :SummaryTable, 'gitlab/qa/report/summary_table'
129
132
  autoload :TestResult, 'gitlab/qa/report/test_result'
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: 7.15.1
4
+ version: 7.16.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: 2021-12-02 00:00:00.000000000 Z
11
+ date: 2021-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -256,7 +256,10 @@ files:
256
256
  - lib/gitlab/qa/report/prepare_stage_reports.rb
257
257
  - lib/gitlab/qa/report/relate_failure_issue.rb
258
258
  - lib/gitlab/qa/report/report_as_issue.rb
259
+ - lib/gitlab/qa/report/report_results.rb
259
260
  - lib/gitlab/qa/report/results_in_issues.rb
261
+ - lib/gitlab/qa/report/results_in_testcases.rb
262
+ - lib/gitlab/qa/report/results_reporter_shared.rb
260
263
  - lib/gitlab/qa/report/summary_table.rb
261
264
  - lib/gitlab/qa/report/test_result.rb
262
265
  - lib/gitlab/qa/report/update_screenshot_path.rb