gitlab_quality-test_tooling 0.2.2 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6aca93da1e251be67dab8c377c542ddfdba84392efb41949b62b42fabb283d3
4
- data.tar.gz: 32d0c338138afaeaf0f47a38cced840387ed07c55e63631847bc59a3bfb20842
3
+ metadata.gz: 8d279ff4333f75a706c86e3eced4a8b95c7612be05b740479ea032b8c7f49a62
4
+ data.tar.gz: 92783c9acf4188c3dc781c097f3d25073fc70abab6c503a4c8802a06fda1cfb2
5
5
  SHA512:
6
- metadata.gz: 3af4b645bb8c495ed38ce06964de0008e31fbd2a097f374339874aa9f7d9b1967cd6b7c3fae7ad46188120ece0103058864e9601a68e38812002529df6ac89c0
7
- data.tar.gz: 6c1670e30153abb2af66e098c6a89fc13140d71bf1b7aa82ed06793006c8c702bfd5d4345ced0737168f7efb6c288734828a1726a905e16d4d97f2785bc9692b
6
+ metadata.gz: 0b0a7ab6ab95bb9356ddc3a5276a1b81083fe2056d102fc284d56e9b64890dcac5e76548f85dad95823bb0d1f8ceb1dc0ef0e4cb3e30ef7aad0ca11764a27b44
7
+ data.tar.gz: c6b06b7040e97db27912113cab68d0161d51d311efe7ae7f5fb81b5f6ef55d7aec0a9d8df310f40f109b5a94d099e0e2be2e617a8119066f967e9efeaeb84a81
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab_quality-test_tooling (0.2.2)
4
+ gitlab_quality-test_tooling (0.3.0)
5
5
  activesupport (~> 6.1)
6
6
  gitlab (~> 4.18.0)
7
7
  http (~> 5.0)
data/README.md CHANGED
@@ -31,9 +31,11 @@ The gem provides the following executables.
31
31
  ```shell
32
32
  Purpose: Generate test session report based on RSpec report files (JSON or JUnit XML)
33
33
  Usage: exe/generate-test-session [options]
34
- -i, --input-files FILES RSpec report files (JSON or JUnit XML)
34
+ -i, --input-files INPUT_FILES RSpec report files (JSON or JUnit XML)
35
35
  -p, --project PROJECT Can be an integer or a group/project string
36
- -t, --token ACCESS_TOKEN A valid access token with Reporter permission in PROJECT
36
+ -t, --token TOKEN A valid access token with `api` scope and Reporter permission in PROJECT
37
+ -c CI_PROJECT_TOKEN, A valid access token with `read_api` scope permission in current ENV["CI_PROJECT_ID"]
38
+ --ci-project-token
37
39
  --dry-run Perform a dry-run (don't create or update issues or test cases)
38
40
  -v, --version Show the version
39
41
  -h, --help Show the usage
@@ -63,7 +65,7 @@ Usage: exe/post-to-slack [options]
63
65
  $ exe/prepare-stage-reports -h
64
66
  Purpose: Prepare separate reports for each DevOps stage from the provided RSpec report files (JUnit XML)
65
67
  Usage: exe/prepare-stage-reports [options]
66
- -j, --junit-files FILES RSpec report files (JUnit XML)
68
+ -i, --input-files INPUT_FILES RSpec report files (JUnit XML)
67
69
  -v, --version Show the version
68
70
  -h, --help Show the usage
69
71
  ```
@@ -74,10 +76,11 @@ Usage: exe/prepare-stage-reports [options]
74
76
  $ exe/relate-failure-issue -h
75
77
  Purpose: Relate test failures to failure issues from RSpec report files (JSON or JUnit XML)
76
78
  Usage: exe/relate-failure-issue [options]
77
- -i, --input-files FILES RSpec report files (JSON or JUnit XML)
78
- --max-diff-ratio DIFF_RATO Max stacktrace diff ratio for QA failure issues detection
79
+ -i, --input-files INPUT_FILES RSpec report files (JSON or JUnit XML)
80
+ --max-diff-ratio MAX_DIFF_RATO
81
+ Max stacktrace diff ratio for QA failure issues detection
79
82
  -p, --project PROJECT Can be an integer or a group/project string
80
- -t, --token ACCESS_TOKEN A valid access token with Reporter permission in PROJECT
83
+ -t, --token TOKEN A valid access token with `api` scope and Reporter permission in PROJECT
81
84
  --system-log-files SYSTEM_LOG_FILES
