allure-report-publisher 4.6.0 → 4.7.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: 84b1216ddf83d1b9b80c0cfaac966968abc6951b236a3a9003f08bbd13b34326
4
- data.tar.gz: 8617b7f328cccd34e2f3e9ace85e068a1fc487f6dca22f06c98089a3963521d9
3
+ metadata.gz: 383b5a328cf9acc9c7ef65bf6e63f807d936dc38a4125e908a5ea6c29ac6df18
4
+ data.tar.gz: 4348a6696f84c9c2fa5c36584b7e8e4313db19965ae2b182aeba8087a2520dc5
5
5
  SHA512:
6
- metadata.gz: 1a7b271815b2f5a3b93766a2e934ca9b509ab229defddbc43b3f53e2c12cf9e37d9b118779a5c9ef8b85ca0f2809aa20716ffea16017fd3b045e0b84b73a0ace
7
- data.tar.gz: 6958a9843470ecfba1da70ceb923b453bca8bd20598e8d60b0956eb85caa8ade5060000722d4944c81e9740fad4e1203a4f8d9dc30fbb3da02cf59203a972519
6
+ metadata.gz: a1b0faa886ce9d3ee4ccb0e3d3459190121b40fc136571476caa859f66480e2284d10b38570fea07ace0284b4fd711db114c4151968cdc95882c54b10e11c452
7
+ data.tar.gz: 710dc295a857b1fdc771f46e9a8c51b018f5832e43fc2e78fd5a9f800c5bfbf3b1326e0c0ae4aea02fd19b577a24dc18d2aedb988f634bda3c9c05fe8b1d2f6e
data/README.md CHANGED
@@ -3,8 +3,6 @@
3
3
  [![Docker Image Version (latest semver)](https://img.shields.io/docker/v/andrcuns/allure-report-publisher?color=blue&label=docker&sort=semver)](https://hub.docker.com/r/andrcuns/allure-report-publisher)
4
4
  [![Docker Pulls](https://img.shields.io/docker/pulls/andrcuns/allure-report-publisher)](https://hub.docker.com/r/andrcuns/allure-report-publisher)
5
5
  ![Workflow status](https://github.com/andrcuns/allure-report-publisher/workflows/Test/badge.svg)
6
- [![Maintainability](https://api.codeclimate.com/v1/badges/210eaa4f74588fb08313/maintainability)](https://codeclimate.com/github/andrcuns/allure-report-publisher/maintainability)
7
- [![Test Coverage](https://api.codeclimate.com/v1/badges/210eaa4f74588fb08313/test_coverage)](https://codeclimate.com/github/andrcuns/allure-report-publisher/test_coverage)
8
6
 
9
7
  Upload your report to a file storage of your choice.
10
8
 
@@ -38,22 +36,23 @@ Description:
38
36
  Generate and upload allure report
39
37
 
40
38
  Arguments:
41
- TYPE # REQUIRED Cloud storage type: (s3/gcs)
39
+ TYPE # REQUIRED Cloud storage type: (gcs/s3/gitlab-artifacts)
42
40
 
43
41
  Options:
44
42
  --results-glob=VALUE # Glob pattern to return allure results directories. Required: true
45
- --bucket=VALUE # Bucket name. Required: true
46
- --prefix=VALUE # Optional prefix for report path. Required: false
43
+ --bucket=VALUE # Bucket name. Required: true (gcs|s3), false (gitlab-artifacts)
44
+ --output=VALUE # Output directory for the report. Required: false. Defaults to 'allure-report' for gitlab-artifacts and random temporary directory for cloud based storage
45
+ --prefix=VALUE # Optional prefix for report path. Required: false. Ignored for gitlab-artifacts
47
46
  --update-pr=VALUE # Add report url to PR via comment or description update. Required: false: (comment/description/actions)
48
47
  --report-title=VALUE # Title for url section in PR comment/description. Required: false, default: "Allure Report"
49
48
  --report-name=VALUE # Custom report name in final Allure report. Required: false
50
49
  --summary=VALUE # Additionally add summary table to PR comment or description. Required: false: (behaviors/suites/packages/total), default: "total"
51
50
  --summary-table-type=VALUE # Summary table type. Required: false: (ascii/markdown), default: "ascii"
52
- --base-url=VALUE # Use custom base url instead of default cloud provider one. Required: false
51
+ --base-url=VALUE # Use custom base url instead of default cloud provider one. Required: false. Ignored for gitlab-artifacts
53
52
  --parallel=VALUE # Number of parallel threads to use for report file upload to cloud storage. Required: false, default: 8
54
53
  --[no-]flaky-warning-status # Mark run with a '!' status in PR comment/description if report contains flaky tests, default: false
55
54
  --[no-]collapse-summary # Create summary as a collapsible section, default: false
56
- --[no-]copy-latest # Keep copy of latest report at base prefix path, default: false
55
+ --[no-]copy-latest # Keep copy of latest report at base prefix path. Ignored for gitlab-artifacts, default: false
57
56
  --[no-]color # Force color output
58
57
  --[no-]ignore-missing-results # Ignore missing allure results, default: false
59
58
  --[no-]debug # Print additional debug output, default: false
@@ -62,6 +61,17 @@ Options:
62
61
  Examples:
63
62
  allure-report-publisher upload s3 --results-glob='path/to/allure-results' --bucket=my-bucket
64
63
  allure-report-publisher upload gcs --results-glob='paths/to/**/allure-results' --bucket=my-bucket --prefix=my-project/prs
64
+ allure-report-publisher upload gitlab-artifacts --results-glob='paths/to/**/allure-results'
65
+ ```
66
+
67
+ ## Extra arguments
68
+
69
+ You can pass any extra arguments to the `allure generate` command by using `--` before the arguments.
70
+
71
+ Example:
72
+
73
+ ```shell
74
+ allure-report-publisher upload s3 --results-glob='path/to/allure-results' --bucket=my-bucket -- --lang en
65
75
  ```
66
76
 
67
77
  ## Environment variables
@@ -105,6 +115,23 @@ credentials.json contents:
105
115
  - `GOOGLE_CLOUD_KEYFILE_JSON`
106
116
  - `GCLOUD_KEYFILE_JSON`
107
117
 
118
+ ## Gitlab Artifacts
119
+
120
+ This storage provider is only supported for GitLab CI. Because GitLab does not expose public api for uploading artifacts, a job must be configured to upload the report as an artifact. Example:
121
+
122
+ ```yaml
123
+ # .gitlab-ci.yml
124
+ artifacts:
125
+ paths:
126
+ - allure-report
127
+ ```
128
+
129
+ where `allure-report` is the directory containing the generated Allure report and can be overridden via `--output` option.
130
+
131
+ Requires environment variable `GITLAB_AUTH_TOKEN` where token is a GitLab personal access token with `api` scope capable of downloading artifacts and retrieving job and pipeline information.
132
+
133
+ This provider is meant to be used with [GitLab CI](#gitlab-ci).
134
+
108
135
  # CI
109
136
 
110
137
  `allure-report-publisher` will automatically detect if used in CI environment and add relevant executor info and history.
@@ -7,20 +7,25 @@ module Publisher
7
7
  class Upload < Dry::CLI::Command
8
8
  include Helpers
9
9
 
10
+ STORAGE_PROVIDERS = %w[gcs s3 gitlab-artifacts].freeze
11
+
10
12
  desc "Generate and upload allure report"
11
13
 
12
14
  argument :type,
13
15
  type: :string,
14
16
  required: true,
15
- values: %w[s3 gcs],
17
+ values: STORAGE_PROVIDERS,
16
18
  desc: "Cloud storage type"
17
19
 
20
+ # rubocop:disable Layout/LineLength
18
21
  option :results_glob,
19
22
  desc: "Glob pattern to return allure results directories. Required: true"
20
23
  option :bucket,
21
- desc: "Bucket name. Required: true"
24
+ desc: "Bucket name. Required: true (gcs|s3), false (gitlab-artifacts)"
25
+ option :output,
26
+ desc: "Output directory for the report. Required: false. Defaults to 'allure-report' for gitlab-artifacts and random temporary directory for cloud based storage"
22
27
  option :prefix,
23
- desc: "Optional prefix for report path. Required: false"
28
+ desc: "Optional prefix for report path. Required: false. Ignored for gitlab-artifacts"
24
29
  option :update_pr,
25
30
  type: :string,
26
31
  desc: "Add report url to PR via comment or description update. Required: false",
@@ -52,7 +57,7 @@ module Publisher
52
57
  ]
53
58
  option :base_url,
54
59
  type: :string,
55
- desc: "Use custom base url instead of default cloud provider one. Required: false"
60
+ desc: "Use custom base url instead of default cloud provider one. Required: false. Ignored for gitlab-artifacts"
56
61
  option :parallel,
57
62
  type: :integer,
58
63
  desc: "Number of parallel threads to use for report file upload to cloud storage. Required: false",
@@ -68,7 +73,7 @@ module Publisher
68
73
  option :copy_latest,
69
74
  type: :boolean,
70
75
  default: false,
71
- desc: "Keep copy of latest report at base prefix path"
76
+ desc: "Keep copy of latest report at base prefix path. Ignored for gitlab-artifacts"
72
77
  option :color,
73
78
  type: :boolean,
74
79
  desc: "Force color output"
@@ -80,17 +85,19 @@ module Publisher
80
85
  type: :boolean,
81
86
  default: false,
82
87
  desc: "Print additional debug output"
88
+ # rubocop:enable Layout/LineLength
83
89
 
84
90
  example [
85
91
  "s3 --results-glob='path/to/allure-results' --bucket=my-bucket",
86
- "gcs --results-glob='paths/to/**/allure-results' --bucket=my-bucket --prefix=my-project/prs"
92
+ "gcs --results-glob='paths/to/**/allure-results' --bucket=my-bucket --prefix=my-project/prs",
93
+ "gitlab-artifacts --results-glob='paths/to/**/allure-results'"
87
94
  ]
88
95
 
89
96
  def call(args: [], **arguments)
90
97
  Helpers.pastel(force_color: arguments[:color])
91
98
  @args = arguments
92
99
 
93
- validate_args
100
+ validate_args!
94
101
  scan_results_paths
95
102
 
96
103
  generate_report(args)
@@ -106,6 +113,17 @@ module Publisher
106
113
 
107
114
  attr_reader :args
108
115
 
116
+ # Report output path
117
+ #
118
+ # @return [String] output path
119
+ def output
120
+ @output ||= args[:output].then do |path|
121
+ next if path
122
+
123
+ gitlab_artifacts? ? "allure-report" : File.join(Dir.tmpdir, "allure-report-#{Time.now.to_i}")
124
+ end
125
+ end
126
+
109
127
  # Uploader instance
110
128
  #
111
129
  # @return [Publisher::Uploaders::Uploader]
@@ -113,6 +131,7 @@ module Publisher
113
131
  @uploader ||= uploaders(args[:type]).new(
114
132
  result_paths: @result_paths,
115
133
  parallel: parallel_threads,
134
+ output: output,
116
135
  **args.slice(:bucket, :prefix, :base_url, :copy_latest, :report_name)
117
136
  )
118
137
  end
@@ -123,7 +142,7 @@ module Publisher
123
142
  def ci_provider
124
143
  @ci_provider = Providers.provider&.new(
125
144
  report_url: uploader.report_url,
126
- report_path: uploader.report_path,
145
+ report_path: output,
127
146
  summary_type: args[:summary],
128
147
  **args.slice(
129
148
  :update_pr,
@@ -142,19 +161,39 @@ module Publisher
142
161
  def uploaders(uploader)
143
162
  {
144
163
  "s3" => Uploaders::S3,
145
- "gcs" => Uploaders::GCS
164
+ "gcs" => Uploaders::GCS,
165
+ "gitlab-artifacts" => Uploaders::GitlabArtifacts
146
166
  }.fetch(uploader)
147
167
  end
148
168
 
149
169
  # Validate required args
150
170
  #
151
171
  # @return [void]
152
- def validate_args
153
- error("Unsupported cloud storage type! Supported types are: s3, gcs") unless %w[s3 gcs].include?(args[:type])
172
+ def validate_args!
173
+ validate_base_args!
174
+ validate_base_url!
175
+ cast_parallel_threads_arg!
176
+ end
177
+
178
+ # Check base arguments
179
+ #
180
+ # @return [void]
181
+ def validate_base_args!
182
+ unless STORAGE_PROVIDERS.include?(args[:type])
183
+ error("Unsupported storage type! Supported types are: #{STORAGE_PROVIDERS.join(', ')}")
184
+ end
185
+
154
186
  error("Missing argument --results-glob!") unless args[:results_glob]
155
- error("Missing argument --bucket!") unless args[:bucket]
156
- URI.parse(args[:base_url]) if args[:base_url]
157
- validate_parallel_args
187
+ error("Missing argument --bucket!") unless gitlab_artifacts? || args[:bucket]
188
+ end
189
+
190
+ # Check base URL is a valid URI
191
+ #
192
+ # @return [void]
193
+ def validate_base_url!
194
+ return unless args[:base_url] && !gitlab_artifacts?
195
+
196
+ URI.parse(args[:base_url])
158
197
  rescue URI::InvalidURIError
159
198
  error("Invalid --base-url value!")
160
199
  end
@@ -169,7 +208,7 @@ module Publisher
169
208
  rescue ArgumentError
170
209
  error("Invalid --parallel value, must be a positive number!")
171
210
  end
172
- alias validate_parallel_args parallel_threads
211
+ alias cast_parallel_threads_arg! parallel_threads
173
212
 
174
213
  # Scan for allure results paths
175
214
  #
@@ -186,6 +225,13 @@ module Publisher
186
225
  exit(ignore ? 0 : 1)
187
226
  end
188
227
 
228
+ # Gitlab artifacts store
229
+ #
230
+ # @return [Boolean] true if gitlab artifacts store is used
231
+ def gitlab_artifacts?
232
+ args[:type] == "gitlab-artifacts"
233
+ end
234
+
189
235
  # Generate allure report
190
236
  #
191
237
  # @param [Array<String>] extra_args
@@ -200,7 +246,13 @@ module Publisher
200
246
  # @return [void]
201
247
  def upload_report
202
248
  log("Uploading allure report to #{args[:type]}")
203
- Spinner.spin("uploading", debug: args[:debug]) { uploader.upload }
249
+ # gitlab-artifacts by default will raise error with info about upload using artifacts
250
+ spinner_args = {
251
+ debug: args[:debug],
252
+ exit_on_error: !gitlab_artifacts?,
253
+ failed_message: gitlab_artifacts? ? "skipped" : nil
254
+ }.compact
255
+ Spinner.spin("uploading", **spinner_args) { uploader.upload }
204
256
  uploader.report_urls.each { |k, v| log("#{k}: #{v}", :green) }
205
257
  end
206
258
 
@@ -64,6 +64,18 @@ module Publisher
64
64
  ENV[name]
65
65
  end
66
66
 
67
+ # Return environment variable as integer if it's numeric
68
+ #
69
+ # @param [String] name
70
+ # @return [Integer, nil]
71
+ def env_int(name)
72
+ value = env(name)
73
+ return unless value
74
+ raise("Invalid integer value for #{name}") unless value.match?(/\A-?\d+\z/)
75
+
76
+ value.to_i
77
+ end
78
+
67
79
  module_function
68
80
 
69
81
  # Colorize string
@@ -24,20 +24,27 @@ module Publisher
24
24
  # @param [Boolean] exit_on_error
25
25
  # @param [Proc] &block
26
26
  # @return [void]
27
- def self.spin(spinner_message, done_message: "done", exit_on_error: true, debug: false, &block)
28
- new(spinner_message, exit_on_error: exit_on_error, debug: debug).spin(done_message, &block)
27
+ def self.spin(
28
+ spinner_message,
29
+ done_message: "done",
30
+ failed_message: "failed",
31
+ exit_on_error: true,
32
+ debug: false,
33
+ &block
34
+ )
35
+ new(spinner_message, exit_on_error: exit_on_error, debug: debug).spin(done_message, failed_message, &block)
29
36
  end
30
37
 
31
38
  # Run code block inside spinner
32
39
  #
33
40
  # @param [String] done_message
34
41
  # @return [Boolean]
35
- def spin(done_message = "done")
42
+ def spin(done_message = "done", failed_message = "failed")
36
43
  spinner.auto_spin
37
44
  yield
38
45
  spinner_success(done_message)
39
46
  rescue StandardError => e
40
- spinner_error(e)
47
+ spinner_error(e, done_message: failed_message)
41
48
  raise(Failure, e.message) if exit_on_error
42
49
  ensure
43
50
  print_debug
@@ -119,8 +126,8 @@ module Publisher
119
126
  #
120
127
  # @param [StandardError] error
121
128
  # @return [void]
122
- def spinner_error(error)
123
- message = ["failed", error.message]
129
+ def spinner_error(error, done_message: "failed")
130
+ message = [done_message, error.message]
124
131
  log_debug("Error: #{error.message}\n#{error.backtrace.join("\n")}")
125
132
 
126
133
  colored_message = colorize(message.compact.join("\n"), error_color)
@@ -19,18 +19,8 @@ module Publisher
19
19
  def_delegators :"Publisher::Providers::Info::Github.instance",
20
20
  :repository,
21
21
  :server_url,
22
- :build_name
23
-
24
- # Github api client
25
- #
26
- # @return [Octokit::Client]
27
- def client
28
- @client ||= begin
29
- raise("Missing GITHUB_AUTH_TOKEN environment variable!") unless ENV["GITHUB_AUTH_TOKEN"]
30
-
31
- Octokit::Client.new(access_token: ENV["GITHUB_AUTH_TOKEN"], api_endpoint: ENV["GITHUB_API_URL"])
32
- end
33
- end
22
+ :build_name,
23
+ :client
34
24
 
35
25
  # Update pull request description
36
26
  #
@@ -15,21 +15,8 @@ module Publisher
15
15
  :mr_iid,
16
16
  :allure_mr_iid,
17
17
  :server_url,
18
- :build_name
19
-
20
- # Get gitlab client
21
- #
22
- # @return [Gitlab::Client]
23
- def client
24
- @client ||= begin
25
- raise("Missing GITLAB_AUTH_TOKEN environment variable!") unless env("GITLAB_AUTH_TOKEN")
26
-
27
- ::Gitlab::Client.new(
28
- endpoint: "#{server_url}/api/v4",
29
- private_token: env("GITLAB_AUTH_TOKEN")
30
- )
31
- end
32
- end
18
+ :build_name,
19
+ :client
33
20
 
34
21
  # Current pull request description
35
22
  #
@@ -11,6 +11,13 @@ module Publisher
11
11
 
12
12
  # :nocov:
13
13
 
14
+ # CI provider api client
15
+ #
16
+ # @return [Object]
17
+ def client
18
+ raise("Not implemented!")
19
+ end
20
+
14
21
  # CI Provider executor info
15
22
  #
16
23
  # @param [String] report_url
@@ -23,6 +23,17 @@ module Publisher
23
23
  }
24
24
  end
25
25
 
26
+ # Github api client
27
+ #
28
+ # @return [Octokit::Client]
29
+ def client
30
+ @client ||= begin
31
+ raise("Missing GITHUB_AUTH_TOKEN environment variable!") unless ENV["GITHUB_AUTH_TOKEN"]
32
+
33
+ Octokit::Client.new(access_token: ENV["GITHUB_AUTH_TOKEN"], api_endpoint: ENV["GITHUB_API_URL"])
34
+ end
35
+ end
36
+
26
37
  # Pull request run
27
38
  #
28
39
  # @return [Boolean]
@@ -23,6 +23,20 @@ module Publisher
23
23
  }
24
24
  end
25
25
 
26
+ # Get gitlab client
27
+ #
28
+ # @return [Gitlab::Client]
29
+ def client
30
+ @client ||= begin
31
+ raise("Missing GITLAB_AUTH_TOKEN environment variable!") unless env("GITLAB_AUTH_TOKEN")
32
+
33
+ ::Gitlab::Client.new(
34
+ endpoint: "#{server_url}/api/v4",
35
+ private_token: env("GITLAB_AUTH_TOKEN")
36
+ )
37
+ end
38
+ end
39
+
26
40
  # Pull request run
27
41
  #
28
42
  # @return [Boolean]
@@ -32,9 +46,48 @@ module Publisher
32
46
 
33
47
  # Get ci run ID without creating instance of ci provider
34
48
  #
35
- # @return [String]
49
+ # @return [Integer]
36
50
  def run_id
37
- @run_id ||= env(ALLURE_RUN_ID) || ENV["CI_PIPELINE_ID"]
51
+ @run_id ||= env_int(ALLURE_RUN_ID) || env_int("CI_PIPELINE_ID")
52
+ end
53
+
54
+ # CI job ID
55
+ #
56
+ # @return [Integer]
57
+ def job_id
58
+ @job_id ||= env_int("CI_JOB_ID")
59
+ end
60
+
61
+ # Gitlab pages hostname
62
+ #
63
+ # @return [String]
64
+ def pages_hostname
65
+ @pages_hostname ||= env("CI_PAGES_HOSTNAME")
66
+ end
67
+
68
+ # CI project name
69
+ #
70
+ # @return [String]
71
+ def project_name
72
+ @project_name ||= env("CI_PROJECT_NAME")
73
+ end
74
+
75
+ # CI project ID
76
+ #
77
+ # @return [Integer]
78
+ def project_id
79
+ @project_id ||= env_int("CI_PROJECT_ID")
80
+ end
81
+
82
+ # Project directory
83
+ #
84
+ # @return [String] build directory
85
+ def build_dir
86
+ @build_dir ||= env("CI_PROJECT_DIR")
87
+ end
88
+
89
+ def branch
90
+ @branch ||= env("CI_MERGE_REQUEST_SOURCE_BRANCH_NAME") || env("CI_COMMIT_REF_NAME")
38
91
  end
39
92
 
40
93
  # Server url
@@ -62,21 +115,28 @@ module Publisher
62
115
  #
63
116
  # @return [Integer]
64
117
  def mr_iid
65
- @mr_iid ||= allure_mr_iid || env("CI_MERGE_REQUEST_IID")
118
+ @mr_iid ||= allure_mr_iid || env_int("CI_MERGE_REQUEST_IID")
66
119
  end
67
120
 
68
121
  # Custom mr iid name
69
122
  #
70
- # @return [String]
123
+ # @return [Integer]
71
124
  def allure_mr_iid
72
- @allure_mr_iid ||= env("ALLURE_MERGE_REQUEST_IID")
125
+ @allure_mr_iid ||= env_int("ALLURE_MERGE_REQUEST_IID")
73
126
  end
74
127
 
75
- # Job name
128
+ # Job name used in report
76
129
  #
77
130
  # @return [String]
78
131
  def build_name
79
- @build_name ||= env(ALLURE_JOB_NAME) || env("CI_JOB_NAME")
132
+ @build_name ||= env(ALLURE_JOB_NAME) || job_name
133
+ end
134
+
135
+ # CI job name
136
+ #
137
+ # @return [String]
138
+ def job_name
139
+ @job_name ||= env("CI_JOB_NAME")
80
140
  end
81
141
  end
82
142
  end
@@ -10,9 +10,10 @@ module Publisher
10
10
  class ReportGenerator
11
11
  include Helpers
12
12
 
13
- def initialize(result_paths, report_name)
13
+ def initialize(result_paths, report_name, report_path)
14
14
  @result_paths = result_paths.join(" ")
15
15
  @report_name = report_name
16
+ @report_path = report_path
16
17
  end
17
18
 
18
19
  # Generate allure report
@@ -35,12 +36,8 @@ module Publisher
35
36
  end
36
37
  alias create_common_path common_info_path
37
38
 
38
- # Allure report directory
39
- #
40
- # @return [String]
41
- def report_path
42
- @report_path ||= File.join(Dir.tmpdir, "allure-report-#{Time.now.to_i}")
43
- end
39
+ # @return [String] report path
40
+ attr_reader :report_path
44
41
 
45
42
  private
46
43
 
@@ -30,6 +30,7 @@ module Publisher
30
30
  # @option args [String] :copy_latest
31
31
  # @option args [String] :report_name
32
32
  # @option args [Integer] :parallel
33
+ # @option args [String] :output
33
34
  def initialize(**args)
34
35
  @result_paths = args[:result_paths]
35
36
  @bucket_name = args[:bucket]
@@ -38,6 +39,7 @@ module Publisher
38
39
  @copy_latest = ci_info && args[:copy_latest] # copy latest for ci only
39
40
  @report_name = args[:report_name]
40
41
  @parallel = args[:parallel]
42
+ @report_path = args[:output]
41
43
  end
42
44
 
43
45
  # Generate allure report
@@ -90,7 +92,8 @@ module Publisher
90
92
  :base_url,
91
93
  :copy_latest,
92
94
  :report_name,
93
- :parallel
95
+ :parallel,
96
+ :report_path
94
97
 
95
98
  def_delegator :report_generator, :common_info_path
96
99
 
@@ -151,7 +154,7 @@ module Publisher
151
154
  #
152
155
  # @return [Publisher::ReportGenerator]
153
156
  def report_generator
154
- @report_generator ||= ReportGenerator.new(result_paths, report_name)
157
+ @report_generator ||= ReportGenerator.new(result_paths, report_name, report_path)
155
158
  end
156
159
 
157
160
  # Report path prefix
@@ -210,7 +213,7 @@ module Publisher
210
213
  end
211
214
  end
212
215
 
213
- # Fetch allure report history
216
+ # Create allure report history dir
214
217
  #
215
218
  # @return [void]
216
219
  def create_history_dir
@@ -0,0 +1,122 @@
1
+ module Publisher
2
+ module Uploaders
3
+ # Uploads artifacts to GitLab
4
+ #
5
+ class GitlabArtifacts < Uploader
6
+ extend Forwardable
7
+
8
+ def initialize(**args)
9
+ super
10
+
11
+ # gitlab artifacts do not support having url to latest report
12
+ @copy_latest = false
13
+ end
14
+
15
+ # Report url
16
+ #
17
+ # @return [String]
18
+ def report_url
19
+ @report_url ||= "https://#{pages_hostname}/-/#{project_name}/-/jobs/#{job_id}/artifacts/#{report_path}/index.html"
20
+ end
21
+
22
+ # No-op method as gitlab does not expose api to upload artifacts
23
+ #
24
+ # @return [void]
25
+ def upload
26
+ raise("Gitlab artifacts does not support upload operation! Report upload must be configured in the CI job.")
27
+ end
28
+
29
+ private
30
+
31
+ def_delegators :ci_info,
32
+ :pages_hostname,
33
+ :project_name,
34
+ :project_id,
35
+ :job_name,
36
+ :job_id,
37
+ :branch,
38
+ :build_dir,
39
+ :build_name,
40
+ :server_url,
41
+ :client
42
+
43
+ # Download allure history
44
+ #
45
+ # @return [void]
46
+ def download_history
47
+ log_debug("Downloading allure history from previous executions")
48
+
49
+ unless previous_job_id
50
+ log_debug("Previous execution not found, skipping history download")
51
+ return
52
+ end
53
+
54
+ log_debug("Fetching history from artifacts of job: #{previous_job_id}")
55
+ HISTORY.each do |file_name|
56
+ download_artifact_file(
57
+ previous_job_id,
58
+ "#{report_path}/history/#{file_name}",
59
+ path(common_info_path, "history", file_name)
60
+ )
61
+ end
62
+ end
63
+
64
+ # Last job from previous pipeline
65
+ #
66
+ # @return [Integer, nil] job id or nil if not found
67
+ def previous_job_id
68
+ return @previous_job_id if defined?(@previous_job_id)
69
+
70
+ log_debug("Fetching previous pipelines for ref: #{branch}")
71
+ pipelines = client.pipelines(
72
+ project_id,
73
+ ref: branch,
74
+ per_page: 50
75
+ ).map(&:id)
76
+ return @previous_pipeline_job_id = nil if pipelines.size < 2
77
+
78
+ previous_pipeline_index = pipelines.index(run_id) + 1
79
+ return @previous_job_id = nil if previous_pipeline_index >= pipelines.size
80
+
81
+ log_debug("Fetching last job id from pipeline: #{pipelines[previous_pipeline_index]}")
82
+ @previous_job_id = client.pipeline_jobs(
83
+ project_id,
84
+ pipelines[previous_pipeline_index],
85
+ scope: %w[success failed]
86
+ ).find { |job| job.name == build_name }&.id
87
+ end
88
+
89
+ # Current ref pipelines
90
+ #
91
+ # @return [Array<Hash>]
92
+ def pipelines
93
+ @pipelines ||= client.pipelines(project_id, ref: branch, per_page: 10)
94
+ end
95
+
96
+ def latest_job
97
+ @latest_job ||= pipelines.max_by(&:id)
98
+ end
99
+
100
+ # CI info
101
+ #
102
+ # @return [Providers::Info::Gitlab]
103
+ def ci_info
104
+ Providers::Info::Gitlab.instance
105
+ end
106
+
107
+ # Download specific artifact file
108
+ #
109
+ # @param job_id [Integer] job id
110
+ # @param artifact_path [String] path within artifacts
111
+ # @param local_path [String] local file path to save
112
+ # @return [void]
113
+ def download_artifact_file(job_id, artifact_path, local_path)
114
+ log_debug("Downloading artifact file: #{artifact_path} to #{local_path}")
115
+ # this will only work with history json files, see: https://github.com/NARKOZ/gitlab/issues/621
116
+ response = client.download_job_artifact_file(project_id, job_id, artifact_path)
117
+
118
+ File.write(local_path, response.to_json)
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Publisher
4
- VERSION = "4.6.0"
4
+ VERSION = "4.7.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allure-report-publisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.0
4
+ version: 4.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrejs Cunskis
@@ -18,7 +18,7 @@ dependencies:
18
18
  version: 1.93.1
19
19
  - - "<"
20
20
  - !ruby/object:Gem::Version
21
- version: 1.193.0
21
+ version: 1.197.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -28,7 +28,7 @@ dependencies:
28
28
  version: 1.93.1
29
29
  - - "<"
30
30
  - !ruby/object:Gem::Version
31
- version: 1.193.0
31
+ version: 1.197.0
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: dry-cli
34
34
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +38,7 @@ dependencies:
38
38
  version: '0.6'
39
39
  - - "<"
40
40
  - !ruby/object:Gem::Version
41
- version: '1.3'
41
+ version: '1.4'
42
42
  type: :runtime
43
43
  prerelease: false
44
44
  version_requirements: !ruby/object:Gem::Requirement
@@ -48,7 +48,7 @@ dependencies:
48
48
  version: '0.6'
49
49
  - - "<"
50
50
  - !ruby/object:Gem::Version
51
- version: '1.3'
51
+ version: '1.4'
52
52
  - !ruby/object:Gem::Dependency
53
53
  name: faraday-retry
54
54
  requirement: !ruby/object:Gem::Requirement
@@ -240,6 +240,7 @@ files:
240
240
  - lib/allure_report_publisher/lib/report_generator.rb
241
241
  - lib/allure_report_publisher/lib/uploaders/_uploader.rb
242
242
  - lib/allure_report_publisher/lib/uploaders/gcs.rb
243
+ - lib/allure_report_publisher/lib/uploaders/gitlab_artifacts.rb
243
244
  - lib/allure_report_publisher/lib/uploaders/s3.rb
244
245
  - lib/allure_report_publisher/version.rb
245
246
  homepage: https://github.com/andrcuns/allure-report-uploader
@@ -265,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
265
266
  - !ruby/object:Gem::Version
266
267
  version: '0'
267
268
  requirements: []
268
- rubygems_version: 3.6.7
269
+ rubygems_version: 3.6.9
269
270
  specification_version: 4
270
271
  summary: Allure report uploader
271
272
  test_files: []