gitlab_quality-test_tooling 1.20.1 → 1.21.1

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: 94c648574a575a2a7d23ce07a46731500edbd858ae8196e6b50ac104d260b88e
4
- data.tar.gz: '0468936a09caafa090ea0f91a20bb952314a7ebabd2704d35d760901ef3f8939'
3
+ metadata.gz: 3bd25aa86cb58d8b69f852509893b2d7f28a183474d6b4ac96732d8bd3efca23
4
+ data.tar.gz: f17357f3f9e1c97089ac675c918682341978a60ac40cace79557722c2ce4cdff
5
5
  SHA512:
6
- metadata.gz: 24f5968a3038b68a6dc44ec7d9873ad759a73454ac8fed7bca965e0c139cb2e25324ad4a3aea841e6f302b141fa5799abae4eebdb2d58d2b04fa3f09b099b1f8
7
- data.tar.gz: 2d943ff87a109e8951e2889cb6ed34321fcde844d311494de5a9f6808dee4fe80014b81d42765a244fa8338ddf2599852bb46824f50996a0db709ffd664bb5ea
6
+ metadata.gz: a2d8710d330b9dd79a54ff78de39e15e76b014ce70de89791991723a6a272222edda6a751bb0449ba1a820163713046e617c9d45d4fa6a895f0eb4f8d86889bc
7
+ data.tar.gz: 2eda2f409021c5d8f8c710a66294266fcda7a8ef46d3580ab680175718d8468c62b4fea6c375cfcb51cd1fe899f9c83918962f767b9c534916cfcb68fab1c676
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab_quality-test_tooling (1.20.1)
4
+ gitlab_quality-test_tooling (1.21.1)
5
5
  activesupport (>= 6.1, < 7.2)
6
6
  amatch (~> 0.4.1)
7
7
  gitlab (~> 4.19)
@@ -21,13 +21,15 @@ module GitlabQuality
21
21
  # @param [Array<Gitlab::ObjectifiedHash>] jobs
22
22
  # @return [Array]
23
23
  def collect_results(jobs)
24
- jobs.sort_by(&:stage).map do |job|
25
- {
26
- "Job" => job.name,
27
- "Stage" => job.stage,
28
- "Failure Reason" => job.failure_reason
29
- }
30
- end
24
+ jobs.sort_by(&:stage)
25
+ .reject { |job| job.name.downcase.include?("quarantine") }
26
+ .map do |job|
27
+ {
28
+ "Job" => job.name,
29
+ "Stage" => job.stage,
30
+ "Failure Reason" => job.failure_reason
31
+ }
32
+ end
31
33
  end
32
34
  end
33
35
  end
@@ -73,8 +73,7 @@ module GitlabQuality
73
73
  <<~MKDOWN.strip
74
74
  ### Executions
75
75
 
