gitlab-qa 7.15.1 → 7.16.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: 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