gitlab-qa 10.0.0 → 10.1.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/qa/report/relate_failure_issue.rb +21 -3
- data/lib/gitlab/qa/report/test_result.rb +2 -1
- data/lib/gitlab/qa/reporter.rb +8 -0
- data/lib/gitlab/qa/system_logs/finders/json_log_finder.rb +65 -0
- data/lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb +21 -0
- data/lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb +21 -0
- data/lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb +21 -0
- data/lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb +21 -0
- data/lib/gitlab/qa/system_logs/log_types/log.rb +38 -0
- data/lib/gitlab/qa/system_logs/log_types/rails/api_log.rb +34 -0
- data/lib/gitlab/qa/system_logs/log_types/rails/application_log.rb +27 -0
- data/lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb +23 -0
- data/lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb +30 -0
- data/lib/gitlab/qa/system_logs/shared_fields.rb +29 -0
- data/lib/gitlab/qa/system_logs/system_logs_formatter.rb +65 -0
- data/lib/gitlab/qa/version.rb +1 -1
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3d71c9b26ee6da1b637bd155fc3dca98e47f739435802737110b8c76273068f
|
4
|
+
data.tar.gz: 4ede3accf59fadf7ba32c05cb49e0ba53eb3e9c809aa4c0978edb650e04ae529
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70441f243143e6d241f91729d1f35ba1d1668438bbd61bfe534e616e501c989af6382606986fdf593043d2a70a7e7dd59c9d7af5ccf52f93245b29a32dcf2bb7
|
7
|
+
data.tar.gz: 00ecb2e2599f15295e57bfda8313b9312e780693ddc9015b344a21f25d7b0ece878789e9ee6772825617abe8ae7d262429082fe7884cc4c8e8f07ff99a5a6018
|
data/Gemfile.lock
CHANGED
@@ -23,8 +23,9 @@ module Gitlab
|
|
23
23
|
|
24
24
|
MultipleIssuesFound = Class.new(StandardError)
|
25
25
|
|
26
|
-
def initialize(max_diff_ratio: DEFAULT_MAX_DIFF_RATIO_FOR_DETECTION, **kwargs)
|
26
|
+
def initialize(system_logs: [], max_diff_ratio: DEFAULT_MAX_DIFF_RATIO_FOR_DETECTION, **kwargs)
|
27
27
|
super
|
28
|
+
@system_logs = Dir.glob(system_logs)
|
28
29
|
@max_diff_ratio = max_diff_ratio.to_f
|
29
30
|
@issue_type = 'issue'
|
30
31
|
@commented_issue_list = Set.new
|
@@ -217,7 +218,7 @@ module Gitlab
|
|
217
218
|
stacktrace_match = stacktrace.match(regex)
|
218
219
|
|
219
220
|
if stacktrace_match
|
220
|
-
stacktrace_match[:stacktrace].gsub(/^\s*#.*$/, '').gsub(/^[[:space:]]+/, '').strip
|
221
|
+
stacktrace_match[:stacktrace].split('First happened in')[0].gsub(/^\s*#.*$/, '').gsub(/^[[:space:]]+/, '').strip
|
221
222
|
else
|
222
223
|
puts " => [DEBUG] Stacktrace doesn't match the expected regex (#{regex}):\n----------------\n#{stacktrace}\n----------------\n"
|
223
224
|
end
|
@@ -252,10 +253,27 @@ module Gitlab
|
|
252
253
|
"```\n#{full_stacktrace(test)}\n```",
|
253
254
|
"First happened in #{test.ci_job_url}.",
|
254
255
|
"Related test case: #{test.testcase}.",
|
255
|
-
screenshot_section(test)
|
256
|
+
screenshot_section(test),
|
257
|
+
system_log_errors_section(test)
|
256
258
|
].join("\n\n")
|
257
259
|
end
|
258
260
|
|
261
|
+
def system_log_errors_section(test)
|
262
|
+
correlation_id = test.failures.first['correlation_id']
|
263
|
+
section = ''
|
264
|
+
|
265
|
+
if @system_logs.any? && !correlation_id.nil?
|
266
|
+
section = SystemLogs::SystemLogsFormatter.new(
|
267
|
+
@system_logs,
|
268
|
+
correlation_id
|
269
|
+
).system_logs_summary_markdown
|
270
|
+
end
|
271
|
+
|
272
|
+
puts " => No system logs or correlation id provided, skipping this section in issue description" if section.empty?
|
273
|
+
|
274
|
+
section
|
275
|
+
end
|
276
|
+
|
259
277
|
def new_issue_labels(test)
|
260
278
|
up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS)
|
261
279
|
end
|
@@ -128,7 +128,8 @@ module Gitlab
|
|
128
128
|
{
|
129
129
|
'message' => "#{exception['class']}: #{exception['message']}",
|
130
130
|
'message_lines' => exception['message_lines'],
|
131
|
-
'stacktrace' => "#{format_message_lines(exception['message_lines'])}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}"
|
131
|
+
'stacktrace' => "#{format_message_lines(exception['message_lines'])}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}",
|
132
|
+
'correlation_id' => exception['correlation_id']
|
132
133
|
}
|
133
134
|
end
|
134
135
|
end
|
data/lib/gitlab/qa/reporter.rb
CHANGED
@@ -7,6 +7,7 @@ module Gitlab
|
|
7
7
|
class Reporter
|
8
8
|
# rubocop:disable Metrics/AbcSize
|
9
9
|
# rubocop:disable Metrics/PerceivedComplexity
|
10
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
10
11
|
def self.invoke(args)
|
11
12
|
report_options = {}
|
12
13
|
slack_options = {}
|
@@ -65,6 +66,12 @@ module Gitlab
|
|
65
66
|
slack_options[:message] = slack_options[:message] + "\n\n" + Gitlab::QA::Report::SummaryTable.create(input_files: files)
|
66
67
|
end
|
67
68
|
|
69
|
+
opts.on('--include-system-log-errors FILES', String, 'Include errors from system logs in failure issues. To be used with --relate-failure-issue') do |files|
|
70
|
+
raise 'This option should be used with --relate-failure-issue.' unless report_options[:relate_failure_issue]
|
71
|
+
|
72
|
+
report_options[:system_logs] = files if files
|
73
|
+
end
|
74
|
+
|
68
75
|
opts.on('--update-screenshot-path FILES', "Update the path to screenshots to container's host") do |files|
|
69
76
|
report_options[:update_screenshot_path] = true
|
70
77
|
report_options[:files] = files
|
@@ -116,6 +123,7 @@ module Gitlab
|
|
116
123
|
exit 1
|
117
124
|
end
|
118
125
|
end
|
126
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
119
127
|
# rubocop:enable Metrics/PerceivedComplexity
|
120
128
|
# rubocop:enable Metrics/AbcSize
|
121
129
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Gitlab
|
6
|
+
module QA
|
7
|
+
module SystemLogs
|
8
|
+
module Finders
|
9
|
+
class JsonLogFinder
|
10
|
+
def initialize(base_path, file_path)
|
11
|
+
@base_path = base_path
|
12
|
+
@file_path = file_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def find(correlation_id)
|
16
|
+
log_file_path = "#{@base_path}/#{@file_path}"
|
17
|
+
logs = []
|
18
|
+
|
19
|
+
if File.exist?(log_file_path) && !correlation_id.nil?
|
20
|
+
File.foreach(log_file_path) do |line|
|
21
|
+
begin
|
22
|
+
json_line = JSON.parse(line, symbolize_names: true)
|
23
|
+
rescue JSON::ParserError
|
24
|
+
Runtime::Logger.debug("JsonLogFinder#find attempted to parse invalid JSON: #{line}")
|
25
|
+
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
if (json_line[:correlation_id])&.casecmp?(correlation_id)
|
30
|
+
normalized_line = normalize_keys(json_line)
|
31
|
+
logs << new_log(normalized_line)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
logs
|
37
|
+
end
|
38
|
+
|
39
|
+
def new_log(data)
|
40
|
+
raise 'abstract method new_log must be defined!'
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def normalize_keys(json_line)
|
46
|
+
normalized_hash = {}
|
47
|
+
|
48
|
+
json_line.each_key do |old_key|
|
49
|
+
key_string = old_key.to_s
|
50
|
+
|
51
|
+
if key_string.include?('.')
|
52
|
+
normalized_key = key_string.tr('.', '_').to_sym
|
53
|
+
normalized_hash[normalized_key] = json_line[old_key]
|
54
|
+
else
|
55
|
+
normalized_hash[old_key] = json_line[old_key]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
normalized_hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module Finders
|
7
|
+
module Rails
|
8
|
+
class ApiLogFinder < JsonLogFinder
|
9
|
+
def initialize(base_path, file_path = 'gitlab-rails/api_json.log')
|
10
|
+
super(base_path, file_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_log(data)
|
14
|
+
LogTypes::Rails::ApiLog.new(data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module Finders
|
7
|
+
module Rails
|
8
|
+
class ApplicationLogFinder < JsonLogFinder
|
9
|
+
def initialize(base_path, file_path = 'gitlab-rails/application_json.log')
|
10
|
+
super(base_path, file_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_log(data)
|
14
|
+
LogTypes::Rails::ApplicationLog.new(data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module Finders
|
7
|
+
module Rails
|
8
|
+
class ExceptionLogFinder < JsonLogFinder
|
9
|
+
def initialize(base_path, file_path = 'gitlab-rails/exceptions_json.log')
|
10
|
+
super(base_path, file_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_log(data)
|
14
|
+
LogTypes::Rails::ExceptionLog.new(data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module Finders
|
7
|
+
module Rails
|
8
|
+
class GraphqlLogFinder < JsonLogFinder
|
9
|
+
def initialize(base_path, file_path = 'gitlab-rails/graphql_json.log')
|
10
|
+
super(base_path, file_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def new_log(data)
|
14
|
+
LogTypes::Rails::GraphqlLog.new(data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module LogTypes
|
7
|
+
class Log
|
8
|
+
def initialize(name, data)
|
9
|
+
@name = name
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :name, :data
|
14
|
+
|
15
|
+
def summary_fields
|
16
|
+
[
|
17
|
+
:severity,
|
18
|
+
:correlation_id,
|
19
|
+
:time,
|
20
|
+
:message
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
def summary
|
25
|
+
summary = {}
|
26
|
+
|
27
|
+
summary_fields.each do |field|
|
28
|
+
value = data[field]
|
29
|
+
summary[field] = value unless value.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
summary
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module LogTypes
|
7
|
+
module Rails
|
8
|
+
class ApiLog < Log
|
9
|
+
include SharedFields::Exception
|
10
|
+
include SharedFields::Meta
|
11
|
+
|
12
|
+
def initialize(data)
|
13
|
+
super('Rails API', data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def summary_fields
|
17
|
+
super.concat(
|
18
|
+
[
|
19
|
+
:method,
|
20
|
+
:path,
|
21
|
+
:status,
|
22
|
+
:params,
|
23
|
+
:api_error
|
24
|
+
],
|
25
|
+
exception_fields,
|
26
|
+
meta_fields
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module LogTypes
|
7
|
+
module Rails
|
8
|
+
class ApplicationLog < Log
|
9
|
+
include SharedFields::Exception
|
10
|
+
include SharedFields::Meta
|
11
|
+
|
12
|
+
def initialize(data)
|
13
|
+
super('Rails Application', data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def summary_fields
|
17
|
+
super.concat(
|
18
|
+
exception_fields,
|
19
|
+
meta_fields
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module LogTypes
|
7
|
+
module Rails
|
8
|
+
class ExceptionLog < Log
|
9
|
+
include SharedFields::Exception
|
10
|
+
|
11
|
+
def initialize(data)
|
12
|
+
super('Rails Exceptions', data)
|
13
|
+
end
|
14
|
+
|
15
|
+
def summary_fields
|
16
|
+
super.concat(exception_fields)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module LogTypes
|
7
|
+
module Rails
|
8
|
+
class GraphqlLog < Log
|
9
|
+
include SharedFields::Meta
|
10
|
+
|
11
|
+
def initialize(data)
|
12
|
+
super('Rails GraphQL', data)
|
13
|
+
end
|
14
|
+
|
15
|
+
def summary_fields
|
16
|
+
super.concat(
|
17
|
+
[
|
18
|
+
:operation_name,
|
19
|
+
:query_string,
|
20
|
+
:variables
|
21
|
+
],
|
22
|
+
meta_fields
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
module SharedFields
|
7
|
+
module Meta
|
8
|
+
def meta_fields
|
9
|
+
[
|
10
|
+
:meta_user,
|
11
|
+
:meta_project,
|
12
|
+
:meta_caller_id
|
13
|
+
]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Exception
|
18
|
+
def exception_fields
|
19
|
+
[
|
20
|
+
:exception_class,
|
21
|
+
:exception_message,
|
22
|
+
:exception_backtrace
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module SystemLogs
|
6
|
+
class SystemLogsFormatter
|
7
|
+
NUM_OF_LOG_SECTIONS = 4
|
8
|
+
|
9
|
+
def initialize(base_paths, correlation_id)
|
10
|
+
@base_paths = base_paths
|
11
|
+
@correlation_id = correlation_id
|
12
|
+
end
|
13
|
+
|
14
|
+
def system_logs_summary_markdown
|
15
|
+
log_sections = Array.new(NUM_OF_LOG_SECTIONS) { [] }
|
16
|
+
|
17
|
+
@base_paths.each do |base_path|
|
18
|
+
all_logs = [
|
19
|
+
Finders::Rails::ApiLogFinder.new(base_path).find(@correlation_id),
|
20
|
+
Finders::Rails::ExceptionLogFinder.new(base_path).find(@correlation_id),
|
21
|
+
Finders::Rails::ApplicationLogFinder.new(base_path).find(@correlation_id),
|
22
|
+
Finders::Rails::GraphqlLogFinder.new(base_path).find(@correlation_id)
|
23
|
+
]
|
24
|
+
|
25
|
+
create_log_summary_sections!(all_logs, log_sections)
|
26
|
+
end
|
27
|
+
|
28
|
+
log_sections.prepend('### System Logs') unless log_sections.all?(&:empty?)
|
29
|
+
log_sections.join("\n").rstrip
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def create_log_summary_sections!(all_logs, sections)
|
35
|
+
sections.zip(all_logs) do |section, logs|
|
36
|
+
unless logs.empty?
|
37
|
+
section_title = "\n#### #{logs.first.name}"
|
38
|
+
section.append(section_title) unless section.include?(section_title)
|
39
|
+
section.append(create_log_summaries(logs))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_log_summaries(logs)
|
45
|
+
section = []
|
46
|
+
|
47
|
+
logs.each do |log|
|
48
|
+
log_summary = <<~MARKDOWN.chomp
|
49
|
+
<details><summary>Click to expand</summary>
|
50
|
+
|
51
|
+
```json
|
52
|
+
#{JSON.pretty_generate(log.summary)}
|
53
|
+
```
|
54
|
+
</details>
|
55
|
+
MARKDOWN
|
56
|
+
|
57
|
+
section.append(log_summary)
|
58
|
+
end
|
59
|
+
|
60
|
+
section.join("\n\n")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/gitlab/qa/version.rb
CHANGED
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: 10.
|
4
|
+
version: 10.1.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-04-
|
11
|
+
date: 2023-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -485,6 +485,18 @@ files:
|
|
485
485
|
- lib/gitlab/qa/support/invalid_response_error.rb
|
486
486
|
- lib/gitlab/qa/support/shell_command.rb
|
487
487
|
- lib/gitlab/qa/support/shellout.rb
|
488
|
+
- lib/gitlab/qa/system_logs/finders/json_log_finder.rb
|
489
|
+
- lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb
|
490
|
+
- lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb
|
491
|
+
- lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb
|
492
|
+
- lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb
|
493
|
+
- lib/gitlab/qa/system_logs/log_types/log.rb
|
494
|
+
- lib/gitlab/qa/system_logs/log_types/rails/api_log.rb
|
495
|
+
- lib/gitlab/qa/system_logs/log_types/rails/application_log.rb
|
496
|
+
- lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb
|
497
|
+
- lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb
|
498
|
+
- lib/gitlab/qa/system_logs/shared_fields.rb
|
499
|
+
- lib/gitlab/qa/system_logs/system_logs_formatter.rb
|
488
500
|
- lib/gitlab/qa/test_logger.rb
|
489
501
|
- lib/gitlab/qa/version.rb
|
490
502
|
- scripts/build-package-and-test-env
|