76
- All Environments:
77
- <img src="https://dashboards.quality.gitlab.net/render/d-solo/cW0UMgv7k/spec-health?orgId=1&var-run_type=All&var-name=#{formatted_title}&panelId=4&width=1000&height=500" />
76
+ [Spec metrics on all environments](https://dashboards.quality.gitlab.net/d/cW0UMgv7k/single-spec-metrics?orgId=1&var-run_type=All&var-name=#{formatted_title})
78
77
  MKDOWN
79
78
  end
80
79
 
@@ -12,69 +12,36 @@ module GitlabQuality
12
12
  # Creates the merge requests for promoting E2E tests to :blocking
13
13
  #
14
14
  # @param [TestMetaUpdater] context instance of TestMetaUpdater
15
- # @return [Array<Gitlab::ObjectifiedHash>]
16
- def create_merge_requests(context) # rubocop:disable Metrics/AbcSize
15
+ def create_merge_requests(context)
17
16
  @context = context
18
17
 
19
- created_merge_requests = []
20
18
  context.processed_commits.each_value do |record|
21
- branch = record[:branch]
22
- first_spec = record[:commits].values.first
23
- devops_stage = first_spec["stage"]
24
- product_section = first_spec["section"]
25
- product_group = first_spec["product_group"]
26
- file = first_spec["file"]
19
+ branch, devops_stage, product_group, file, reviewer_id, assignee_handle = extract_data_from_record(record)
27
20
 
28
- mr_title = format("%{prefix} %{file}", prefix: '[E2E PROMOTE TO BLOCKING]', file: file).truncate(72, omission: '')
29
-
30
- reviewer_id, assignee_handle = context.fetch_dri_id(product_group, devops_stage, product_section)
31
-
32
- gitlab_bot_user_id = context.user_id_for_username(Runtime::Env.gitlab_bot_username)
21
+ mr_title = format("%{prefix} %{file}", prefix: '[E2E] PROMOTE TO BLOCKING:', file: file).truncate(72, omission: '')
33
22
 
34
23
  merge_request = context.create_merge_request(mr_title, branch, gitlab_bot_user_id, [reviewer_id]) do
35
- <<~MARKDOWN
36
- ## What does this MR do?
37
-
38
- Promotes the following e2e tests to the blocking bucket:
39
-
40
- #{mr_spec_details_from_commits(record[:commits])}
41
-
42
- This MR was created based on data from reliable e2e test report: #{context.report_issue}
43
-
44
- /label ~"Quality" ~"QA" ~"type::maintenance"
45
- /label ~"devops::#{devops_stage}"
46
- #{context.label_from_product_group(product_group)}
47
-
48
- <div align="center">
49
- (This MR was automatically generated by [`gitlab_quality-test_tooling`](https://gitlab.com/gitlab-org/ruby/gems/gitlab_quality-test_tooling) at #{Time.now.utc})
50
- </div>
51
- MARKDOWN
24
+ merge_request_description(record, devops_stage, product_group)
52
25
  end
53
26
 
54
- context.post_note_on_merge_request(<<~MARKDOWN, merge_request.iid)
55
- @#{assignee_handle} Please review this MR, approve and assign it to a maintainer.
56
-
57
- 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}
58
- MARKDOWN
27
+ context.post_note_on_merge_request(maintainer_note_on_merge_request(assignee_handle), merge_request.iid)
59
28
 
60
29
  if merge_request
61
30
  Runtime::Logger.info(" Created MR for promotion to blocking: #{merge_request.web_url}")
62
- created_merge_requests << merge_request
31
+ record[:merge_request] = merge_request
63
32
  end
64
33
  end
65
-
66
- created_merge_requests
67
34
  end
68
35
 
69
- # Performs post processing. Takes a list of MRs and posts them in a note on report_issue
36
+ # Performs post processing. Posts a list of MRs in a note on report_issue
70
37
  #
71
- # @param [Array<Gitlab::ObjectifiedHash>] merge_requests
72
- def post_process(merge_requests)
73
- web_urls = merge_requests.compact.map { |mr| "- #{mr.web_url}\n" }.join
38
+ # @param [TestMetaUpdater] context instance of TestMetaUpdater
39
+ def post_process(context)
40
+ web_urls = context.processed_commits.values.map { |value| "- #{value[:merge_request].web_url}\n" }.join
74
41
 
75
42
  return if web_urls.empty?
76
43
 
77
- context.post_note_on_report_issue(<<~ISSUE_NOTE)
44
+ context.post_note_on_issue(<<~ISSUE_NOTE, context.report_issue)
78
45
  The following merge requests have been created to promote stable specs to blocking:
79
46
 
80
47
  #{web_urls}
@@ -108,6 +75,47 @@ module GitlabQuality
108
75
  COMMIT_MESSAGE
109
76
  end
110
77
 
78
+ def maintainer_note_on_merge_request(assignee_handle)
79
+ <<~MARKDOWN
80
+ @#{assignee_handle} Please review this MR, approve and assign it to a maintainer.
81
+
82
+ 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}
83
+ MARKDOWN
84
+ end
85
+
86
+ def merge_request_description(record, devops_stage, product_group)
87
+ <<~MARKDOWN
88
+ ## What does this MR do?
89
+
90
+ Promotes the following e2e tests to the blocking bucket:
91
+
92
+ #{spec_details_from_commits(record[:commits])}
93
+
94
+ This MR was created based on data from reliable e2e test report: #{context.report_issue}
95
+
96
+ /label ~"Quality" ~"QA" ~"type::maintenance"
97
+ /label ~"devops::#{devops_stage}"
98
+ #{context.label_from_product_group(product_group)}
99
+
100
+ <div align="center">
101
+ (This MR was automatically generated by [`gitlab_quality-test_tooling`](https://gitlab.com/gitlab-org/ruby/gems/gitlab_quality-test_tooling) at #{Time.now.utc})
102
+ </div>
103
+ MARKDOWN
104
+ end
105
+
106
+ def extract_data_from_record(record)
107
+ first_spec = record[:commits].values.first
108
+ product_group = first_spec["product_group"]
109
+ devops_stage = first_spec["stage"]
110
+ reviewer_id, assignee_handle = context.fetch_dri_id(product_group, devops_stage, first_spec["section"])
111
+
112
+ [record[:branch], devops_stage, product_group, first_spec["file"], reviewer_id, assignee_handle]
113
+ end
114
+
115
+ def gitlab_bot_user_id
116
+ context.user_id_for_username(Runtime::Env.gitlab_bot_username)
117
+ end
118
+
111
119
  # Add blocking metadata to the file content and replace it
112
120
  #
113
121
  # @return [Array<String, Integer>] first value holds the new content, the second value holds the line number of the test
@@ -18,19 +18,13 @@ module GitlabQuality
18
18
  # Creates the merge requests to quarantine E2E tests
19
19
  #
20
20
  # @param [TestMetaUpdater] context instance of TestMetaUpdater
21
- # @return [Array<Gitlab::ObjectifiedHash>]
22
- def create_merge_requests(context) # rubocop:disable Metrics/AbcSize
21
+ def create_merge_requests(context)
23
22
  @context = context
24
23
 
25
- created_merge_requests = []
26
24
  context.processed_commits.each_value do |record|
27
- branch = record[:branch]
28
- first_spec = record[:commits].values.first
29
- devops_stage = first_spec["stage"]
30
- product_group = first_spec["product_group"]
31
- file = first_spec["file"]
25
+ branch, devops_stage, product_group, file = extract_data_from_record(record)
32
26
 
33
- mr_title = format("%{prefix} %{file}", prefix: '[QUARANTINE]', file: file).truncate(72, omission: '')
27
+ mr_title = format("%{prefix} %{file}", prefix: '[E2E] QUARANTINE:', file: file).truncate(72, omission: '')
34
28
 
35
29
  gitlab_bot_user_id = context.user_id_for_username(Runtime::Env.gitlab_bot_username)
36
30
 
@@ -40,36 +34,27 @@ module GitlabQuality
40
34
 
41
35
  if merge_request
42
36
  Runtime::Logger.info(" Created MR for quarantine: #{merge_request.web_url}")
43
- created_merge_requests << merge_request
37
+ record[:merge_request] = merge_request
44
38
  end
45
39
  end
46
-
47
- created_merge_requests
48
40
  end
49
41
 
50
- # Performs post processing. Takes a list of MRs and posts them in a note on report_issue and Slack
42
+ # Performs post processing. Posts a list of MRs in a note on report_issue and Slack.
43
+ # Also posts note on failure issues for un-quarantining of the quarantined
51
44
  #
52
- # @param [Gitlab::ObjectifiedHash] merge_requests
53
- def post_process(merge_requests)
54
- web_urls = merge_requests.compact.map { |mr| "- #{mr.web_url}\n" }.join
55
-
56
- return if web_urls.empty?
57
-
58
- context.post_note_on_report_issue(<<~ISSUE_NOTE)
45
+ # @param [TestMetaUpdater] context instance of TestMetaUpdater
46
+ def post_process(context)
47
+ @context = context
59
48
 
60
- The following merge requests have been created to quarantine the unstable tests:
49
+ web_urls = context.processed_commits.values.map { |value| "- #{value[:merge_request].web_url}\n" }.join
61
50
 
62
- #{web_urls}
63
- ISSUE_NOTE
51
+ return if web_urls.empty?
64
52
 
65
- context.post_message_on_slack(<<~MSG)
66
- *Action Required!* The following merge requests have been created to quarantine the unstable tests identified
67
- in the reliable test report: #{context.report_issue}
53
+ context.post_note_on_issue(mrs_created_note_for_report_issue(web_urls), context.report_issue)
68
54
 
69
- #{web_urls}
55
+ context.post_message_on_slack(mrs_created_message_for_slack(web_urls))
70
56
 
71
- Maintainers are requested to review and merge. Thank you.
72
- MSG
57
+ post_unquarantine_note_on_failure_issue
73
58
  end
74
59
 
75
60
  private
@@ -99,41 +84,68 @@ module GitlabQuality
99
84
  context.issue_scoped_label(failure_issue, 'failure')&.split('::')&.last == 'test-environment'
100
85
  end
101
86
 
87
+ def extract_data_from_record(record)
88
+ first_spec = record[:commits].values.first
89
+ [record[:branch], first_spec["stage"], first_spec["product_group"], first_spec["file"]]
90
+ end
91
+
92
+ # Posts note on failure issue to un-quarantine the test
93
+ #
94
+ def post_unquarantine_note_on_failure_issue
95
+ context.processed_commits.each_value do |record|
96
+ merge_request = record[:merge_request]
97
+ next unless merge_request
98
+
99
+ record[:commits].each_value do |spec|
100
+ devops_stage = spec["stage"]
101
+ product_group = spec["product_group"]
102
+ failure_issue = spec["failure_issue"]
103
+
104
+ next unless failure_issue
105
+
106
+ note = context.post_note_on_issue(unquarantine_note_for_failure(spec, product_group, devops_stage, merge_request),
107
+ failure_issue)
108
+
109
+ Runtime::Logger.info(" Posted note on failure issue for un-quarantine: #{failure_issue}") if note
110
+ end
111
+ end
112
+ end
113
+
102
114
  def merge_request_description(record, devops_stage, product_group)
103
115
  <<~MARKDOWN
104
- ## What does this MR do?
116
+ ## What does this MR do?
105
117
 
106
- Quarantines the following e2e tests:
118
+ Quarantines the following e2e tests:
107
119
 
108
- #{mr_spec_details_from_commits(record[:commits])}
120
+ #{spec_details_from_commits(record[:commits])}
109
121
 
110
- This MR was created based on data from reliable e2e test report: #{context.report_issue}#{' '}
122
+ This MR was created based on data from reliable e2e test report: #{context.report_issue}
111
123
 
112
- ### Check-list
124
+ ### Check-list
113
125
 
114
- - [ ] General code guidelines check-list
115
- - [ ] [Code review guidelines](https://docs.gitlab.com/ee/development/code_review.html)
116
- - [ ] [Style guides](https://docs.gitlab.com/ee/development/contributing/style_guides.html)
117
- - [ ] Quarantine test check-list
118
- - [ ] Follow the [Quarantining Tests guide](https://about.gitlab.com/handbook/engineering/infrastructure/test-platform/debugging-qa-test-failures/#quarantining-tests).
119
- - [ ] Confirm the test has a [`quarantine:` tag with the specified quarantine type](https://about.gitlab.com/handbook/engineering/infrastructure/test-platform/debugging-qa-test-failures/#quarantined-test-types).
120
- - [ ] Note if the test should be [quarantined for a specific environment](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/execution_context_selection.html#quarantine-a-test-for-a-specific-environment).
121
- - [ ] (Optionally) In case of an emergency (e.g. blocked deployments), consider adding labels to pick into auto-deploy (~"Pick into auto-deploy" ~"priority::1" ~"severity::1").
122
- - [ ] To ensure a faster turnaround, ask in the `#quality_maintainers` Slack channel for someone to review and merge the merge request, rather than assigning it directly.
126
+ - [ ] General code guidelines check-list
127
+ - [ ] [Code review guidelines](https://docs.gitlab.com/ee/development/code_review.html)
128
+ - [ ] [Style guides](https://docs.gitlab.com/ee/development/contributing/style_guides.html)
129
+ - [ ] Quarantine test check-list
130
+ - [ ] Follow the [Quarantining Tests guide](https://about.gitlab.com/handbook/engineering/infrastructure/test-platform/debugging-qa-test-failures/#quarantining-tests).
131
+ - [ ] Confirm the test has a [`quarantine:` tag with the specified quarantine type](https://about.gitlab.com/handbook/engineering/infrastructure/test-platform/debugging-qa-test-failures/#quarantined-test-types).
132
+ - [ ] Note if the test should be [quarantined for a specific environment](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/execution_context_selection.html#quarantine-a-test-for-a-specific-environment).
133
+ - [ ] (Optionally) In case of an emergency (e.g. blocked deployments), consider adding labels to pick into auto-deploy (~"Pick into auto-deploy" ~"priority::1" ~"severity::1").
134
+ - [ ] To ensure a faster turnaround, ask in the `#quality_maintainers` Slack channel for someone to review and merge the merge request, rather than assigning it directly.
123
135
 
124
- <!-- Base labels. -->
125
- /label ~"Quality" ~"QA" ~"type::maintenance" ~"maintenance::pipelines"
136
+ <!-- Base labels. -->
137
+ /label ~"Quality" ~"QA" ~"type::maintenance" ~"maintenance::pipelines"
126
138
 
127
- <!--
128
- Choose the stage that appears in the test path, e.g. ~"devops::create" for
129
- `qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb`.
130
- -->
131
- /label ~"devops::#{devops_stage}"
132
- #{context.label_from_product_group(product_group)}
139
+ <!--
140
+ Choose the stage that appears in the test path, e.g. ~"devops::create" for
141
+ `qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb`.
142
+ -->
143
+ /label ~"devops::#{devops_stage}"
144
+ #{context.label_from_product_group(product_group)}
133
145
 
134
- <div align="center">
135
- (This MR was automatically generated by [`gitlab_quality-test_tooling`](https://gitlab.com/gitlab-org/ruby/gems/gitlab_quality-test_tooling) at #{Time.now.utc})
136
- </div>
146
+ <div align="center">
147
+ (This MR was automatically generated by [`gitlab_quality-test_tooling`](https://gitlab.com/gitlab-org/ruby/gems/gitlab_quality-test_tooling) at #{Time.now.utc})
148
+ </div>
137
149
  MARKDOWN
138
150
  end
139
151
 
@@ -145,6 +157,44 @@ module GitlabQuality
145
157
  COMMIT_MESSAGE
146
158
  end
147
159
 
160
+ def mrs_created_note_for_report_issue(web_urls)
161
+ <<~ISSUE_NOTE
162
+
163
+ The following merge requests have been created to quarantine the unstable tests:
164
+
165
+ #{web_urls}
166
+ ISSUE_NOTE
167
+ end
168
+
169
+ def unquarantine_note_for_failure(spec, product_group, devops_stage, merge_request)
170
+ failure_issue_assignee_handle = get_failure_issue_assignee_handle(spec, product_group, devops_stage)
171
+ <<~ISSUE_NOTE
172
+ @#{failure_issue_assignee_handle} This test will be quarantined in #{merge_request.web_url} based on data from reliable e2e test report: #{context.report_issue}
173
+
174
+ Please take this issue forward to un-quarantine the test by either addressing the issue yourself or delegating it to the relevant product group.
175
+
176
+ If this issue is delegated, please make sure to update the assignee. Thanks.
177
+ ISSUE_NOTE
178
+ end
179
+
180
+ def mrs_created_message_for_slack(web_urls)
181
+ <<~MSG
182
+ *Action Required!* The following merge requests have been created to quarantine the unstable tests identified
183
+ in the reliable test report: #{context.report_issue}
184
+
185
+ #{web_urls}
186
+
187
+ Maintainers are requested to review and merge the above MRs. Thank you.
188
+ MSG
189
+ end
190
+
191
+ def get_failure_issue_assignee_handle(spec, product_group, devops_stage)
192
+ return spec["failure_issue_assignee_handle"] if spec["failure_issue_assignee_handle"]
193
+
194
+ _, assignee_handle = context.fetch_dri_id(product_group, devops_stage, nil)
195
+ assignee_handle
196
+ end
197
+
148
198
  # Add quarantine metadata to the file content and replace it
149
199
  #
150
200
  # @return [Array<String, Integer>] first value holds the new content, the second value holds the line number of the test
@@ -41,12 +41,12 @@ module GitlabQuality
41
41
  #
42
42
  # @param [Hash<String,Hash>] commits The commits hash to use for spec details
43
43
  # @return String
44
- def mr_spec_details_from_commits(commits)
44
+ def spec_details_from_commits(commits)
45
45
  commits.each_with_index.map do |(changed_line_number, spec), index|
46
46
  <<~MARKDOWN
47
- #{index + 1}. [`#{spec['name']}`](https://gitlab.com/#{context.project}/-/blob/#{context.ref}/#{spec['file_path']}#L#{changed_line_number.to_i + 1})
48
- | [Testcase](#{spec['testcase']}) | [Spec metrics](#{context.single_spec_metrics_link(spec['name'])})
49
- #{failure_issue_text(spec)}
47
+ #{index + 1}. [`#{spec['name']}`](https://gitlab.com/#{context.project}/-/blob/#{context.ref}/#{spec['file_path']}#L#{changed_line_number.to_i + 1})
48
+ | [Testcase](#{spec['testcase']}) | [Spec metrics](#{context.single_spec_metrics_link(spec['name'])})
49
+ #{failure_issue_text(spec)}
50
50
  MARKDOWN
51
51
  end.join("\n")
52
52
  end
@@ -78,6 +78,8 @@ module GitlabQuality
78
78
 
79
79
  @failure_issue = context.fetch_issue(iid: issue_id) if issue_id
80
80
 
81
+ spec['failure_issue_assignee_handle'] = @failure_issue['assignee']['username'] if @failure_issue && @failure_issue['assignee']
82
+
81
83
  new_content, @changed_line_no = add_metadata
82
84
 
83
85
  return unless proceed_with_commit?
@@ -11,6 +11,7 @@ module GitlabQuality
11
11
  attr_reader :project, :ref, :report_issue, :processed_commits
12
12
 
13
13
  TEST_PLATFORM_MAINTAINERS_SLACK_CHANNEL_ID = 'C0437FV9KBN' # test-platform-maintainers
14
+ BATCH_LIMIT = 10
14
15
 
15
16
  def initialize(token:, project:, specs_file:, processor:, ref: 'master', dry_run: false)
16
17
  @specs_file = specs_file
@@ -28,11 +29,12 @@ module GitlabQuality
28
29
 
29
30
  contents['specs'].each do |spec|
30
31
  processor.create_commit(spec, self)
32
+ break if processed_commits.keys.count >= BATCH_LIMIT
31
33
  end
32
34
 
33
- created_merge_requests = processor.create_merge_requests(self)
35
+ processor.create_merge_requests(self)
34
36
 
35
- processor.post_process(created_merge_requests)
37
+ processor.post_process(self)
36
38
  end
37
39
  end
38
40
 
@@ -215,16 +217,17 @@ module GitlabQuality
215
217
  issue_client.find_issues(iid: iid).first
216
218
  end
217
219
 
218
- # Post note on report_issue
220
+ # Post note on isse
219
221
  #
220
222
  # @param [String] note the note to post
221
223
  # @return [Gitlab::ObjectifiedHash]
222
- def post_note_on_report_issue(note)
223
- iid = report_issue&.split('/')&.last # split url segment, last segment of path is the issue id
224
+ def post_note_on_issue(note, issue_url)
225
+ iid = issue_url&.split('/')&.last # split url segment, last segment of path is the issue id
224
226
  if iid
225
227
  issue_client.create_issue_note(iid: iid, note: note)
226
228
  else
227
- Runtime::Logger.info("#{self.class.name}##{__method__} Note was NOT posted on report issue: #{report_issue}")
229
+ Runtime::Logger.info("#{self.class.name}##{__method__} Note was NOT posted on issue: #{issue_url}")
230
+ nil
228
231
  end
229
232
  end
230
233
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitlabQuality
4
4
  module TestTooling
5
- VERSION = "1.20.1"
5
+ VERSION = "1.21.1"
6
6
  end
7
7
  end
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.20.1
4
+ version: 1.21.1
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-03-22 00:00:00.000000000 Z
11
+ date: 2024-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control