gitlab_quality-test_tooling 0.9.3 → 1.0.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/README.md +17 -0
- data/exe/slow-test-merge-request-report-note +54 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/merge_request.rb +52 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/merge_request_dry_client.rb +31 -0
- data/lib/gitlab_quality/test_tooling/report/concerns/find_set_dri.rb +1 -3
- data/lib/gitlab_quality/test_tooling/report/merge_request_slow_tests_report.rb +147 -0
- data/lib/gitlab_quality/test_tooling/report/report_as_issue.rb +2 -30
- data/lib/gitlab_quality/test_tooling/report/slow_test_issue.rb +1 -5
- data/lib/gitlab_quality/test_tooling/test_result/json_test_result.rb +36 -0
- data/lib/gitlab_quality/test_tooling/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 989fdbc7beb98d23c28a6df0918b48db36962183f71e931d90c1ef70cb99b918
|
4
|
+
data.tar.gz: 5edeaf64ee7042db858fdec5cd9a434a449f530abeef5a03eafbec873cabf0f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 936dc55126b3e217b38a43cb7b5b6810bc01f6bbc74d8713414818422130a9158d779941a6f49c11a4ca7e290922cf8c53c19717d1164a0b55e9bc4ee1481aa9
|
7
|
+
data.tar.gz: ebe5967dc286b06b72ed8efba01d3c713019e7e89c8b3bf30d26f6567832a4f939b0e4e15d39020acfa959352b3200a996562eb2b3bf43a40009ad6f4c96259b
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -128,11 +128,28 @@ Purpose: Create slow test issues from JSON RSpec report files
|
|
128
128
|
Usage: exe/slow-test-issue [options]
|
129
129
|
-i, --input-files INPUT_FILES JSON RSpec report files JSON
|
130
130
|
-p, --project PROJECT Can be an integer or a group/project string
|
131
|
+
-t, --token TOKEN A valid access token with `api` scope and Maintainer permission in PROJECT
|
132
|
+
--dry-run Perform a dry-run (don't create note)
|
133
|
+
-v, --version Show the version
|
134
|
+
-h, --help Show the usage
|
135
|
+
```
|
136
|
+
|
137
|
+
### `slow-test-merge-request-report-note`
|
138
|
+
|
139
|
+
```shell
|
140
|
+
$ exe/slow-test-merge-request-report-note -h
|
141
|
+
Purpose: Create slow test note on merge requests from JSON RSpec report files
|
142
|
+
Usage: exe/slow-test-merge-request-report-note [options]
|
143
|
+
-i, --input-files INPUT_FILES JSON RSpec report files JSON
|
144
|
+
--project PROJECT Can be an integer or a group/project string
|
145
|
+
-m MERGE_REQUEST_IID, An integer merge request IID
|
146
|
+
--merge_request_iid
|
131
147
|
-t, --token TOKEN A valid access token with `api` scope and Maintainer permission in PROJECT
|
132
148
|
--dry-run Perform a dry-run (don't create issues)
|
133
149
|
-v, --version Show the version
|
134
150
|
-h, --help Show the usage
|
135
151
|
```
|
152
|
+
|
136
153
|
## Development
|
137
154
|
|
138
155
|
### Initial setup
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "optparse"
|
6
|
+
|
7
|
+
require_relative "../lib/gitlab_quality/test_tooling"
|
8
|
+
|
9
|
+
params = {}
|
10
|
+
|
11
|
+
options = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
13
|
+
|
14
|
+
opts.on('-i', '--input-files INPUT_FILES', String, 'JSON RSpec report files JSON') do |input_files|
|
15
|
+
params[:input_files] = input_files
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on('-p', '--project PROJECT', String, 'Can be an integer or a group/project string') do |project|
|
19
|
+
params[:project] = project
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('-m', '--merge_request_iid MERGE_REQUEST_IID', String, 'An integer merge request IID') do |merge_request_iid|
|
23
|
+
params[:merge_request_iid] = merge_request_iid
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on('-t', '--token TOKEN', String, 'A valid access token with `api` scope and Maintainer permission in PROJECT') do |token|
|
27
|
+
params[:token] = token
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('--dry-run', "Perform a dry-run (don't create note)") do
|
31
|
+
params[:dry_run] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on_tail('-v', '--version', 'Show the version') do
|
35
|
+
require_relative "../lib/gitlab_quality/test_tooling/version"
|
36
|
+
puts "#{$PROGRAM_NAME} : #{GitlabQuality::TestTooling::VERSION}"
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on_tail('-h', '--help', 'Show the usage') do
|
41
|
+
puts "Purpose: Create slow test note on merge requests from JSON RSpec report files"
|
42
|
+
puts opts
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.parse(ARGV)
|
47
|
+
end
|
48
|
+
|
49
|
+
if params.any?
|
50
|
+
GitlabQuality::TestTooling::Report::MergeRequestSlowTestsReport.new(**params).invoke!
|
51
|
+
else
|
52
|
+
puts options
|
53
|
+
exit 1
|
54
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'gitlab'
|
4
|
+
|
5
|
+
module GitlabQuality
|
6
|
+
module TestTooling
|
7
|
+
module GitlabClient
|
8
|
+
class MergeRequest
|
9
|
+
def initialize(token:, project:, merge_request_iid:)
|
10
|
+
@token = token
|
11
|
+
@project = project
|
12
|
+
@merge_request_iid = merge_request_iid
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_merge_request
|
16
|
+
client.merge_request_changes(project, merge_request_iid)
|
17
|
+
end
|
18
|
+
|
19
|
+
def merge_request_changed_files
|
20
|
+
find_merge_request["changes"].map do |change|
|
21
|
+
change["new_path"]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def find_note(body:)
|
26
|
+
client.merge_request_notes(project, merge_request_iid, per_page: 100).auto_paginate.find do |mr_note|
|
27
|
+
mr_note['body'] =~ /#{body}/
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_note(note:)
|
32
|
+
client.create_merge_request_note(project, merge_request_iid, note)
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_note(id:, note:)
|
36
|
+
client.edit_merge_request_note(project, merge_request_iid, id, note)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :project, :token, :merge_request_iid
|
42
|
+
|
43
|
+
def client
|
44
|
+
@client ||= Gitlab.client(
|
45
|
+
endpoint: Runtime::Env.gitlab_api_base,
|
46
|
+
private_token: token
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabQuality
|
4
|
+
module TestTooling
|
5
|
+
module GitlabClient
|
6
|
+
class MergeRequestDryClient < MergeRequest
|
7
|
+
def find_merge_request
|
8
|
+
puts "Finding merge_request_id #{merge_request_iid}"
|
9
|
+
puts "project: #{project}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def merge_request_changed_files
|
13
|
+
puts "Changed files for #{merge_request_iid}"
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_note(body:)
|
18
|
+
puts "Find note for #{merge_request_iid} with body: #{body}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_note(note:)
|
22
|
+
puts "The following note would have been created with body: #{note}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def update_note(id:, note:)
|
26
|
+
puts "The following note would have been update id: #{id} with body: #{note}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -39,9 +39,7 @@ module GitlabQuality
|
|
39
39
|
|
40
40
|
def fetch_group_sets(product_group)
|
41
41
|
@group_sets = @stage_sets.select do |user|
|
42
|
-
user['role'].include?(product_group
|
43
|
-
word == 'and' ? word : word.capitalize
|
44
|
-
end.join(" "))
|
42
|
+
user['role'].downcase.tr(' ', '_').include?(product_group)
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabQuality
|
4
|
+
module TestTooling
|
5
|
+
module Report
|
6
|
+
class MergeRequestSlowTestsReport
|
7
|
+
SLOW_TEST_MESSAGE = '<!-- slow-test -->'
|
8
|
+
SLOW_TEST_LABEL = '/label ~"rspec:slow test detected"'
|
9
|
+
|
10
|
+
def initialize(token:, input_files:, merge_request_iid:, project: nil, dry_run: false, **_kwargs)
|
11
|
+
@project = project
|
12
|
+
@gitlab_merge_request = (dry_run ? GitlabClient::MergeRequestDryClient : GitlabClient::MergeRequest).new(token: token, project: project,
|
13
|
+
merge_request_iid: merge_request_iid)
|
14
|
+
@files = Array(input_files)
|
15
|
+
@merge_request_iid = merge_request_iid
|
16
|
+
end
|
17
|
+
|
18
|
+
def invoke!
|
19
|
+
validate_input!
|
20
|
+
|
21
|
+
run!
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :gitlab_merge_request, :files, :project, :merge_request_iid
|
27
|
+
|
28
|
+
def run!
|
29
|
+
puts "Reporting slow tests in MR #{merge_request_iid}"
|
30
|
+
|
31
|
+
TestResults::Builder.new(files).test_results_per_file do |test_results|
|
32
|
+
puts "=> Reporting #{test_results.count} tests in #{test_results.path}"
|
33
|
+
|
34
|
+
upsert_mr_note(slow_related_tests(slow_tests(test_results))) if should_create_mr_note?(test_results)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def should_create_mr_note?(test_results)
|
39
|
+
gitlab_merge_request.merge_request_changed_files.any? &&
|
40
|
+
slow_tests(test_results).any? &&
|
41
|
+
slow_related_tests(slow_tests(test_results)).any?
|
42
|
+
end
|
43
|
+
|
44
|
+
def slow_related_tests(slow_test_results)
|
45
|
+
slow_test_results.select do |slow_test_result|
|
46
|
+
base_file = slow_test_result.file.split('/').last.gsub('_spec.rb', '')
|
47
|
+
|
48
|
+
merge_request_changed_files.any? { |change| change =~ /#{base_file}/ }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def merge_request_changed_files
|
53
|
+
@merge_request_changed_files ||= gitlab_merge_request.merge_request_changed_files
|
54
|
+
end
|
55
|
+
|
56
|
+
def slow_tests(test_results)
|
57
|
+
test_results.select(&:slow_test?)
|
58
|
+
end
|
59
|
+
|
60
|
+
def note_header
|
61
|
+
[
|
62
|
+
SLOW_TEST_MESSAGE,
|
63
|
+
SLOW_TEST_LABEL,
|
64
|
+
':snail: Slow tests detected in this merge request, might be related with changed RSpec files.',
|
65
|
+
'| Job | File | Name | Duration | Expected duration |',
|
66
|
+
'| --- | --- | --- | --- | --- |'
|
67
|
+
]
|
68
|
+
end
|
69
|
+
|
70
|
+
def slow_test_rows(slow_test)
|
71
|
+
rows = []
|
72
|
+
|
73
|
+
slow_test.each do |test|
|
74
|
+
rows << slow_test_table_row(test)
|
75
|
+
end
|
76
|
+
|
77
|
+
rows
|
78
|
+
end
|
79
|
+
|
80
|
+
def build_note(slow_test)
|
81
|
+
rows = note_header + slow_test_rows(slow_test)
|
82
|
+
|
83
|
+
rows.join("\n")
|
84
|
+
end
|
85
|
+
|
86
|
+
def note_comment_includes_slow_test?(gitlab_note, slow_test)
|
87
|
+
gitlab_note.include?("[##{slow_test.ci_job_id}](#{slow_test.ci_job_url}) | #{slow_test.test_file_link}")
|
88
|
+
end
|
89
|
+
|
90
|
+
def slow_test_table_row(slow_test)
|
91
|
+
row = [
|
92
|
+
"[##{slow_test.ci_job_id}](#{slow_test.ci_job_url})",
|
93
|
+
slow_test.test_file_link,
|
94
|
+
slow_test.name,
|
95
|
+
"#{slow_test.run_time} s",
|
96
|
+
"< #{slow_test.max_duration_for_test} s"
|
97
|
+
]
|
98
|
+
|
99
|
+
"| #{row.join(' | ')} |"
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_slow_test_rows(gitlab_note, slow_tests)
|
103
|
+
slow_tests.each do |slow_test|
|
104
|
+
gitlab_note += "\n#{slow_test_table_row(slow_test)}" unless note_comment_includes_slow_test?(gitlab_note, slow_test)
|
105
|
+
end
|
106
|
+
|
107
|
+
gitlab_note
|
108
|
+
end
|
109
|
+
|
110
|
+
def upsert_mr_note(slow_tests)
|
111
|
+
existing_note = gitlab_merge_request.find_note(body: SLOW_TEST_MESSAGE)
|
112
|
+
|
113
|
+
if existing_note
|
114
|
+
puts "Update note for merge request: #{merge_request_iid}"
|
115
|
+
|
116
|
+
up_to_date_note = add_slow_test_rows(existing_note.body, slow_tests)
|
117
|
+
|
118
|
+
gitlab_merge_request.update_note(id: existing_note['id'], note: up_to_date_note) if existing_note.body != up_to_date_note
|
119
|
+
else
|
120
|
+
up_to_date_note = build_note(slow_tests)
|
121
|
+
|
122
|
+
puts "Create note for merge request: #{merge_request_iid}"
|
123
|
+
|
124
|
+
gitlab_merge_request.create_note(note: up_to_date_note)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def validate_input!
|
129
|
+
assert_project!
|
130
|
+
assert_input_files!(files)
|
131
|
+
end
|
132
|
+
|
133
|
+
def assert_project!
|
134
|
+
return if project
|
135
|
+
|
136
|
+
abort "Please provide a valid project ID or path with the `-p/--project` option!"
|
137
|
+
end
|
138
|
+
|
139
|
+
def assert_input_files!(files)
|
140
|
+
return if Dir.glob(files).any?
|
141
|
+
|
142
|
+
abort "Please provide valid JUnit report files. No files were found matching `#{files.join(',')}`"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -8,19 +8,6 @@ module GitlabQuality
|
|
8
8
|
class ReportAsIssue
|
9
9
|
include Concerns::Utils
|
10
10
|
|
11
|
-
FILE_BASE_URL = "https://gitlab.com/gitlab-org/gitlab/-/blob/master/"
|
12
|
-
|
13
|
-
OTHER_TESTS_MAX_DURATION = 45.40 # seconds
|
14
|
-
|
15
|
-
TestLevelSpecification = Struct.new(:regex, :max_duration)
|
16
|
-
|
17
|
-
TEST_LEVEL_SPECIFICATIONS = [
|
18
|
-
TestLevelSpecification.new(%r{spec/features/}, 50.13),
|
19
|
-
TestLevelSpecification.new(%r{spec/(controllers|requests)/}, 19.20),
|
20
|
-
TestLevelSpecification.new(%r{spec/lib/}, 27.12),
|
21
|
-
TestLevelSpecification.new(%r{qa/specs/features/}, 240)
|
22
|
-
].freeze
|
23
|
-
|
24
11
|
def initialize(token:, input_files:, project: nil, dry_run: false, **_kwargs)
|
25
12
|
@project = project
|
26
13
|
@gitlab = (dry_run ? GitlabIssueDryClient : GitlabIssueClient).new(token: token, project: project)
|
@@ -51,22 +38,16 @@ module GitlabQuality
|
|
51
38
|
|
52
39
|
| Field | Value |
|
53
40
|
| ------ | ------ |
|
54
|
-
| File | #{test_file_link
|
41
|
+
| File | #{test.test_file_link} |
|
55
42
|
| Description | `#{test.name}` |
|
56
43
|
| Test level | #{test.level} |
|
57
44
|
| Hash | `#{test_hash(test)}` |
|
58
45
|
| Duration | #{test.run_time} seconds |
|
59
|
-
| Expected duration | < #{max_duration_for_test
|
46
|
+
| Expected duration | < #{test.max_duration_for_test} seconds |
|
60
47
|
#{"| Test case | #{test.testcase} |" if test.testcase}
|
61
48
|
DESCRIPTION
|
62
49
|
end
|
63
50
|
|
64
|
-
def test_file_link(test)
|
65
|
-
path_prefix = test.file.start_with?('qa/') ? 'qa/' : ''
|
66
|
-
|
67
|
-
"[`#{path_prefix}#{test.file}#L#{test.line_number}`](#{FILE_BASE_URL}#{path_prefix}#{test.file}#L#{test.line_number})"
|
68
|
-
end
|
69
|
-
|
70
51
|
def new_issue_labels(_test)
|
71
52
|
[]
|
72
53
|
end
|
@@ -169,15 +150,6 @@ module GitlabQuality
|
|
169
150
|
def ee_test?(test)
|
170
151
|
test.file =~ %r{features/ee/(api|browser_ui)}
|
171
152
|
end
|
172
|
-
|
173
|
-
def max_duration_for_test(test)
|
174
|
-
test_level_specification = TEST_LEVEL_SPECIFICATIONS.find do |test_level_specification|
|
175
|
-
test.example_id =~ test_level_specification.regex
|
176
|
-
end
|
177
|
-
return OTHER_TESTS_MAX_DURATION unless test_level_specification
|
178
|
-
|
179
|
-
test_level_specification.max_duration
|
180
|
-
end
|
181
153
|
end
|
182
154
|
end
|
183
155
|
end
|
@@ -27,7 +27,7 @@ module GitlabQuality
|
|
27
27
|
puts "=> Reporting #{test_results.count} tests in #{test_results.path}"
|
28
28
|
|
29
29
|
test_results.each do |test|
|
30
|
-
create_slow_issue(test) if
|
30
|
+
create_slow_issue(test) if test.slow_test?
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -59,10 +59,6 @@ module GitlabQuality
|
|
59
59
|
rescue MultipleIssuesFound => e
|
60
60
|
warn(e.message)
|
61
61
|
end
|
62
|
-
|
63
|
-
def should_create_slow_issue?(test)
|
64
|
-
!test.allowed_to_be_slow? && test.run_time > max_duration_for_test(test)
|
65
|
-
end
|
66
62
|
end
|
67
63
|
end
|
68
64
|
end
|
@@ -4,8 +4,21 @@ module GitlabQuality
|
|
4
4
|
module TestTooling
|
5
5
|
module TestResult
|
6
6
|
class JsonTestResult < BaseTestResult
|
7
|
+
FILE_BASE_URL = "https://gitlab.com/gitlab-org/gitlab/-/blob/master/"
|
8
|
+
|
7
9
|
PRIVATE_TOKEN_REGEX = /(private_token=)[\w-]+/
|
8
10
|
|
11
|
+
OTHER_TESTS_MAX_DURATION = 45.40 # seconds
|
12
|
+
|
13
|
+
TestLevelSpecification = Struct.new(:regex, :max_duration)
|
14
|
+
|
15
|
+
TEST_LEVEL_SPECIFICATIONS = [
|
16
|
+
TestLevelSpecification.new(%r{spec/features/}, 50.13),
|
17
|
+
TestLevelSpecification.new(%r{spec/(controllers|requests)/}, 19.20),
|
18
|
+
TestLevelSpecification.new(%r{spec/lib/}, 27.12),
|
19
|
+
TestLevelSpecification.new(%r{qa/specs/features/}, 240)
|
20
|
+
].freeze
|
21
|
+
|
9
22
|
def name
|
10
23
|
report.fetch('full_description')
|
11
24
|
end
|
@@ -93,6 +106,10 @@ module GitlabQuality
|
|
93
106
|
report['level']
|
94
107
|
end
|
95
108
|
|
109
|
+
def ci_job_id
|
110
|
+
report['ci_job_url'].split('/').last
|
111
|
+
end
|
112
|
+
|
96
113
|
def failures # rubocop:disable Metrics/AbcSize
|
97
114
|
@failures ||=
|
98
115
|
report.fetch('exceptions', []).filter_map do |exception|
|
@@ -123,6 +140,25 @@ module GitlabQuality
|
|
123
140
|
!!report['allowed_to_be_slow']
|
124
141
|
end
|
125
142
|
|
143
|
+
def slow_test?
|
144
|
+
!allowed_to_be_slow? && run_time > max_duration_for_test
|
145
|
+
end
|
146
|
+
|
147
|
+
def max_duration_for_test
|
148
|
+
test_level_specification = TEST_LEVEL_SPECIFICATIONS.find do |test_level_specification|
|
149
|
+
example_id =~ test_level_specification.regex
|
150
|
+
end
|
151
|
+
return OTHER_TESTS_MAX_DURATION unless test_level_specification
|
152
|
+
|
153
|
+
test_level_specification.max_duration
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_file_link
|
157
|
+
path_prefix = file.start_with?('qa/') ? 'qa/' : ''
|
158
|
+
|
159
|
+
"[`#{path_prefix}#{file}#L#{line_number}`](#{FILE_BASE_URL}#{path_prefix}#{file}#L#{line_number})"
|
160
|
+
end
|
161
|
+
|
126
162
|
private
|
127
163
|
|
128
164
|
def quarantine
|
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: 0.
|
4
|
+
version: 1.0.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: 2023-
|
11
|
+
date: 2023-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -324,6 +324,7 @@ executables:
|
|
324
324
|
- relate-failure-issue
|
325
325
|
- report-results
|
326
326
|
- slow-test-issues
|
327
|
+
- slow-test-merge-request-report-note
|
327
328
|
- update-screenshot-paths
|
328
329
|
extensions: []
|
329
330
|
extra_rdoc_files: []
|
@@ -348,9 +349,12 @@ files:
|
|
348
349
|
- exe/relate-failure-issue
|
349
350
|
- exe/report-results
|
350
351
|
- exe/slow-test-issues
|
352
|
+
- exe/slow-test-merge-request-report-note
|
351
353
|
- exe/update-screenshot-paths
|
352
354
|
- lefthook.yml
|
353
355
|
- lib/gitlab_quality/test_tooling.rb
|
356
|
+
- lib/gitlab_quality/test_tooling/gitlab_client/merge_request.rb
|
357
|
+
- lib/gitlab_quality/test_tooling/gitlab_client/merge_request_dry_client.rb
|
354
358
|
- lib/gitlab_quality/test_tooling/gitlab_issue_client.rb
|
355
359
|
- lib/gitlab_quality/test_tooling/gitlab_issue_dry_client.rb
|
356
360
|
- lib/gitlab_quality/test_tooling/labels_inference.rb
|
@@ -359,6 +363,7 @@ files:
|
|
359
363
|
- lib/gitlab_quality/test_tooling/report/concerns/results_reporter.rb
|
360
364
|
- lib/gitlab_quality/test_tooling/report/concerns/utils.rb
|
361
365
|
- lib/gitlab_quality/test_tooling/report/generate_test_session.rb
|
366
|
+
- lib/gitlab_quality/test_tooling/report/merge_request_slow_tests_report.rb
|
362
367
|
- lib/gitlab_quality/test_tooling/report/prepare_stage_reports.rb
|
363
368
|
- lib/gitlab_quality/test_tooling/report/relate_failure_issue.rb
|
364
369
|
- lib/gitlab_quality/test_tooling/report/report_as_issue.rb
|