gitlab_quality-test_tooling 2.6.0 → 2.8.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/gitlab_quality/test_tooling/gitlab_client/gitlab_client.rb +4 -3
- data/lib/gitlab_quality/test_tooling/gitlab_client/issues_client.rb +24 -0
- data/lib/gitlab_quality/test_tooling/report/concerns/group_and_category_labels.rb +5 -11
- data/lib/gitlab_quality/test_tooling/report/concerns/utils.rb +4 -0
- data/lib/gitlab_quality/test_tooling/report/failed_test_issue.rb +9 -5
- data/lib/gitlab_quality/test_tooling/report/flaky_test_issue.rb +15 -7
- data/lib/gitlab_quality/test_tooling/report/health_problem_reporter.rb +18 -7
- data/lib/gitlab_quality/test_tooling/report/knapsack_report_issue.rb +4 -0
- data/lib/gitlab_quality/test_tooling/report/relate_failure_issue.rb +143 -9
- data/lib/gitlab_quality/test_tooling/report/report_as_issue.rb +3 -0
- data/lib/gitlab_quality/test_tooling/report/slow_test_issue.rb +11 -3
- data/lib/gitlab_quality/test_tooling/runtime/env.rb +3 -1
- data/lib/gitlab_quality/test_tooling/test_result/base_test_result.rb +3 -1
- data/lib/gitlab_quality/test_tooling/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: 8547ed9407707737f7d776f263543f3681e19706d7705591968f2e0ec348ed88
|
4
|
+
data.tar.gz: 84f1fb8007ce5c5dd96a1782cfa7b75207d456df2b9c163ddde5900f3efe6ad2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43e26da079892ae22a44025b4c96a076b65499e1ab1a5574da130132e9c70358ed12ae9ba123bb645b757b8e177bb59c11fd036f5e8d9d14e22620c5c0616958
|
7
|
+
data.tar.gz: f236ba27bc98161951cc4d98e4ff22321eeee476b6e305c0b67e2d58b09f6329a0361c9d834c20ff3efa86b41f5763733eb278c755fffa1e5fa49d25c556c1a9
|
data/Gemfile.lock
CHANGED
@@ -9,10 +9,11 @@ module GitlabQuality
|
|
9
9
|
RETRY_BACK_OFF_DELAY = 60
|
10
10
|
MAX_RETRY_ATTEMPTS = 3
|
11
11
|
|
12
|
-
def initialize(token:, project:, **_kwargs)
|
12
|
+
def initialize(token:, project:, endpoint: nil, **_kwargs)
|
13
13
|
@token = token
|
14
14
|
@project = project
|
15
15
|
@retry_backoff = 0
|
16
|
+
@endpoint = endpoint
|
16
17
|
end
|
17
18
|
|
18
19
|
def handle_gitlab_client_exceptions
|
@@ -76,11 +77,11 @@ module GitlabQuality
|
|
76
77
|
|
77
78
|
private
|
78
79
|
|
79
|
-
attr_reader :project, :token
|
80
|
+
attr_reader :project, :token, :endpoint
|
80
81
|
|
81
82
|
def client
|
82
83
|
@client ||= Gitlab.client(
|
83
|
-
endpoint: Runtime::Env.gitlab_api_base,
|
84
|
+
endpoint: endpoint || Runtime::Env.gitlab_api_base,
|
84
85
|
private_token: token
|
85
86
|
)
|
86
87
|
end
|
@@ -128,6 +128,12 @@ module GitlabQuality
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
+
def find_commit(project, sha)
|
132
|
+
handle_gitlab_client_exceptions do
|
133
|
+
client.commit(project, sha)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
131
137
|
def find_commit_parent(project, sha)
|
132
138
|
handle_gitlab_client_exceptions do
|
133
139
|
# In a merged results commit, the first parent is the one from
|
@@ -137,6 +143,24 @@ module GitlabQuality
|
|
137
143
|
end
|
138
144
|
end
|
139
145
|
|
146
|
+
def find_commit_diff(project, sha)
|
147
|
+
handle_gitlab_client_exceptions do
|
148
|
+
client.commit_diff(project, sha)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def find_deployments(project, environment:, status:, order_by: 'id', sort: 'desc')
|
153
|
+
handle_gitlab_client_exceptions do
|
154
|
+
client.deployments(
|
155
|
+
project,
|
156
|
+
environment: environment,
|
157
|
+
status: status,
|
158
|
+
order_by: order_by,
|
159
|
+
sort: sort
|
160
|
+
)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
140
164
|
private
|
141
165
|
|
142
166
|
attr_reader :token, :project
|
@@ -5,20 +5,14 @@ module GitlabQuality
|
|
5
5
|
module Report
|
6
6
|
module Concerns
|
7
7
|
module GroupAndCategoryLabels
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def new_issue_labels(test)
|
13
|
-
debug_line = ' => [DEBUG] '
|
14
|
-
debug_line += "product_group: #{test&.product_group}; " if test.respond_to?(:product_group)
|
15
|
-
debug_line += "feature_category: #{test&.feature_category}" if test.respond_to?(:feature_category)
|
16
|
-
puts debug_line
|
8
|
+
def group_and_category_labels_for_test(test)
|
9
|
+
labels_inference = GitlabQuality::TestTooling::LabelsInference.new
|
10
|
+
new_labels = Set.new
|
17
11
|
|
18
|
-
new_labels = self.class::NEW_ISSUE_LABELS
|
19
12
|
new_labels += labels_inference.infer_labels_from_product_group(test.product_group) if test.respond_to?(:product_group)
|
20
13
|
new_labels += labels_inference.infer_labels_from_feature_category(test.feature_category) if test.respond_to?(:feature_category)
|
21
|
-
|
14
|
+
|
15
|
+
new_labels
|
22
16
|
end
|
23
17
|
end
|
24
18
|
end
|
@@ -15,6 +15,10 @@ module GitlabQuality
|
|
15
15
|
"#{title[...MAX_TITLE_LENGTH - 3]}..."
|
16
16
|
end
|
17
17
|
|
18
|
+
def label_names_to_label_quick_action(label_names)
|
19
|
+
%(/label #{label_names.map { |label| %(~"#{label}") }.join(' ')})
|
20
|
+
end
|
21
|
+
|
18
22
|
def new_issue_title(test)
|
19
23
|
"[Test] #{partial_file_path(test.file)} | #{search_safe(test.name)}".strip
|
20
24
|
end
|
@@ -57,7 +57,7 @@ module GitlabQuality
|
|
57
57
|
current_reports_note = find_failure_discussion_note(issue: issue, test: test, reports_discussion: reports_discussion)
|
58
58
|
|
59
59
|
new_reports_list = new_reports_list(current_reports_note: current_reports_note, test: test)
|
60
|
-
note_body =
|
60
|
+
note_body = append_quick_actions_to_note(
|
61
61
|
new_reports_list: new_reports_list,
|
62
62
|
related_issues: related_issues,
|
63
63
|
options: {
|
@@ -105,6 +105,14 @@ module GitlabQuality
|
|
105
105
|
IDENTITY_LABELS
|
106
106
|
end
|
107
107
|
|
108
|
+
def new_issue_labels(test)
|
109
|
+
up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS + group_and_category_labels_for_test(test))
|
110
|
+
end
|
111
|
+
|
112
|
+
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
113
|
+
(base_issue_labels + super).to_a
|
114
|
+
end
|
115
|
+
|
108
116
|
def report_section_header
|
109
117
|
REPORT_SECTION_HEADER
|
110
118
|
end
|
@@ -139,10 +147,6 @@ module GitlabQuality
|
|
139
147
|
quick_actions.join("\n")
|
140
148
|
end
|
141
149
|
|
142
|
-
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
143
|
-
(base_issue_labels + super).to_a
|
144
|
-
end
|
145
|
-
|
146
150
|
def find_failure_discussion_note(issue:, test:, reports_discussion:)
|
147
151
|
return unless reports_discussion
|
148
152
|
|
@@ -44,6 +44,14 @@ module GitlabQuality
|
|
44
44
|
IDENTITY_LABELS
|
45
45
|
end
|
46
46
|
|
47
|
+
def new_issue_labels(test)
|
48
|
+
up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS)
|
49
|
+
end
|
50
|
+
|
51
|
+
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
52
|
+
(base_issue_labels + super).to_a
|
53
|
+
end
|
54
|
+
|
47
55
|
def report_section_header
|
48
56
|
REPORT_SECTION_HEADER
|
49
57
|
end
|
@@ -52,22 +60,22 @@ module GitlabQuality
|
|
52
60
|
REPORTS_DOCUMENTATION
|
53
61
|
end
|
54
62
|
|
55
|
-
def health_problem_status_label_quick_action(reports_list,
|
63
|
+
def health_problem_status_label_quick_action(reports_list, options: {})
|
56
64
|
case reports_list.reports_count
|
57
65
|
when 399..Float::INFINITY
|
58
|
-
'
|
66
|
+
label_names = Set.new(['flakiness::1'])
|
67
|
+
label_names += group_and_category_labels_for_test(options[:test]) if options.key?(:test)
|
68
|
+
label_names_to_label_quick_action(label_names)
|
59
69
|
when 37..398
|
60
|
-
'
|
70
|
+
label_names = Set.new(['flakiness::2'])
|
71
|
+
label_names += group_and_category_labels_for_test(options[:test]) if options.key?(:test)
|
72
|
+
label_names_to_label_quick_action(label_names)
|
61
73
|
when 13..36
|
62
74
|
'/label ~"flakiness::3"'
|
63
75
|
else
|
64
76
|
'/label ~"flakiness::4"'
|
65
77
|
end
|
66
78
|
end
|
67
|
-
|
68
|
-
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
69
|
-
(base_issue_labels + super).to_a
|
70
|
-
end
|
71
79
|
end
|
72
80
|
end
|
73
81
|
end
|
@@ -45,6 +45,10 @@ module GitlabQuality
|
|
45
45
|
[]
|
46
46
|
end
|
47
47
|
|
48
|
+
def new_issue_labels(_test)
|
49
|
+
[]
|
50
|
+
end
|
51
|
+
|
48
52
|
def search_labels
|
49
53
|
BASE_SEARCH_LABELS
|
50
54
|
end
|
@@ -57,10 +61,6 @@ module GitlabQuality
|
|
57
61
|
''
|
58
62
|
end
|
59
63
|
|
60
|
-
def health_problem_status_label_quick_action(*)
|
61
|
-
''
|
62
|
-
end
|
63
|
-
|
64
64
|
def item_extra_content(_test)
|
65
65
|
found_label
|
66
66
|
end
|
@@ -115,7 +115,13 @@ module GitlabQuality
|
|
115
115
|
current_reports_note = existing_reports_note(issue_iid: issue.iid)
|
116
116
|
|
117
117
|
new_reports_list = new_reports_list(current_reports_note: current_reports_note, test: test)
|
118
|
-
note_body =
|
118
|
+
note_body = append_quick_actions_to_note(
|
119
|
+
new_reports_list: new_reports_list,
|
120
|
+
related_issues: related_issues,
|
121
|
+
options: {
|
122
|
+
test: test
|
123
|
+
}
|
124
|
+
)
|
119
125
|
|
120
126
|
if current_reports_note
|
121
127
|
gitlab.edit_issue_note(
|
@@ -138,7 +144,7 @@ module GitlabQuality
|
|
138
144
|
)
|
139
145
|
end
|
140
146
|
|
141
|
-
def
|
147
|
+
def append_quick_actions_to_note(new_reports_list:, related_issues:, options: {})
|
142
148
|
report = new_reports_list
|
143
149
|
|
144
150
|
quick_actions = [
|
@@ -164,10 +170,15 @@ module GitlabQuality
|
|
164
170
|
end
|
165
171
|
end
|
166
172
|
|
173
|
+
# Defined in subclasses
|
174
|
+
def health_problem_status_label_quick_action(*)
|
175
|
+
''
|
176
|
+
end
|
177
|
+
|
167
178
|
def identity_labels_quick_action
|
168
179
|
return if identity_labels.empty?
|
169
180
|
|
170
|
-
|
181
|
+
label_names_to_label_quick_action(identity_labels)
|
171
182
|
end
|
172
183
|
|
173
184
|
def relate_issues_quick_actions(issues)
|
@@ -39,6 +39,10 @@ module GitlabQuality
|
|
39
39
|
search_and_create_issue
|
40
40
|
end
|
41
41
|
|
42
|
+
def new_issue_labels(test)
|
43
|
+
up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS + group_and_category_labels_for_test(test))
|
44
|
+
end
|
45
|
+
|
42
46
|
def search_and_create_issue
|
43
47
|
filtered_report = KnapsackReports::SpecRunTimeReport.new(
|
44
48
|
token: token,
|
@@ -33,6 +33,21 @@ module GitlabQuality
|
|
33
33
|
'gitlab-org/customers-gitlab-com' => 'gitlab-org/customers-gitlab-com'
|
34
34
|
}.freeze
|
35
35
|
|
36
|
+
# The project contains record of the deployments we use to determine the commit diff
|
37
|
+
OPS_RELEASES_METADATA_PROJECT = 'gitlab-org/release/metadata'
|
38
|
+
|
39
|
+
# Naming of the environments are different between `gitlab-org/release/metadata` and `gitlab-org/quality`
|
40
|
+
# This maps the gitlab-org/quality environment names to the equivalent in `gitlab-org/release/metadata`
|
41
|
+
ENVIRONMENT_MAPPING = {
|
42
|
+
'production' => 'gprd',
|
43
|
+
'canary' => 'gprd-cny',
|
44
|
+
'staging' => 'gstg',
|
45
|
+
'staging-canary' => 'gstg-cny',
|
46
|
+
'staging-ref' => 'gstg-ref',
|
47
|
+
'preprod' => 'pre',
|
48
|
+
'release' => 'release'
|
49
|
+
}.freeze
|
50
|
+
|
36
51
|
MultipleIssuesFound = Class.new(StandardError)
|
37
52
|
|
38
53
|
def initialize(
|
@@ -54,7 +69,7 @@ module GitlabQuality
|
|
54
69
|
|
55
70
|
private
|
56
71
|
|
57
|
-
attr_reader :max_diff_ratio, :system_logs, :base_issue_labels, :exclude_labels_for_search, :metrics_files
|
72
|
+
attr_reader :max_diff_ratio, :system_logs, :base_issue_labels, :exclude_labels_for_search, :metrics_files, :ops_gitlab_client
|
58
73
|
|
59
74
|
def run!
|
60
75
|
puts "Reporting test failures in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
|
@@ -65,6 +80,14 @@ module GitlabQuality
|
|
65
80
|
end
|
66
81
|
end
|
67
82
|
|
83
|
+
def new_issue_labels(test)
|
84
|
+
up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS + group_and_category_labels_for_test(test))
|
85
|
+
end
|
86
|
+
|
87
|
+
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
88
|
+
(Set.new(base_issue_labels) + (super << pipeline_name_label)).to_a
|
89
|
+
end
|
90
|
+
|
68
91
|
def test_metric_collections
|
69
92
|
@test_metric_collections ||= Dir.glob(metrics_files).map do |path|
|
70
93
|
TestMetrics::JsonTestMetricCollection.new(path)
|
@@ -278,7 +301,7 @@ module GitlabQuality
|
|
278
301
|
|
279
302
|
def new_issue_description(test)
|
280
303
|
super + [
|
281
|
-
"\n#{
|
304
|
+
"\n#{commit_diff_section}",
|
282
305
|
"### Stack trace",
|
283
306
|
"```\n#{test.full_stacktrace}\n```",
|
284
307
|
screenshot_section(test),
|
@@ -287,8 +310,123 @@ module GitlabQuality
|
|
287
310
|
].compact.join("\n\n")
|
288
311
|
end
|
289
312
|
|
290
|
-
def
|
291
|
-
|
313
|
+
def commit_diff_section
|
314
|
+
"### Commit diff\n#{generate_diff_link}"
|
315
|
+
end
|
316
|
+
|
317
|
+
def generate_diff_link
|
318
|
+
initialize_gitlab_ops_client
|
319
|
+
|
320
|
+
if Runtime::Env.ci_pipeline_url.include?('ops.gitlab.net')
|
321
|
+
pipeline = ops_gitlab_client.find_pipeline(project, Runtime::Env.ci_pipeline_id.to_i)
|
322
|
+
generate_ops_gitlab_diff(pipeline)
|
323
|
+
else
|
324
|
+
pipeline = gitlab.find_pipeline(project, Runtime::Env.ci_pipeline_id.to_i)
|
325
|
+
generate_gitlab_diff(pipeline)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def generate_ops_gitlab_diff(pipeline)
|
330
|
+
deployment_info = fetch_deployment_info(pipeline)
|
331
|
+
|
332
|
+
return deployment_info if deployment_info.is_a?(String)
|
333
|
+
|
334
|
+
source_gitlab_ee_sha = fetch_deployment_gitlab_ee_sha(ops_gitlab_client, deployment_info[:source].sha)
|
335
|
+
target_gitlab_ee_sha = fetch_deployment_gitlab_ee_sha(ops_gitlab_client, deployment_info[:target].sha)
|
336
|
+
|
337
|
+
if source_gitlab_ee_sha == target_gitlab_ee_sha
|
338
|
+
"No diff"
|
339
|
+
else
|
340
|
+
"https://gitlab.com/gitlab-org/security/gitlab/-/compare/#{target_gitlab_ee_sha}...#{source_gitlab_ee_sha}"
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def fetch_deployment_info(pipeline)
|
345
|
+
pipeline_deploy_version = Runtime::Env.ci_pipeline_name.match(/(\d+\.\d+\.\d+)(?:-|$)/)&.captures&.first
|
346
|
+
deployments = fetch_deployments(ops_gitlab_client, pipeline)
|
347
|
+
found_deployment = find_matching_deployment(pipeline_deploy_version, deployments)
|
348
|
+
|
349
|
+
return 'No matching deployment found to generate a diff link.' unless found_deployment
|
350
|
+
|
351
|
+
{
|
352
|
+
source: found_deployment[:deployment],
|
353
|
+
target: deployments[found_deployment[:index] + 1]
|
354
|
+
}
|
355
|
+
end
|
356
|
+
|
357
|
+
def fetch_deployments(client, pipeline)
|
358
|
+
ops_environment = pipeline.web_url.match(%r{gitlab-org/quality/([^/-]+(?:-[^/-]+)*?)(?:/-)?/pipelines})[1]
|
359
|
+
|
360
|
+
raise "Environment '#{ops_environment}' is not supported" unless ENVIRONMENT_MAPPING.key?(ops_environment)
|
361
|
+
|
362
|
+
environment = ENVIRONMENT_MAPPING[ops_environment]
|
363
|
+
|
364
|
+
client.find_deployments(
|
365
|
+
OPS_RELEASES_METADATA_PROJECT,
|
366
|
+
environment: environment,
|
367
|
+
status: 'success'
|
368
|
+
)
|
369
|
+
end
|
370
|
+
|
371
|
+
def initialize_gitlab_ops_client
|
372
|
+
@ops_gitlab_client = GitlabClient::IssuesClient.new(
|
373
|
+
endpoint: Runtime::Env.ci_api_v4_url,
|
374
|
+
token: Runtime::Env.gitlab_ci_token,
|
375
|
+
project: OPS_RELEASES_METADATA_PROJECT
|
376
|
+
)
|
377
|
+
end
|
378
|
+
|
379
|
+
def find_matching_deployment(pipeline_deploy_version, deployments)
|
380
|
+
return nil unless pipeline_deploy_version
|
381
|
+
return nil unless deployments
|
382
|
+
|
383
|
+
target_timestamp = extract_timestamp(pipeline_deploy_version)
|
384
|
+
return nil unless target_timestamp
|
385
|
+
|
386
|
+
matching_deployment = nil
|
387
|
+
|
388
|
+
deployments.each_with_index do |deployment, index|
|
389
|
+
deployment_version = extract_deployment_version(ops_gitlab_client, deployment)
|
390
|
+
next unless deployment_version
|
391
|
+
|
392
|
+
deployment_timestamp = extract_timestamp(deployment_version)
|
393
|
+
next unless deployment_timestamp
|
394
|
+
|
395
|
+
# Stop searching if the deployment timestamp is older than the target timestamp
|
396
|
+
break if deployment_timestamp && deployment_timestamp < target_timestamp
|
397
|
+
|
398
|
+
if deployment_version == pipeline_deploy_version
|
399
|
+
matching_deployment = { deployment: deployment, index: index }
|
400
|
+
break
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
matching_deployment
|
405
|
+
end
|
406
|
+
|
407
|
+
def extract_timestamp(version)
|
408
|
+
version.match(/\d{12}$/)&.to_s
|
409
|
+
end
|
410
|
+
|
411
|
+
def extract_deployment_version(client, deployment)
|
412
|
+
commit = client.find_commit(OPS_RELEASES_METADATA_PROJECT, deployment.sha)
|
413
|
+
version_match = commit.message&.match(/Product-Version: ([\d.]+)/)
|
414
|
+
version_match&.[](1)
|
415
|
+
end
|
416
|
+
|
417
|
+
def fetch_deployment_gitlab_ee_sha(client, deployment_sha)
|
418
|
+
commit_diff = client.find_commit_diff(OPS_RELEASES_METADATA_PROJECT, deployment_sha).first
|
419
|
+
diffs_content = commit_diff.diff.lines.select { |line| line.start_with?('+') }.map { |line| line[1..] }.join
|
420
|
+
|
421
|
+
begin
|
422
|
+
JSON.parse(diffs_content).dig('releases', 'gitlab-ee', 'sha')
|
423
|
+
rescue JSON::ParserError
|
424
|
+
raise "Failed to parse the diffs content"
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
def generate_gitlab_diff(pipeline)
|
429
|
+
pipeline_sha = pipeline.sha
|
292
430
|
parent_sha = gitlab.find_commit_parent(project, pipeline_sha)
|
293
431
|
diff_project = if DIFF_PROJECT_MAPPINGS.key?(project)
|
294
432
|
DIFF_PROJECT_MAPPINGS[project]
|
@@ -296,7 +434,7 @@ module GitlabQuality
|
|
296
434
|
raise "Project #{project} is not supported for commit diff links"
|
297
435
|
end
|
298
436
|
|
299
|
-
"
|
437
|
+
"https://gitlab.com/#{diff_project}/-/compare/#{parent_sha}...#{pipeline_sha}"
|
300
438
|
end
|
301
439
|
|
302
440
|
def system_log_errors_section(test)
|
@@ -318,10 +456,6 @@ module GitlabQuality
|
|
318
456
|
section
|
319
457
|
end
|
320
458
|
|
321
|
-
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
322
|
-
(Set.new(base_issue_labels) + (super << pipeline_name_label)).to_a
|
323
|
-
end
|
324
|
-
|
325
459
|
def new_issue_assignee_id(test)
|
326
460
|
return unless test.product_group?
|
327
461
|
|
@@ -144,6 +144,9 @@ module GitlabQuality
|
|
144
144
|
gitlab.edit_issue(iid: issue.iid, options: { labels: labels.to_a })
|
145
145
|
end
|
146
146
|
|
147
|
+
# Infer labels from the test, and optionally from the issue and new_labels in arguments
|
148
|
+
#
|
149
|
+
# Called when we're updating a test health issue with a new test report.
|
147
150
|
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
148
151
|
labels = issue_labels(issue)
|
149
152
|
labels |= new_labels.to_set
|
@@ -34,6 +34,10 @@ module GitlabQuality
|
|
34
34
|
IDENTITY_LABELS
|
35
35
|
end
|
36
36
|
|
37
|
+
def new_issue_labels(test)
|
38
|
+
up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS)
|
39
|
+
end
|
40
|
+
|
37
41
|
def report_section_header
|
38
42
|
REPORT_SECTION_HEADER
|
39
43
|
end
|
@@ -42,12 +46,16 @@ module GitlabQuality
|
|
42
46
|
REPORTS_DOCUMENTATION
|
43
47
|
end
|
44
48
|
|
45
|
-
def health_problem_status_label_quick_action(reports_list,
|
49
|
+
def health_problem_status_label_quick_action(reports_list, options: {})
|
46
50
|
case reports_list.reports_count
|
47
51
|
when 6099..Float::INFINITY
|
48
|
-
'
|
52
|
+
label_names = Set.new(['slowness::1'])
|
53
|
+
label_names += group_and_category_labels_for_test(options[:test]) if options.key?(:test)
|
54
|
+
label_names_to_label_quick_action(label_names)
|
49
55
|
when 2177..6098
|
50
|
-
'
|
56
|
+
label_names = Set.new(['slowness::2'])
|
57
|
+
label_names += group_and_category_labels_for_test(options[:test]) if options.key?(:test)
|
58
|
+
label_names_to_label_quick_action(label_names)
|
51
59
|
when 521..2176
|
52
60
|
'/label ~"slowness::3"'
|
53
61
|
else
|
@@ -19,9 +19,11 @@ module GitlabQuality
|
|
19
19
|
'CI_PROJECT_NAME' => :ci_project_name,
|
20
20
|
'CI_PROJECT_PATH' => :ci_project_path,
|
21
21
|
'CI_PIPELINE_ID' => :ci_pipeline_id,
|
22
|
+
'CI_PIPELINE_NAME' => :ci_pipeline_name,
|
22
23
|
'CI_PIPELINE_URL' => :ci_pipeline_url,
|
23
24
|
'SLACK_QA_CHANNEL' => :slack_qa_channel,
|
24
|
-
'DEPLOY_VERSION' => :deploy_version
|
25
|
+
'DEPLOY_VERSION' => :deploy_version,
|
26
|
+
'QA_GITLAB_CI_TOKEN' => :gitlab_ci_token
|
25
27
|
}.freeze
|
26
28
|
|
27
29
|
ENV_VARIABLES.each do |env_name, method_name|
|
@@ -11,7 +11,9 @@ module GitlabQuality
|
|
11
11
|
"unexpected token at 'GitLab is not responding'",
|
12
12
|
"GitLab: Internal API error (502).",
|
13
13
|
"could not be found (502)",
|
14
|
-
"Error reference number: 502"
|
14
|
+
"Error reference number: 502",
|
15
|
+
"(502): `GitLab is not responding`",
|
16
|
+
"<head><title>502 Bad Gateway</title></head>"
|
15
17
|
].freeze
|
16
18
|
|
17
19
|
SHARED_EXAMPLES_CALLERS = %w[include_examples it_behaves_like].freeze
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab_quality-test_tooling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.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: 2025-
|
11
|
+
date: 2025-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|