82
85
  Include errors from system logs in failure issues
83
86
  --dry-run Perform a dry-run (don't create or update issues)
@@ -91,13 +94,16 @@ Usage: exe/relate-failure-issue [options]
91
94
  $ exe/report-results -h
92
95
  Purpose: Report test results from RSpec report files (JSON or JUnit XML) in GitLab test cases and result issues
93
96
  Usage: exe/report-results [options]
94
- -i, --input-files FILES RSpec report files (JSON or JUnit XML)
97
+ -i, --input-files INPUT_FILES RSpec report files (JSON or JUnit XML)
95
98
  --test-case-project TEST_CASE_PROJECT
96
99
  Can be an integer or a group/project string
100
+ -t TEST_CASE_PROJECT_TOKEN, A valid access token with `api` scope and Reporter permission in TEST_CASE_PROJECT
101
+ --test-case-project-token
97
102
  --results-issue-project RESULTS_ISSUE_PROJECT
98
103
  Can be an integer or a group/project string
99
- -t, --token ACCESS_TOKEN A valid access token
100
- --dry-run Perform a dry-run (don't create or update issues or test cases)
104
+ -r RESULTS_ISSUE_PROJECT_TOKEN, A valid access token with `api` scope and Reporter permission in RESULTS_ISSUE_PROJECT
105
+ --results-issue-project-token
106
+ --dry-run Perform a dry-run (don't create/update issues or test cases)
101
107
  -v, --version Show the version
102
108
  -h, --help Show the usage
103
109
  ```
@@ -108,7 +114,7 @@ Usage: exe/report-results [options]
108
114
  $ exe/update-screenshot-paths -h
109
115
  Purpose: Update the path to screenshots to container's host from RSpec report files (JSON or JUnit XML)
110
116
  Usage: exe/update-screenshot-paths [options]
111
- -i, --input-files FILES RSpec report files (JSON or JUnit XML)
117
+ -i, --input-files INPUT_FILES RSpec report files (JSON or JUnit XML)
112
118
  -v, --version Show the version
113
119
  -h, --help Show the usage
114
120
  ```
@@ -11,7 +11,7 @@ params = {}
11
11
  options = OptionParser.new do |opts|
12
12
  opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
13
13
 
14
- opts.on('-i', '--input-files FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
14
+ opts.on('-i', '--input-files INPUT_FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
15
15
  params[:input_files] = input_files
16
16
  end
17
17
 
@@ -19,8 +19,12 @@ options = OptionParser.new do |opts|
19
19
  params[:project] = project
20
20
  end
21
21
 
22
- opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token with Reporter permission in PROJECT') do |token|
23
- params[:token] = GitlabQuality::TestTooling::Runtime::TokenFinder.find_token!(token)
22
+ opts.on('-t', '--token TOKEN', String, 'A valid access token with `api` scope and Reporter permission in PROJECT') do |token|
23
+ params[:token] = token
24
+ end
25
+
26
+ opts.on('-c', '--ci-project-token CI_PROJECT_TOKEN', String, 'A valid access token with `read_api` scope permission in current ENV["CI_PROJECT_ID"]') do |ci_project_token|
27
+ params[:ci_project_token] = ci_project_token
24
28
  end
25
29
 
26
30
  opts.on('--dry-run', "Perform a dry-run (don't create or update issues or test cases)") do
@@ -11,8 +11,8 @@ params = {}
11
11
  options = OptionParser.new do |opts|
12
12
  opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
13
13
 
14
- opts.on('-j', '--junit-files FILES', String, 'RSpec report files (JUnit XML)') do |junit_files|
15
- params[:junit_files] = junit_files
14
+ opts.on('-i', '--input-files INPUT_FILES', String, 'RSpec report files (JUnit XML)') do |input_files|
15
+ params[:input_files] = input_files
16
16
  end
17
17
 
18
18
  opts.on_tail('-v', '--version', 'Show the version') do
@@ -11,20 +11,20 @@ params = {}
11
11
  options = OptionParser.new do |opts|
12
12
  opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
13
13
 
14
- opts.on('-i', '--input-files FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
14
+ opts.on('-i', '--input-files INPUT_FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
15
15
  params[:input_files] = input_files
16
16
  end
17
17
 
18
- opts.on('--max-diff-ratio DIFF_RATO', Float, 'Max stacktrace diff ratio for QA failure issues detection') do |value|
19
- params[:max_diff_ratio] = value
18
+ opts.on('--max-diff-ratio MAX_DIFF_RATO', Float, 'Max stacktrace diff ratio for QA failure issues detection') do |max_diff_ratio|
19
+ params[:max_diff_ratio] = max_diff_ratio
20
20
  end
21
21
 
22
22
  opts.on('-p', '--project PROJECT', String, 'Can be an integer or a group/project string') do |project|
23
23
  params[:project] = project
24
24
  end
25
25
 
26
- opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token with Reporter permission in PROJECT') do |token|
27
- params[:token] = GitlabQuality::TestTooling::Runtime::TokenFinder.find_token!(token)
26
+ opts.on('-t', '--token TOKEN', String, 'A valid access token with `api` scope and Reporter permission in PROJECT') do |token|
27
+ params[:token] = token
28
28
  end
29
29
 
30
30
  opts.on('--system-log-files SYSTEM_LOG_FILES', String,
data/exe/report-results CHANGED
@@ -11,7 +11,7 @@ params = {}
11
11
  options = OptionParser.new do |opts|
12
12
  opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
13
13
 
14
- opts.on('-i', '--input-files FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
14
+ opts.on('-i', '--input-files INPUT_FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
15
15
  params[:input_files] = input_files
16
16
  end
17
17
 
@@ -20,16 +20,22 @@ options = OptionParser.new do |opts|
20
20
  params[:test_case_project] = test_case_project
21
21
  end
22
22
 
23
+ opts.on('-t', '--test-case-project-token TEST_CASE_PROJECT_TOKEN', String,
24
+ 'A valid access token with `api` scope and Reporter permission in TEST_CASE_PROJECT') do |test_case_project_token|
25
+ params[:test_case_project_token] = test_case_project_token
26
+ end
27
+
23
28
  opts.on('--results-issue-project RESULTS_ISSUE_PROJECT', String,
24
29
  'Can be an integer or a group/project string') do |results_issue_project|
25
30
  params[:results_issue_project] = results_issue_project
26
31
  end
27
32
 
28
- opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token') do |token|
29
- params[:token] = GitlabQuality::TestTooling::Runtime::TokenFinder.find_token!(token)
33
+ opts.on('-r', '--results-issue-project-token RESULTS_ISSUE_PROJECT_TOKEN', String,
34
+ 'A valid access token with `api` scope and Reporter permission in RESULTS_ISSUE_PROJECT') do |results_issue_project_token|
35
+ params[:results_issue_project_token] = results_issue_project_token
30
36
  end
31
37
 
32
- opts.on('--dry-run', "Perform a dry-run (don't create or update issues or test cases)") do
38
+ opts.on('--dry-run', "Perform a dry-run (don't create/update issues or test cases)") do
33
39
  params[:dry_run] = true
34
40
  end
35
41
 
@@ -11,8 +11,8 @@ params = {}
11
11
  options = OptionParser.new do |opts|
12
12
  opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
13
13
 
14
- opts.on('-i', '--input-files FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
15
- params[:junit_files] = input_files
14
+ opts.on('-i', '--input-files INPUT_FILES', String, 'RSpec report files (JSON or JUnit XML)') do |input_files|
15
+ params[:input_files] = input_files
16
16
  end
17
17
 
18
18
  opts.on_tail('-v', '--version', 'Show the version') do
@@ -7,13 +7,16 @@ module GitlabQuality
7
7
  module TestTooling
8
8
  module Report
9
9
  class GenerateTestSession < ReportAsIssue
10
- def initialize(**kwargs)
10
+ def initialize(ci_project_token:, **kwargs)
11
11
  super
12
+ @ci_project_token = ci_project_token
12
13
  @issue_type = 'issue'
13
14
  end
14
15
 
15
16
  private
16
17
 
18
+ attr_reader :ci_project_token
19
+
17
20
  # rubocop:disable Metrics/AbcSize
18
21
  def run!
19
22
  puts "Generating test results in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
@@ -37,7 +40,7 @@ module GitlabQuality
37
40
  note: "/relate #{Runtime::Env.qa_issue_url}")
38
41
  end
39
42
 
40
- File.write('REPORT_ISSUE_URL', issue.web_url)
43
+ issue&.web_url # Issue isn't created in dry-run mode
41
44
  end
42
45
  # rubocop:enable Metrics/AbcSize
43
46
 
@@ -78,12 +81,12 @@ module GitlabQuality
78
81
  def generate_failed_jobs_listing
79
82
  failed_jobs = []
80
83
 
81
- client = Gitlab.client(
84
+ ci_project_client = Gitlab.client(
82
85
  endpoint: Runtime::Env.ci_api_v4_url,
83
- private_token: Runtime::Env.gitlab_ci_api_token)
86
+ private_token: ci_project_token)
84
87
 
85
88
  gitlab.handle_gitlab_client_exceptions do
86
- failed_jobs = client.pipeline_jobs(
89
+ failed_jobs = ci_project_client.pipeline_jobs(
87
90
  Runtime::Env.ci_project_id,
88
91
  Runtime::Env.ci_pipeline_id,
89
92
  scope: 'failed')
@@ -8,8 +8,8 @@ module GitlabQuality
8
8
  class PrepareStageReports
9
9
  EXTRACT_STAGE_FROM_TEST_FILE_REGEX = %r{(?:api|browser_ui)/(?:[0-9]+_)?(?<stage>[_\w]+)/}i
10
10
 
11
- def initialize(junit_files:)
12
- @junit_files = junit_files
11
+ def initialize(input_files:)
12
+ @input_files = input_files
13
13
  end
14
14
 
15
15
  def invoke!
@@ -24,13 +24,13 @@ module GitlabQuality
24
24
 
25
25
  private
26
26
 
27
- attr_reader :junit_files
27
+ attr_reader :input_files
28
28
 
29
29
  # Collect the test cases from the original reports and group them by Stage
30
30
  def collate_test_cases
31
- Dir.glob(junit_files)
32
- .each_with_object(Hash.new { |h, k| h[k] = [] }) do |junit_file, test_cases|
33
- report = Nokogiri::XML(File.open(junit_file))
31
+ Dir.glob(input_files)
32
+ .each_with_object(Hash.new { |h, k| h[k] = [] }) do |input_file, test_cases|
33
+ report = Nokogiri::XML(File.open(input_file))
34
34
  report.xpath('//testcase').each do |test_case|
35
35
  # The test file paths could start with any of
36
36
  # /qa/specs/features/api/<stage>
@@ -12,12 +12,12 @@ module GitlabQuality
12
12
  :results_issue_project, :gitlab
13
13
 
14
14
  def initialize(
15
- token:, input_files:, test_case_project: nil, results_issue_project: nil, dry_run: false,
15
+ test_case_project_token:, results_issue_project_token:, input_files:, test_case_project: nil, results_issue_project: nil, dry_run: false,
16
16
  **kwargs)
17
17
  @testcase_project_reporter = GitlabQuality::TestTooling::Report::ResultsInTestCases.new(
18
- token: token, input_files: input_files, project: test_case_project, dry_run: dry_run, **kwargs)
18
+ token: test_case_project_token, input_files: input_files, project: test_case_project, dry_run: dry_run, **kwargs)
19
19
  @results_issue_project_reporter = GitlabQuality::TestTooling::Report::ResultsInIssues.new(
20
- token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
20
+ token: results_issue_project_token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
21
21
  @test_case_project = test_case_project
22
22
  @results_issue_project = results_issue_project
23
23
  @files = Array(input_files)
@@ -8,28 +8,28 @@ module GitlabQuality
8
8
  module TestTooling
9
9
  module Report
10
10
  class UpdateScreenshotPath
11
- def initialize(junit_files:)
12
- @junit_files = junit_files
11
+ def initialize(input_files:)
12
+ @input_files = input_files
13
13
  end
14
14
 
15
15
  REGEX = %r{(?<gitlab_qa_run>gitlab-qa-run-.*?(?=/))/(?<gitlab_ce_ee_qa>gitlab-(?:ee|ce)-qa-.*?(?=/))}
16
16
  CONTAINER_PATH = File.join('/home', 'gitlab', 'qa', 'tmp').freeze
17
17
 
18
18
  def invoke!
19
- Dir.glob(junit_files).each do |junit_file|
20
- match_data = junit_file.match(REGEX)
19
+ Dir.glob(input_files).each do |input_file|
20
+ match_data = input_file.match(REGEX)
21
21
  next unless match_data
22
22
 
23
23
  host_relative_path = "#{match_data[:gitlab_qa_run]}/#{match_data[:gitlab_ce_ee_qa]}"
24
24
 
25
- rewrite_schreenshot_paths_in_junit_file(junit_file, host_relative_path)
26
- rewrite_schreenshot_paths_in_json_file(junit_file.gsub('.xml', '.json'), host_relative_path)
25
+ rewrite_schreenshot_paths_in_junit_file(input_file, host_relative_path)
26
+ rewrite_schreenshot_paths_in_json_file(input_file.gsub('.xml', '.json'), host_relative_path)
27
27
  end
28
28
  end
29
29
 
30
30
  private
31
31
 
32
- attr_reader :junit_files
32
+ attr_reader :input_files
33
33
 
34
34
  def rewrite_schreenshot_paths_in_junit_file(junit_file, host_relative_path)
35
35
  File.write(
@@ -11,9 +11,7 @@ module GitlabQuality
11
11
  using Rainbow
12
12
 
13
13
  ENV_VARIABLES = {
14
- 'GITLAB_API_BASE' => :api_base,
15
14
  'GITLAB_QA_ISSUE_URL' => :qa_issue_url,
16
- 'GITLAB_CI_API_TOKEN' => :gitlab_ci_api_token,
17
15
  'CI_COMMIT_REF_NAME' => :ci_commit_ref_name,
18
16
  'CI_JOB_NAME' => :ci_job_name,
19
17
  'CI_JOB_URL' => :ci_job_url,
@@ -21,7 +19,6 @@ module GitlabQuality
21
19
  'CI_PROJECT_NAME' => :ci_project_name,
22
20
  'CI_PIPELINE_ID' => :ci_pipeline_id,
23
21
  'CI_PIPELINE_URL' => :ci_pipeline_url,
24
- 'CI_API_V4_URL' => :ci_api_v4_url,
25
22
  'SLACK_QA_CHANNEL' => :slack_qa_channel,
26
23
  'DEPLOY_VERSION' => :deploy_version
27
24
  }.freeze
@@ -44,8 +41,12 @@ module GitlabQuality
44
41
  env_var_value_if_defined('QA_DEFAULT_BRANCH') || 'main'
45
42
  end
46
43
 
44
+ def ci_api_v4_url
45
+ env_var_value_if_defined('CI_API_V4_URL') || 'https://gitlab.com/api/v4'
46
+ end
47
+
47
48
  def gitlab_api_base
48
- env_var_value_if_defined('GITLAB_API_BASE') || 'https://gitlab.com/api/v4'
49
+ env_var_value_if_defined('GITLAB_API_BASE') || ci_api_v4_url
49
50
  end
50
51
 
51
52
  def pipeline_from_project_name
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitlabQuality
4
4
  module TestTooling
5
- VERSION = "0.2.2"
5
+ VERSION = "0.3.0"
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: 0.2.2
4
+ version: 0.3.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-05-10 00:00:00.000000000 Z
11
+ date: 2023-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -357,7 +357,6 @@ files:
357
357
  - lib/gitlab_quality/test_tooling/report/update_screenshot_path.rb
358
358
  - lib/gitlab_quality/test_tooling/runtime/env.rb
359
359
  - lib/gitlab_quality/test_tooling/runtime/logger.rb
360
- - lib/gitlab_quality/test_tooling/runtime/token_finder.rb
361
360
  - lib/gitlab_quality/test_tooling/slack/post_to_slack.rb
362
361
  - lib/gitlab_quality/test_tooling/summary_table.rb
363
362
  - lib/gitlab_quality/test_tooling/support/http_request.rb
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GitlabQuality
4
- module TestTooling
5
- module Runtime
6
- class TokenFinder
7
- def self.find_token!(token, suffix: nil)
8
- new(token, suffix).find_token!
9
- end
10
-
11
- attr_reader :token, :suffix
12
-
13
- def initialize(token, suffix)
14
- @token = token
15
- @suffix = suffix
16
- end
17
-
18
- def find_token!
19
- find_token_from_attrs || find_token_from_env || find_token_from_file
20
- end
21
-
22
- def find_token_from_attrs
23
- token
24
- end
25
-
26
- def find_token_from_env
27
- Env.gitlab_ci_api_token
28
- end
29
-
30
- def find_token_from_file
31
- @token_from_file ||= File.read(token_file_path).strip
32
- rescue Errno::ENOENT
33
- fail "Please provide a valid access token with the `-t/--token` option, the `GITLAB_CI_API_TOKEN` environment variable, or in the `#{token_file_path}` file!"
34
- end
35
-
36
- private
37
-
38
- def token_file_path
39
- @token_file_path ||= File.expand_path("../api_token#{"_#{suffix}" if suffix}", __dir__)
40
- end
41
- end
42
- end
43
- end
44
- end