gitlab_quality-test_tooling 1.14.2 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_client.rb +3 -2
- data/lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_dry_client.rb +3 -2
- data/lib/gitlab_quality/test_tooling/report/relate_failure_issue.rb +1 -1
- data/lib/gitlab_quality/test_tooling/runtime/env.rb +4 -0
- data/lib/gitlab_quality/test_tooling/test_meta/processor/add_to_blocking_processor.rb +24 -13
- data/lib/gitlab_quality/test_tooling/test_meta/processor/add_to_quarantine_processor.rb +25 -15
- data/lib/gitlab_quality/test_tooling/test_meta/processor/meta_processor.rb +9 -0
- data/lib/gitlab_quality/test_tooling/test_meta/test_meta_updater.rb +37 -6
- 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: 8364acd36abab9ce89c0846c346b893ca041a6a740ced7dc5c784da5990ea74c
|
4
|
+
data.tar.gz: 9468d8b559aeec587f9c3722e4f6e9d539d790828f9ecc7f815cc39ca22f2657
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d287ca74d5fe7bc1bd9acd25541eb6f150f717f95f9e8c0bdf7a53ac139f3dab5186565ec74f2f7279e50dd47268d22121eb94ba2e3955cc5f6de33e7a952c0
|
7
|
+
data.tar.gz: e2954fea3d65bdce6e72f26a201965f45cc3aab583a34af9835f4d42f71540ad21582f4f8a96a12cd377a949644ab458ea213febfb2e6e90fbdc25c1867ddb72
|
data/Gemfile.lock
CHANGED
@@ -10,7 +10,7 @@ module GitlabQuality
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id: nil)
|
13
|
+
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id: nil, reviewer_ids: [])
|
14
14
|
attrs = {
|
15
15
|
source_branch: source_branch,
|
16
16
|
target_branch: target_branch,
|
@@ -18,7 +18,8 @@ module GitlabQuality
|
|
18
18
|
labels: labels,
|
19
19
|
assignee_id: assignee_id,
|
20
20
|
squash: true,
|
21
|
-
remove_source_branch: true
|
21
|
+
remove_source_branch: true,
|
22
|
+
reviewer_ids: reviewer_ids
|
22
23
|
}.compact
|
23
24
|
|
24
25
|
merge_request = handle_gitlab_client_exceptions do
|
@@ -26,10 +26,11 @@ module GitlabQuality
|
|
26
26
|
puts "The following note would have been updated id: #{id} with body: #{note} for mr_iid: #{merge_request_iid}"
|
27
27
|
end
|
28
28
|
|
29
|
-
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id:)
|
29
|
+
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id:, reviewer_ids:)
|
30
30
|
puts "A merge request would be created with title: #{title} " \
|
31
31
|
"source_branch: #{source_branch} target_branch: #{target_branch} " \
|
32
|
-
"description: #{description} labels: #{labels}, assignee_id: #{assignee_id}"
|
32
|
+
"description: #{description} labels: #{labels}, assignee_id: #{assignee_id}" \
|
33
|
+
"reviewer_ids: #{reviewer_ids}"
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -268,7 +268,7 @@ module GitlabQuality
|
|
268
268
|
if stacktrace_match
|
269
269
|
stacktrace_match[:stacktrace].gsub(/^\s*#.*$/, '').gsub(/^[[:space:]]+/, '').strip
|
270
270
|
else
|
271
|
-
puts " => [DEBUG] Stacktrace doesn't match the regex (#{regex})
|
271
|
+
puts " => [DEBUG] Stacktrace doesn't match the regex (#{regex})!"
|
272
272
|
end
|
273
273
|
end
|
274
274
|
|
@@ -33,6 +33,10 @@ module GitlabQuality
|
|
33
33
|
env_var_value_if_defined('QA_LOG_LEVEL')&.upcase || 'INFO'
|
34
34
|
end
|
35
35
|
|
36
|
+
def gitlab_bot_username
|
37
|
+
env_var_value_if_defined('GITLAB_BOT_USERNAME') || 'gitlab-bot'
|
38
|
+
end
|
39
|
+
|
36
40
|
def log_path
|
37
41
|
env_var_value_if_defined('QA_LOG_PATH') || host_artifacts_dir
|
38
42
|
end
|
@@ -14,38 +14,39 @@ module GitlabQuality
|
|
14
14
|
# @param [TestMetaUpdater] context instance of TestMetaUpdater
|
15
15
|
def execute(spec, context) # rubocop:disable Metrics/AbcSize
|
16
16
|
@context = context
|
17
|
-
|
17
|
+
@existing_mrs = nil
|
18
18
|
@file_path = spec["file_path"]
|
19
19
|
devops_stage = spec["stage"]
|
20
20
|
product_group = spec["product_group"]
|
21
21
|
@example_name = spec["name"]
|
22
22
|
@mr_title = format("%{prefix} %{example_name}", prefix: '[PROMOTE TO BLOCKING]', example_name: example_name)
|
23
23
|
|
24
|
-
return unless proceed_with_merge_request?
|
25
|
-
|
26
24
|
@file_contents = context.get_file_contents(file_path)
|
27
25
|
|
28
|
-
new_content, changed_line_no = add_blocking_metadata
|
26
|
+
new_content, @changed_line_no = add_blocking_metadata
|
29
27
|
|
30
|
-
return
|
28
|
+
return unless proceed_with_merge_request?
|
31
29
|
|
32
30
|
branch = context.create_branch("blocking-promotion-#{SecureRandom.hex(4)}", example_name, context.ref)
|
33
31
|
|
34
32
|
context.commit_changes(branch, <<~COMMIT_MESSAGE, file_path, new_content)
|
35
33
|
Promote end-to-end test to blocking
|
36
34
|
|
37
|
-
Promote to blocking: #{example_name}
|
35
|
+
#{"Promote to blocking: #{example_name}".truncate(72)}
|
38
36
|
COMMIT_MESSAGE
|
39
37
|
|
40
|
-
|
38
|
+
reviewer_id, assignee_handle = context.fetch_dri_id(product_group, devops_stage)
|
39
|
+
|
40
|
+
gitlab_bot_user_id = context.user_id_for_username(Runtime::Env.gitlab_bot_username)
|
41
41
|
|
42
|
-
merge_request = context.create_merge_request(mr_title, branch,
|
42
|
+
merge_request = context.create_merge_request(mr_title, branch, gitlab_bot_user_id, [reviewer_id]) do
|
43
43
|
<<~MARKDOWN
|
44
44
|
## What does this MR do?
|
45
45
|
|
46
46
|
Promotes the test [`#{example_name}`](https://gitlab.com/#{context.project}/-/blob/#{context.ref}/#{file_path}#L#{changed_line_no + 1})
|
47
47
|
to the blocking bucket
|
48
48
|
|
49
|
+
This test was identified in the reliable e2e test report: #{context.report_issue}
|
49
50
|
|
50
51
|
/label ~"Quality" ~"QA" ~"type::maintenance"
|
51
52
|
/label ~"devops::#{devops_stage}"
|
@@ -62,6 +63,11 @@ module GitlabQuality
|
|
62
63
|
If you think this MR should not be merged, please close it and add a note of the reason to the blocking report: #{context.report_issue}
|
63
64
|
MARKDOWN
|
64
65
|
|
66
|
+
if merge_request
|
67
|
+
context.add_processed_record({ file_path => changed_line_no })
|
68
|
+
Runtime::Logger.info(" Created MR for promotion to blocking: #{merge_request.web_url}")
|
69
|
+
end
|
70
|
+
|
65
71
|
merge_request
|
66
72
|
end
|
67
73
|
|
@@ -82,15 +88,20 @@ module GitlabQuality
|
|
82
88
|
|
83
89
|
private
|
84
90
|
|
85
|
-
attr_reader :context, :file_path, :file_contents, :example_name, :mr_title
|
91
|
+
attr_reader :context, :file_path, :file_contents, :example_name, :mr_title, :changed_line_no
|
86
92
|
|
87
93
|
# Checks if there is already an MR open
|
88
94
|
#
|
89
95
|
# @return [Boolean]
|
90
|
-
def proceed_with_merge_request?
|
91
|
-
|
92
|
-
|
93
|
-
|
96
|
+
def proceed_with_merge_request? # rubocop:disable Metrics/AbcSize
|
97
|
+
if changed_line_no.negative?
|
98
|
+
Runtime::Logger.info(" No lines were changed in #{file_path}. Will not proceed with creating MR.")
|
99
|
+
return false
|
100
|
+
elsif context.record_processed?(file_path, changed_line_no)
|
101
|
+
Runtime::Logger.info(" Record already processed for #{file_path}:#{changed_line_no}. Will not proceed with creating MR.")
|
102
|
+
return false
|
103
|
+
elsif existing_mrs&.any?
|
104
|
+
Runtime::Logger.info(" An open MR already exists for '#{example_name}': #{existing_mrs.first['web_url']}. Will not proceed with creating MR.")
|
94
105
|
return false
|
95
106
|
end
|
96
107
|
|
@@ -24,7 +24,7 @@ module GitlabQuality
|
|
24
24
|
# @param [TestMetaUpdater] context instance of TestMetaUpdater
|
25
25
|
def execute(spec, context) # rubocop:disable Metrics/AbcSize
|
26
26
|
@context = context
|
27
|
-
|
27
|
+
@existing_mrs = nil
|
28
28
|
@file_path = spec["file_path"]
|
29
29
|
devops_stage = spec["stage"]
|
30
30
|
@failure_issue_url = spec["failure_issue"]
|
@@ -33,21 +33,23 @@ module GitlabQuality
|
|
33
33
|
@mr_title = format("%{prefix} %{example_name}", prefix: '[QUARANTINE]', example_name: example_name)
|
34
34
|
@failure_issue = context.fetch_issue(iid: issue_id)
|
35
35
|
|
36
|
-
return unless proceed_with_merge_request?
|
37
|
-
|
38
36
|
@file_contents = context.get_file_contents(file_path)
|
39
37
|
|
40
|
-
new_content, changed_line_no = add_quarantine_metadata
|
38
|
+
new_content, @changed_line_no = add_quarantine_metadata
|
39
|
+
|
40
|
+
return unless proceed_with_merge_request?
|
41
41
|
|
42
42
|
branch = context.create_branch("#{issue_id}-quarantine-#{SecureRandom.hex(4)}", example_name, context.ref)
|
43
43
|
|
44
44
|
context.commit_changes(branch, <<~COMMIT_MESSAGE, file_path, new_content)
|
45
45
|
Quarantine end-to-end test
|
46
46
|
|
47
|
-
Quarantine #{example_name}
|
47
|
+
#{"Quarantine #{example_name}".truncate(72)}
|
48
48
|
COMMIT_MESSAGE
|
49
49
|
|
50
|
-
context.
|
50
|
+
gitlab_bot_user_id = context.user_id_for_username(Runtime::Env.gitlab_bot_username)
|
51
|
+
|
52
|
+
merge_request = context.create_merge_request(mr_title, branch, gitlab_bot_user_id) do
|
51
53
|
<<~MARKDOWN
|
52
54
|
## What does this MR do?
|
53
55
|
|
@@ -85,6 +87,13 @@ module GitlabQuality
|
|
85
87
|
</div>
|
86
88
|
MARKDOWN
|
87
89
|
end
|
90
|
+
|
91
|
+
if merge_request
|
92
|
+
context.add_processed_record({ file_path => changed_line_no })
|
93
|
+
Runtime::Logger.info(" Created MR for quarantine: #{merge_request.web_url}")
|
94
|
+
end
|
95
|
+
|
96
|
+
merge_request
|
88
97
|
end
|
89
98
|
|
90
99
|
# Performs post processing. Takes a list of MRs and posts them in a note on report_issue and Slack
|
@@ -114,20 +123,21 @@ module GitlabQuality
|
|
114
123
|
|
115
124
|
private
|
116
125
|
|
117
|
-
attr_reader :context, :file_path, :file_contents, :failure_issue_url, :example_name,
|
126
|
+
attr_reader :context, :file_path, :file_contents, :failure_issue_url, :example_name,
|
127
|
+
:issue_id, :mr_title, :failure_issue, :changed_line_no
|
118
128
|
|
119
129
|
# Checks if the failure issue is closed or if there is already an MR open
|
120
130
|
#
|
121
131
|
# @return [Boolean]
|
122
|
-
def proceed_with_merge_request?
|
132
|
+
def proceed_with_merge_request? # rubocop:disable Metrics/AbcSize
|
123
133
|
if context.issue_is_closed?(failure_issue)
|
124
|
-
|
134
|
+
Runtime::Logger.info(" Failure issue '#{failure_issue_url}' is closed. Will not proceed with creating MR.")
|
125
135
|
return false
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
136
|
+
elsif context.record_processed?(file_path, changed_line_no)
|
137
|
+
Runtime::Logger.info(" Record already processed for #{file_path}:#{changed_line_no}. Will not proceed with creating MR.")
|
138
|
+
return false
|
139
|
+
elsif existing_mrs&.any?
|
140
|
+
Runtime::Logger.info(" An open MR already exists for '#{example_name}': #{existing_mrs.first['web_url']}. Will not proceed with creating MR.")
|
131
141
|
return false
|
132
142
|
end
|
133
143
|
|
@@ -144,7 +154,7 @@ module GitlabQuality
|
|
144
154
|
indentation = context.indentation(line)
|
145
155
|
|
146
156
|
if line.include?(',') && line.split.last != 'do'
|
147
|
-
line[line.
|
157
|
+
line[line.rindex(',')] = format(QUARANTINE_METADATA.rstrip, issue_url: failure_issue_url, indentation: indentation, suffix: ',', quarantine_type: quarantine_type)
|
148
158
|
else
|
149
159
|
line[line.rindex(' ')] = format(QUARANTINE_METADATA.rstrip, issue_url: failure_issue_url, indentation: indentation, suffix: ' ', quarantine_type: quarantine_type)
|
150
160
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'active_support/core_ext/string/filters'
|
4
|
+
|
3
5
|
module GitlabQuality
|
4
6
|
module TestTooling
|
5
7
|
module TestMeta
|
@@ -15,6 +17,13 @@ module GitlabQuality
|
|
15
17
|
end
|
16
18
|
|
17
19
|
private_class_method :new
|
20
|
+
|
21
|
+
# Fetch existing MRs for given mr title
|
22
|
+
#
|
23
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
24
|
+
def existing_mrs
|
25
|
+
@existing_mrs ||= context.existing_merge_requests(title: mr_title)
|
26
|
+
end
|
18
27
|
end
|
19
28
|
end
|
20
29
|
end
|
@@ -8,7 +8,7 @@ module GitlabQuality
|
|
8
8
|
class TestMetaUpdater
|
9
9
|
include TestTooling::Concerns::FindSetDri
|
10
10
|
|
11
|
-
attr_reader :project, :ref, :report_issue
|
11
|
+
attr_reader :project, :ref, :report_issue, :processed_records
|
12
12
|
|
13
13
|
TEST_PLATFORM_MAINTAINERS_SLACK_CHANNEL_ID = 'C0437FV9KBN' # test-platform-maintainers
|
14
14
|
|
@@ -19,6 +19,7 @@ module GitlabQuality
|
|
19
19
|
@ref = ref
|
20
20
|
@dry_run = dry_run
|
21
21
|
@processor = processor
|
22
|
+
@processed_records = {}
|
22
23
|
end
|
23
24
|
|
24
25
|
def invoke!
|
@@ -33,10 +34,20 @@ module GitlabQuality
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
37
|
+
# Add processed records
|
38
|
+
#
|
39
|
+
# @param [Hash<String,Integer>] record the processed record
|
40
|
+
# @option record [String] :file_path the path to the spec file
|
41
|
+
# @option spec [Intenger] :changed_line_no the line number change in file_path
|
42
|
+
# @return [Hash<String,Integer>] processed_records
|
43
|
+
def add_processed_record(record)
|
44
|
+
@processed_records.merge!(record)
|
45
|
+
end
|
46
|
+
|
36
47
|
# Fetch contents of file from the repository
|
37
48
|
#
|
38
|
-
# [String] file_path path to the file
|
39
|
-
# [String] contents of the file
|
49
|
+
# @param [String] file_path path to the file
|
50
|
+
# @return [String] contents of the file
|
40
51
|
def get_file_contents(file_path)
|
41
52
|
repository_files = GitlabClient::RepositoryFilesClient.new(token: token, project: project, file_path: file_path)
|
42
53
|
repository_files.file_contents
|
@@ -110,8 +121,10 @@ module GitlabQuality
|
|
110
121
|
# @param [String] example_name the example
|
111
122
|
# @param [Gitlab::ObjectifiedHash] branch the branch
|
112
123
|
# @param [Integer] assignee_id
|
124
|
+
# @param [Array<Integer>] reviewer_ids
|
125
|
+
# @param [String] labels comma seperated list of labels
|
113
126
|
# @return [Gitlab::ObjectifiedHash] the created merge request
|
114
|
-
def create_merge_request(title, branch, assignee_id = nil, labels = '')
|
127
|
+
def create_merge_request(title, branch, assignee_id = nil, reviewer_ids = [], labels = '')
|
115
128
|
description = yield
|
116
129
|
|
117
130
|
merge_request_client.create_merge_request(
|
@@ -120,7 +133,8 @@ module GitlabQuality
|
|
120
133
|
target_branch: ref,
|
121
134
|
description: description,
|
122
135
|
labels: labels,
|
123
|
-
assignee_id: assignee_id
|
136
|
+
assignee_id: assignee_id,
|
137
|
+
reviewer_ids: reviewer_ids)
|
124
138
|
end
|
125
139
|
|
126
140
|
# Check if issue is closed
|
@@ -179,7 +193,15 @@ module GitlabQuality
|
|
179
193
|
def fetch_dri_id(product_group, devops_stage)
|
180
194
|
assignee_handle = ENV.fetch('QA_TEST_DRI_HANDLE', nil) || set_dri_via_group(product_group, devops_stage)
|
181
195
|
|
182
|
-
[
|
196
|
+
[user_id_for_username(assignee_handle), assignee_handle]
|
197
|
+
end
|
198
|
+
|
199
|
+
# Fetch id for the given GitLab username/handle
|
200
|
+
#
|
201
|
+
# @param [String] username
|
202
|
+
# @return [Integer]
|
203
|
+
def user_id_for_username(username)
|
204
|
+
issue_client.find_user_id(username: username)
|
183
205
|
end
|
184
206
|
|
185
207
|
# Post a message on Slack
|
@@ -221,6 +243,15 @@ module GitlabQuality
|
|
221
243
|
merge_request_client.find(options: { search: title, in: 'title', state: 'opened' })
|
222
244
|
end
|
223
245
|
|
246
|
+
# Checks if changes has already been made to given file and line number
|
247
|
+
#
|
248
|
+
# @param [String] file_path path to the file
|
249
|
+
# @param [Integer] changed_line_no updated line number
|
250
|
+
# @return [Boolean]
|
251
|
+
def record_processed?(file_path, changed_line_no)
|
252
|
+
processed_records[file_path] && processed_records[file_path] == changed_line_no
|
253
|
+
end
|
254
|
+
|
224
255
|
private
|
225
256
|
|
226
257
|
attr_reader :token, :specs_file, :dry_run, :processor
|
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: 1.
|
4
|
+
version: 1.15.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: 2024-
|
11
|
+
date: 2024-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|