allure-report-publisher 0.0.5 → 0.2.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: 2d7d2654f1e2f5e4afe6dd64d08bd24a9fc6764d24abfb06f2f52dc66df21d56
4
- data.tar.gz: cce27a83826622967fc3847c53275c8b087ef2e9c1aa216da3237081e75e3772
3
+ metadata.gz: 676e5c29b0fb534f66b54f22f06e5a9c7c3f429d7c2923fd6285139234cd563d
4
+ data.tar.gz: f68177fdde3a101fb501b47fb82897f7b48ba8e5669a1d1ee5f4a631364505a4
5
5
  SHA512:
6
- metadata.gz: 0141ca8082a561395e97f93e9b02bbe17e2aa69bfddc2146452769e6009824e29e2e23203e2e36ad54afaacfbb91701f30527e65c6599d5b8d6707b3e7e3ffb1
7
- data.tar.gz: 1420f1b3ec4fa386217bd4f0228bf59615772111190adcfb35f4ff68fce1de6eaa8bf39b173ec408ab4ef3c95645c00013c52d4acaca96cc4ab46efbe64bfb7e
6
+ metadata.gz: 826a881f81782358f580c4c5565c62d8b3dd06156bf224174d58149053c74a5d1e9456040c3dd6a136151ba0c091cf0fe74bcd3e945112dbe3a60eba4e05d6ba
7
+ data.tar.gz: 50da6a0a16eeb2bd24b1473003515c9fbd58fc28dfc171994129d9a13a796a5fbd2cef76a46358f7736385c6c67fa4dc097abd6f06ed494bc5c27e48b03c236f
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  [![Gem Version](https://img.shields.io/gem/v/allure-report-publisher?color=red)](https://rubygems.org/gems/allure-report-publisher)
2
+ [![Gem Pulls](https://img.shields.io/gem/dt/allure-report-publisher)](https://rubygems.org/gems/allure-report-publisher)
2
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
+ [![Docker Pulls](https://img.shields.io/docker/pulls/andrcuns/allure-report-publisher)](https://hub.docker.com/r/andrcuns/allure-report-publisher)
3
5
  ![Workflow status](https://github.com/andrcuns/allure-report-publisher/workflows/Test/badge.svg)
6
+ [![Test Report](https://img.shields.io/badge/report-allure-blue.svg)](https://storage.googleapis.com/allure-test-reports/allure-report-publisher/refs/heads/main/index.html)
4
7
  [![Maintainability](https://api.codeclimate.com/v1/badges/210eaa4f74588fb08313/maintainability)](https://codeclimate.com/github/andrcuns/allure-report-publisher/maintainability)
5
8
  [![Test Coverage](https://api.codeclimate.com/v1/badges/210eaa4f74588fb08313/test_coverage)](https://codeclimate.com/github/andrcuns/allure-report-publisher/test_coverage)
6
9
 
@@ -28,7 +31,7 @@ docker pull andrcuns/allure-report-publisher:latest
28
31
 
29
32
  allure-report-publisher will automatically detect if used in CI environment and add relevant executor info and history
30
33
 
31
- - `Allure report link`: requires `GITHUB_AUTH_TOKEN` or `GITLAB_AUTH_TOKEN` in order to update pull request description with link to latest report
34
+ - `--update-pr=(comment|description)`: requires `GITHUB_AUTH_TOKEN` or `GITLAB_AUTH_TOKEN` in order to update pull request with links to allure reports
32
35
 
33
36
  ```shell
34
37
  $ (allure-report-publisher|docker run --rm andrcuns/allure-report-publisher:latest) upload --help
@@ -42,16 +45,16 @@ Description:
42
45
  Generate and upload allure report
43
46
 
44
47
  Arguments:
45
- TYPE # REQUIRED Cloud storage type: (s3/gcs)
48
+ TYPE # REQUIRED Cloud storage type: (s3/gcs)
46
49
 
47
50
  Options:
48
- --results-glob=VALUE # Allure results files glob. Required: true
49
- --bucket=VALUE # Bucket name. Required: true
50
- --prefix=VALUE # Optional prefix for report path. Required: false
51
- --[no-]update-pr # Update pull request description with url to allure report, default: false
52
- --[no-]copy-latest # Keep copy of latest report at base prefix path, default: false
53
- --[no-]color # Toggle color output, default: false
54
- --help, -h # Print this help
51
+ --results-glob=VALUE # Allure results files glob. Required: true
52
+ --bucket=VALUE # Bucket name. Required: true
53
+ --prefix=VALUE # Optional prefix for report path. Required: false
54
+ --update-pr=VALUE # Add report url to PR via comment or description update. Required: false: (comment/description)
55
+ --[no-]copy-latest # Keep copy of latest report at base prefix path, default: false
56
+ --[no-]color # Toggle color output, default: false
57
+ --help, -h # Print this help
55
58
 
56
59
  Examples:
57
60
  allure-report-publisher upload s3 --results-glob='path/to/allure-result/**/*' --bucket=my-bucket
@@ -60,11 +63,28 @@ Examples:
60
63
 
61
64
  ### AWS S3
62
65
 
63
- - `AWS authentication`: requires environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` or credentials file `~/.aws/credentials`
66
+ Requires environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` or credentials file `~/.aws/credentials`
64
67
 
65
68
  ### Google Cloud Storage
66
69
 
67
- - `GCS authentication`: requires environment variable `GOOGLE_CLOUD_CREDENTIALS_JSON` with contents of credentials.json
70
+ Requires on of the following environment variables.
71
+
72
+ credentials.json file location:
73
+
74
+ - `STORAGE_CREDENTIALS`
75
+ - `STORAGE_KEYFILE`
76
+ - `GOOGLE_CLOUD_CREDENTIALS`
77
+ - `GOOGLE_CLOUD_KEYFILE`
78
+ - `GCLOUD_KEYFILE`
79
+
80
+ credentials.json contents:
81
+
82
+ - `GOOGLE_CLOUD_CREDENTIALS_JSON`
83
+ - `STORAGE_CREDENTIALS_JSON`
84
+ - `STORAGE_KEYFILE_JSON`
85
+ - `GOOGLE_CLOUD_CREDENTIALS_JSON`
86
+ - `GOOGLE_CLOUD_KEYFILE_JSON`
87
+ - `GCLOUD_KEYFILE_JSON`
68
88
 
69
89
  ## Development
70
90
 
@@ -20,9 +20,9 @@ module Publisher
20
20
  option :prefix,
21
21
  desc: "Optional prefix for report path. Required: false"
22
22
  option :update_pr,
23
- type: :boolean,
24
- default: false,
25
- desc: "Update pull request description with url to allure report"
23
+ type: :string,
24
+ values: %w[comment description],
25
+ desc: "Add report url to PR via comment or description update. Required: false"
26
26
  option :copy_latest,
27
27
  type: :boolean,
28
28
  default: false,
@@ -42,9 +42,18 @@ module Publisher
42
42
  validate_result_files(args[:results_glob])
43
43
  Helpers.pastel(force_color: args[:color] || nil)
44
44
 
45
- uploaders(args[:type])
46
- .new(**args.slice(:results_glob, :bucket, :prefix, :copy_latest, :update_pr))
47
- .execute
45
+ uploader = uploaders(args[:type]).new(**args.slice(:results_glob, :bucket, :prefix, :copy_latest, :update_pr))
46
+
47
+ log("Generating allure report")
48
+ Spinner.spin("generating") { uploader.generate_report }
49
+
50
+ log("Uploading allure report to #{args[:type]}")
51
+ Spinner.spin("uploading") { uploader.upload }
52
+ uploader.report_urls.each { |k, v| log("#{k}: #{v}", :green) }
53
+ return unless args[:update_pr] && uploader.pr?
54
+
55
+ log("Adding reports urls")
56
+ Spinner.spin("updating", exit_on_error: false) { uploader.add_url_to_pr }
48
57
  end
49
58
 
50
59
  private
@@ -10,7 +10,7 @@ module Publisher
10
10
  # @param [Boolean] force_color
11
11
  # @return [Pastel]
12
12
  def self.pastel(force_color: nil)
13
- @pastel ||= Pastel.new(enabled: force_color)
13
+ @pastel ||= Pastel.new(enabled: force_color, eachline: "\n")
14
14
  end
15
15
 
16
16
  # Check allure cli is installed and executable
@@ -99,7 +99,7 @@ module Publisher
99
99
  # @param [String] error_message
100
100
  # @return [void]
101
101
  def spinner_error(error_message)
102
- colored_message = colorize(error_message, error_color)
102
+ colored_message = colorize("failed\n#{error_message}", error_color)
103
103
  return spinner.error(colored_message) if tty?
104
104
 
105
105
  spinner.stop
@@ -13,12 +13,11 @@ module Publisher
13
13
  # Base class for CI executor info
14
14
  #
15
15
  class Provider
16
- EXECUTOR_JSON = "executor.json".freeze
17
- DESCRIPTION_PATTERN = /<!-- allure -->[\s\S]+<!-- allurestop -->/.freeze
16
+ ALLURE_JOB_NAME = "ALLURE_JOB_NAME".freeze
18
17
 
19
- def initialize(results_path, report_url)
20
- @results_path = results_path
18
+ def initialize(report_url:, update_pr:)
21
19
  @report_url = report_url
20
+ @update_pr = update_pr
22
21
  end
23
22
 
24
23
  # :nocov:
@@ -29,42 +28,27 @@ module Publisher
29
28
  def self.run_id
30
29
  raise("Not implemented!")
31
30
  end
32
- # :nocov:
33
31
 
34
- # Write executor info file
32
+ # Get executor info
35
33
  #
36
- # @return [void]
37
- def write_executor_info
38
- File.open("#{results_path}/#{EXECUTOR_JSON}", "w") do |file|
39
- file.write(executor_info.to_json)
40
- end
34
+ # @return [Hash]
35
+ def executor_info
36
+ raise("Not implemented!")
41
37
  end
38
+ # :nocov:
42
39
 
43
40
  # Add report url to pull request description
44
41
  #
45
42
  # @return [void]
46
43
  def add_report_url
47
44
  raise("Not a pull request, skipped!") unless pr?
45
+ return add_comment if comment?
48
46
 
49
- reported = pr_description.match?(DESCRIPTION_PATTERN)
50
- return update_pr_description(pr_description.gsub(DESCRIPTION_PATTERN, description_template).strip) if reported
51
-
52
- update_pr_description("#{pr_description}\n\n#{description_template}".strip)
47
+ update_pr_description
53
48
  end
54
49
 
55
- private
56
-
57
- attr_reader :results_path, :report_url
58
-
59
50
  # :nocov:
60
51
 
61
- # Get executor info
62
- #
63
- # @return [Hash]
64
- def executor_info
65
- raise("Not implemented!")
66
- end
67
-
68
52
  # Pull request run
69
53
  #
70
54
  # @return [Boolean]
@@ -72,6 +56,10 @@ module Publisher
72
56
  raise("Not implemented!")
73
57
  end
74
58
 
59
+ private
60
+
61
+ attr_reader :report_url, :update_pr
62
+
75
63
  # Current pull request description
76
64
  #
77
65
  # @return [String]
@@ -81,9 +69,29 @@ module Publisher
81
69
 
82
70
  # Update pull request description
83
71
  #
84
- # @param [String] _desc
85
72
  # @return [void]
86
- def update_pr_description(_desc)
73
+ def update_pr_description
74
+ raise("Not implemented!")
75
+ end
76
+
77
+ # Add comment with report url
78
+ #
79
+ # @return [void]
80
+ def add_comment
81
+ raise("Not implemented!")
82
+ end
83
+
84
+ # Build name
85
+ #
86
+ # @return [String]
87
+ def build_name
88
+ raise("Not implemented!")
89
+ end
90
+
91
+ # Commit SHA url
92
+ #
93
+ # @return [String]
94
+ def sha_url
87
95
  raise("Not implemented!")
88
96
  end
89
97
  # :nocov:
@@ -95,16 +103,18 @@ module Publisher
95
103
  self.class.run_id
96
104
  end
97
105
 
98
- # Allure report url pr description
106
+ # Add report url as comment
99
107
  #
100
- # @return [String]
101
- def description_template
102
- <<~DESC
103
- <!-- allure -->
104
- ---
105
- 📝 [Latest allure report](#{report_url})
106
- <!-- allurestop -->
107
- DESC
108
+ # @return [Boolean]
109
+ def comment?
110
+ update_pr == "comment"
111
+ end
112
+
113
+ # Report urls section creator
114
+ #
115
+ # @return [ReportUrls]
116
+ def report_urls
117
+ @report_urls ||= UrlSectionBuilder.new(report_url: report_url, build_name: build_name, sha_url: sha_url)
108
118
  end
109
119
  end
110
120
  end
@@ -5,6 +5,12 @@ module Publisher
5
5
  # Github implementation
6
6
  #
7
7
  class Github < Provider
8
+ # Set octokit to autopaginate
9
+ #
10
+ Octokit.configure do |config|
11
+ config.auto_paginate = true
12
+ end
13
+
8
14
  # Run id
9
15
  #
10
16
  # @return [String]
@@ -12,7 +18,12 @@ module Publisher
12
18
  @run_id ||= ENV["GITHUB_RUN_ID"]
13
19
  end
14
20
 
15
- private
21
+ # Pull request run
22
+ #
23
+ # @return [Boolean]
24
+ def pr?
25
+ ENV["GITHUB_EVENT_NAME"] == "pull_request"
26
+ end
16
27
 
17
28
  # Executor info
18
29
  #
@@ -30,6 +41,8 @@ module Publisher
30
41
  }
31
42
  end
32
43
 
44
+ private
45
+
33
46
  # Github api client
34
47
  #
35
48
  # @return [Octokit::Client]
@@ -41,11 +54,36 @@ module Publisher
41
54
  end
42
55
  end
43
56
 
44
- # Pull request run
57
+ # Update pull request description
45
58
  #
46
- # @return [Boolean]
47
- def pr?
48
- ENV["GITHUB_EVENT_NAME"] == "pull_request"
59
+ # @return [void]
60
+ def update_pr_description
61
+ client.update_pull_request(repository, pr_id, body: report_urls.updated_pr_description(pr_description))
62
+ end
63
+
64
+ # Add comment with report url
65
+ #
66
+ # @return [void]
67
+ def add_comment
68
+ return client.add_comment(repository, pr_id, report_urls.comment_body) unless comment
69
+
70
+ client.update_comment(repository, comment[:id], report_urls.comment_body(comment[:body]))
71
+ end
72
+
73
+ # Existing comment with allure urls
74
+ #
75
+ # @return [Sawyer::Resource]
76
+ def comment
77
+ @comment ||= client.issue_comments(repository, pr_id).detect do |comment|
78
+ UrlSectionBuilder.match?(comment[:body])
79
+ end
80
+ end
81
+
82
+ # Github event
83
+ #
84
+ # @return [Hash]
85
+ def github_event
86
+ @github_event ||= JSON.parse(File.read(ENV["GITHUB_EVENT_PATH"]), symbolize_names: true)
49
87
  end
50
88
 
51
89
  # Pull request description
@@ -55,19 +93,11 @@ module Publisher
55
93
  @pr_description ||= client.pull_request(repository, pr_id)[:body]
56
94
  end
57
95
 
58
- # Update pull request description
59
- #
60
- # @param [String] _desc
61
- # @return [void]
62
- def update_pr_description(desc)
63
- client.update_pull_request(repository, pr_id, body: desc)
64
- end
65
-
66
96
  # Pull request id
67
97
  #
68
98
  # @return [Integer]
69
99
  def pr_id
70
- @pr_id ||= JSON.parse(File.read(ENV["GITHUB_EVENT_PATH"]))["number"]
100
+ @pr_id ||= github_event[:number]
71
101
  end
72
102
 
73
103
  # Server url
@@ -88,7 +118,7 @@ module Publisher
88
118
  #
89
119
  # @return [String]
90
120
  def build_name
91
- @build_name ||= ENV["GITHUB_JOB"]
121
+ @build_name ||= ENV[ALLURE_JOB_NAME] || ENV["GITHUB_JOB"]
92
122
  end
93
123
 
94
124
  # Github repository
@@ -97,6 +127,16 @@ module Publisher
97
127
  def repository
98
128
  @repository ||= ENV["GITHUB_REPOSITORY"]
99
129
  end
130
+
131
+ # Commit sha url
132
+ #
133
+ # @return [String]
134
+ def sha_url
135
+ sha = github_event.dig(:pull_request, :head, :sha)
136
+ short_sha = sha[0..7]
137
+
138
+ "[#{short_sha}](#{server_url}/#{repository}/pull/#{pr_id}/commits/#{sha})"
139
+ end
100
140
  end
101
141
  end
102
142
  end
@@ -12,6 +12,13 @@ module Publisher
12
12
  @run_id ||= ENV["CI_PIPELINE_ID"]
13
13
  end
14
14
 
15
+ # Pull request run
16
+ #
17
+ # @return [Boolean]
18
+ def pr?
19
+ ENV["CI_PIPELINE_SOURCE"] == "merge_request_event"
20
+ end
21
+
15
22
  # Get executor info
16
23
  #
17
24
  # @return [Hash]
@@ -28,6 +35,8 @@ module Publisher
28
35
  }
29
36
  end
30
37
 
38
+ private
39
+
31
40
  # Current pull request description
32
41
  #
33
42
  # @return [String]
@@ -37,10 +46,27 @@ module Publisher
37
46
 
38
47
  # Update pull request description
39
48
  #
40
- # @param [String] desc
41
49
  # @return [void]
42
- def update_pr_description(desc)
43
- client.update_merge_request(project, mr_iid, description: desc)
50
+ def update_pr_description
51
+ client.update_merge_request(project, mr_iid, description: report_urls.updated_pr_description(pr_description))
52
+ end
53
+
54
+ # Add comment with report url
55
+ #
56
+ # @return [void]
57
+ def add_comment
58
+ return client.create_merge_request_comment(project, mr_iid, report_urls.comment_body) unless comment
59
+
60
+ client.edit_merge_request_note(project, mr_iid, comment.id, report_urls.comment_body(comment.body))
61
+ end
62
+
63
+ # Existing comment with allure urls
64
+ #
65
+ # @return [Gitlab::ObjectifiedHash]
66
+ def comment
67
+ client.merge_request_comments(project, mr_iid).auto_paginate.detect do |comment|
68
+ UrlSectionBuilder.match?(comment.body)
69
+ end
44
70
  end
45
71
 
46
72
  # Get gitlab client
@@ -57,13 +83,6 @@ module Publisher
57
83
  end
58
84
  end
59
85
 
60
- # Pull request run
61
- #
62
- # @return [Boolean]
63
- def pr?
64
- ENV["CI_PIPELINE_SOURCE"] == "merge_request_event"
65
- end
66
-
67
86
  # Merge request iid
68
87
  #
69
88
  # @return [Integer]
@@ -89,15 +108,25 @@ module Publisher
89
108
  #
90
109
  # @return [String]
91
110
  def build_name
92
- @build_name ||= ENV["CI_JOB_NAME"]
111
+ @build_name ||= ENV[ALLURE_JOB_NAME] || ENV["CI_JOB_NAME"]
93
112
  end
94
113
 
95
- # Github repository
114
+ # Gitlab repository
96
115
  #
97
116
  # @return [String]
98
117
  def project
99
118
  @project ||= ENV["CI_PROJECT_PATH"]
100
119
  end
120
+
121
+ # Commit sha url
122
+ #
123
+ # @return [String]
124
+ def sha_url
125
+ sha = ENV["CI_MERGE_REQUEST_SOURCE_BRANCH_SHA"] || ENV["CI_COMMIT_SHA"]
126
+ short_sha = sha[0..7]
127
+
128
+ "[#{short_sha}](#{server_url}/#{project}/-/merge_requests/#{mr_iid}/diffs?commit_id=#{sha})"
129
+ end
101
130
  end
102
131
  end
103
132
  end
@@ -0,0 +1,97 @@
1
+ module Publisher
2
+ module Providers
3
+ # Urls section builder
4
+ #
5
+ class UrlSectionBuilder
6
+ DESCRIPTION_PATTERN = /<!-- allure -->[\s\S]+<!-- allurestop -->/.freeze
7
+ JOBS_PATTERN = /<!-- jobs -->\n([\s\S]+)\n<!-- jobs -->/.freeze
8
+
9
+ def initialize(report_url:, build_name:, sha_url:)
10
+ @report_url = report_url
11
+ @build_name = build_name
12
+ @sha_url = sha_url
13
+ end
14
+
15
+ # Matches url section pattern
16
+ #
17
+ # @param [String] urls_block
18
+ # @return [Boolean]
19
+ def self.match?(urls_block)
20
+ urls_block.match?(DESCRIPTION_PATTERN)
21
+ end
22
+
23
+ # Get urls for PR update
24
+ #
25
+ # @param [String] pr
26
+ # @return [String]
27
+ def updated_pr_description(pr_description)
28
+ return "#{pr_description}\n\n#{body}" unless pr_description.match?(DESCRIPTION_PATTERN)
29
+
30
+ job_entries = jobs_section(pr_description)
31
+ pr_description.gsub(DESCRIPTION_PATTERN, body(job_entries))
32
+ end
33
+
34
+ # Allure report url comment
35
+ #
36
+ # @return [String]
37
+ def comment_body(pr_comment = nil)
38
+ return body.gsub("---\n", "") unless pr_comment
39
+
40
+ job_entries = jobs_section(pr_comment)
41
+ body(job_entries).gsub("---\n", "")
42
+ end
43
+
44
+ attr_reader :report_url, :build_name, :sha_url
45
+
46
+ private
47
+
48
+ # Allure report url pr description
49
+ #
50
+ # @return [String]
51
+ def body(job_entries = job_entry)
52
+ @body ||= <<~BODY.strip
53
+ <!-- allure -->
54
+ ---
55
+ #{heading}
56
+
57
+ <!-- jobs -->
58
+ #{job_entries}
59
+ <!-- jobs -->
60
+ <!-- allurestop -->
61
+ BODY
62
+ end
63
+
64
+ # Url section heading
65
+ #
66
+ # @return [String]
67
+ def heading
68
+ @heading ||= "# Allure report\n`allure-report-publisher` generated allure report for #{sha_url}!"
69
+ end
70
+
71
+ # Return updated jobs section
72
+ #
73
+ # @param [String] urls
74
+ # @return [String]
75
+ def jobs_section(urls_block)
76
+ jobs = urls_block.match(JOBS_PATTERN)[1]
77
+ return jobs.gsub(job_entry_pattern, job_entry) if jobs.match?(job_entry_pattern)
78
+
79
+ "#{jobs}\n#{job_entry}"
80
+ end
81
+
82
+ # Single job report URL entry
83
+ #
84
+ # @return [String]
85
+ def job_entry
86
+ @job_entry ||= "**#{build_name}**: 📝 [allure report](#{report_url})<br />"
87
+ end
88
+
89
+ # Job entry pattern
90
+ #
91
+ # @return [RegExp]
92
+ def job_entry_pattern
93
+ @job_entry_pattern ||= %r{^\*\*#{build_name}\*\*:.*\[allure report\]\(.*\)<br />$}
94
+ end
95
+ end
96
+ end
97
+ end
@@ -10,35 +10,32 @@ module Publisher
10
10
  class ReportGenerator
11
11
  include Helpers
12
12
 
13
- def initialize(results_glob, results_dir, report_dir)
13
+ def initialize(results_glob, results_path, report_path)
14
14
  @results_glob = results_glob
15
- @results_dir = results_dir
16
- @report_dir = report_dir
15
+ @results_path = results_path
16
+ @report_path = report_path
17
17
  end
18
18
 
19
19
  # Generate allure report
20
20
  #
21
21
  # @return [void]
22
22
  def generate
23
- log("Generating allure report")
24
- Helpers::Spinner.spin("generating report") do
25
- aggregate_results
26
- generate_report
27
- end
23
+ aggregate_results
24
+ generate_report
28
25
  end
29
26
 
30
27
  private
31
28
 
32
- attr_reader :results_glob, :results_dir, :report_dir
29
+ attr_reader :results_glob, :results_path, :report_path
33
30
 
34
31
  # Copy all results files to results directory
35
32
  #
36
33
  # @return [void]
37
34
  def aggregate_results
38
35
  results = Dir.glob(results_glob)
39
- error("Missing allure results") if results.empty?
36
+ raise(NoAllureResultsError, "Missing allure results") if results.empty?
40
37
 
41
- FileUtils.cp(results, results_dir)
38
+ FileUtils.cp(results, results_path)
42
39
  end
43
40
 
44
41
  # Generate allure report
@@ -46,9 +43,9 @@ module Publisher
46
43
  # @return [void]
47
44
  def generate_report
48
45
  out, _err, status = Open3.capture3(
49
- "allure generate --clean --output #{report_dir} #{results_dir}"
46
+ "allure generate --clean --output #{report_path} #{results_path}"
50
47
  )
51
- error(out) unless status.success?
48
+ raise(AllureError, out) unless status.success?
52
49
  end
53
50
  end
54
51
  end
@@ -1,10 +1,13 @@
1
1
  module Publisher
2
2
  module Uploaders
3
+ class HistoryNotFoundError < StandardError; end
4
+
3
5
  # Uploader implementation
4
6
  #
5
7
  class Uploader
6
8
  include Helpers
7
9
 
10
+ EXECUTOR_JSON = "executor.json".freeze
8
11
  HISTORY = [
9
12
  "categories-trend.json",
10
13
  "duration-trend.json",
@@ -13,7 +16,7 @@ module Publisher
13
16
  "retry-trend.json"
14
17
  ].freeze
15
18
 
16
- def initialize(results_glob:, bucket:, update_pr: false, prefix: nil, copy_latest: false)
19
+ def initialize(results_glob:, bucket:, update_pr: nil, prefix: nil, copy_latest: false)
17
20
  @results_glob = results_glob
18
21
  @bucket_name = bucket
19
22
  @prefix = prefix
@@ -25,13 +28,52 @@ module Publisher
25
28
  #
26
29
  # @return [void]
27
30
  def execute
28
- client # initialize client and check for errors
29
-
30
- generate
31
+ generate_report
31
32
  upload
32
33
  add_url_to_pr
33
- rescue StandardError => e
34
- error(e.message)
34
+ end
35
+
36
+ # Generate allure report
37
+ #
38
+ # @return [void]
39
+ def generate_report
40
+ add_history
41
+ add_executor_info
42
+
43
+ ReportGenerator.new(results_glob, results_path, report_path).generate
44
+ end
45
+
46
+ # Upload report to storage provider
47
+ #
48
+ # @return [void]
49
+ def upload
50
+ run_uploads
51
+ end
52
+
53
+ # Add allure report url to pull request description
54
+ #
55
+ # @return [void]
56
+ def add_url_to_pr
57
+ return unless update_pr && ci_provider
58
+
59
+ ci_provider.add_report_url
60
+ end
61
+
62
+ # Uploaded report urls
63
+ #
64
+ # @return [Hash<String, String>] uploaded report urls
65
+ def report_urls
66
+ urls = { "Report url" => report_url }
67
+ urls["Latest report url"] = latest_report_url if copy_latest
68
+
69
+ urls
70
+ end
71
+
72
+ # Executed in PR pipeline
73
+ #
74
+ # @return [Boolean]
75
+ def pr?
76
+ ci_provider&.pr?
35
77
  end
36
78
 
37
79
  private
@@ -54,6 +96,13 @@ module Publisher
54
96
  raise("Not Implemented!")
55
97
  end
56
98
 
99
+ # Latest report url
100
+ #
101
+ # @return [String]
102
+ def latest_report_url
103
+ raise("Not Implemented!")
104
+ end
105
+
57
106
  # Download allure history
58
107
  #
59
108
  # @return [void]
@@ -87,11 +136,10 @@ module Publisher
87
136
  #
88
137
  # @return [void]
89
138
  def add_history
90
- log("Adding allure history")
91
- Helpers::Spinner.spin("adding history", exit_on_error: false) do
92
- create_history_dir
93
- download_history
94
- end
139
+ create_history_dir
140
+ download_history
141
+ rescue HistoryNotFoundError
142
+ nil
95
143
  end
96
144
 
97
145
  # Add CI executor info
@@ -100,32 +148,11 @@ module Publisher
100
148
  def add_executor_info
101
149
  return unless ci_provider
102
150
 
103
- log("Adding executor info")
104
- Helpers::Spinner.spin("adding executor") do
105
- ci_provider.write_executor_info
151
+ File.open("#{results_path}/#{EXECUTOR_JSON}", "w") do |file|
152
+ file.write(ci_provider.executor_info.to_json)
106
153
  end
107
154
  end
108
155
 
109
- # Generate allure report
110
- #
111
- # @return [void]
112
- def generate
113
- add_history
114
- add_executor_info
115
-
116
- ReportGenerator.new(results_glob, results_dir, report_dir).generate
117
- end
118
-
119
- # Upload report to storage provider
120
- #
121
- # @return [void]
122
- def upload
123
- log("Uploading report")
124
- Helpers::Spinner.spin("uploading report") { run_uploads }
125
- log("Run report: #{report_url}", :green)
126
- log("Latest report: #{latest_report_url}", :green) if copy_latest
127
- end
128
-
129
156
  # Run upload commands
130
157
  #
131
158
  # @return [void]
@@ -135,18 +162,6 @@ module Publisher
135
162
  upload_latest_copy if copy_latest
136
163
  end
137
164
 
138
- # Add allure report url to pull request description
139
- #
140
- # @return [void]
141
- def add_url_to_pr
142
- return unless update_pr && ci_provider
143
-
144
- log("Adding allure report link to pr description")
145
- Helpers::Spinner.spin("adding link", exit_on_error: false) do
146
- ci_provider.add_report_url
147
- end
148
- end
149
-
150
165
  # Get run id
151
166
  #
152
167
  # @return [String]
@@ -160,14 +175,14 @@ module Publisher
160
175
  def ci_provider
161
176
  return @ci_provider if defined?(@ci_provider)
162
177
 
163
- @ci_provider = Providers.provider&.new(results_dir, report_url)
178
+ @ci_provider = Providers.provider&.new(report_url: report_url, update_pr: update_pr)
164
179
  end
165
180
 
166
181
  # Fetch allure report history
167
182
  #
168
183
  # @return [void]
169
184
  def create_history_dir
170
- FileUtils.mkdir_p(path(results_dir, "history"))
185
+ FileUtils.mkdir_p(path(results_path, "history"))
171
186
  end
172
187
 
173
188
  # Report path prefix
@@ -184,15 +199,15 @@ module Publisher
184
199
  # Aggregated results directory
185
200
  #
186
201
  # @return [String]
187
- def results_dir
188
- @results_dir ||= Dir.mktmpdir("allure-results")
202
+ def results_path
203
+ @results_path ||= Dir.mktmpdir("allure-results")
189
204
  end
190
205
 
191
206
  # Allure report directory
192
207
  #
193
208
  # @return [String]
194
- def report_dir
195
- @report_dir ||= Dir.mktmpdir("allure-report")
209
+ def report_path
210
+ @report_path ||= Dir.mktmpdir("allure-report")
196
211
  end
197
212
 
198
213
  # Report files
@@ -200,7 +215,7 @@ module Publisher
200
215
  # @return [Array<Pathname>]
201
216
  def report_files
202
217
  @report_files ||= Pathname
203
- .glob("#{report_dir}/**/*")
218
+ .glob("#{report_path}/**/*")
204
219
  .reject(&:directory?)
205
220
  end
206
221
  end
@@ -41,9 +41,9 @@ module Publisher
41
41
  def download_history
42
42
  HISTORY.each do |file_name|
43
43
  file = bucket.file(key(prefix, "history", file_name))
44
- raise("Allure history from previous runs not found!") unless file
44
+ raise(HistoryNotFoundError, "Allure history from previous runs not found!") unless file
45
45
 
46
- file.download(path(results_dir, "history", file_name))
46
+ file.download(path(results_path, "history", file_name))
47
47
  end
48
48
  end
49
49
 
@@ -77,7 +77,7 @@ module Publisher
77
77
  args = files.map do |file|
78
78
  {
79
79
  file: file.to_s,
80
- path: key(key_prefix, file.relative_path_from(report_dir))
80
+ path: key(key_prefix, file.relative_path_from(report_path))
81
81
  }
82
82
  end
83
83
 
@@ -40,13 +40,13 @@ module Publisher
40
40
  def download_history
41
41
  HISTORY.each do |file|
42
42
  client.get_object(
43
- response_target: path(results_dir, "history", file),
43
+ response_target: path(results_path, "history", file),
44
44
  key: key(prefix, "history", file),
45
45
  bucket: bucket_name
46
46
  )
47
47
  end
48
48
  rescue Aws::S3::Errors::NoSuchKey
49
- raise("Allure history from previous runs not found!")
49
+ raise(HistoryNotFoundError, "Allure history from previous runs not found!")
50
50
  end
51
51
 
52
52
  # Upload allure history
@@ -80,7 +80,7 @@ module Publisher
80
80
  {
81
81
  body: File.new(file),
82
82
  bucket: bucket_name,
83
- key: key(key_prefix, file.relative_path_from(report_dir))
83
+ key: key(key_prefix, file.relative_path_from(report_path))
84
84
  }
85
85
  end
86
86
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Publisher
4
- VERSION = "0.0.5"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allure-report-publisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrejs Cunskis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-06 00:00:00.000000000 Z
11
+ date: 2021-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-s3
@@ -34,16 +34,22 @@ dependencies:
34
34
  name: dry-cli
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0.6'
40
+ - - "<"
38
41
  - !ruby/object:Gem::Version
39
- version: 0.6.0
42
+ version: '0.8'
40
43
  type: :runtime
41
44
  prerelease: false
42
45
  version_requirements: !ruby/object:Gem::Requirement
43
46
  requirements:
44
- - - "~>"
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0.6'
50
+ - - "<"
45
51
  - !ruby/object:Gem::Version
46
- version: 0.6.0
52
+ version: '0.8'
47
53
  - !ruby/object:Gem::Dependency
48
54
  name: gitlab
49
55
  requirement: !ruby/object:Gem::Requirement
@@ -160,6 +166,7 @@ files:
160
166
  - lib/allure_report_publisher/lib/providers/_provider.rb
161
167
  - lib/allure_report_publisher/lib/providers/github.rb
162
168
  - lib/allure_report_publisher/lib/providers/gitlab.rb
169
+ - lib/allure_report_publisher/lib/providers/url_section_builder.rb
163
170
  - lib/allure_report_publisher/lib/report_generator.rb
164
171
  - lib/allure_report_publisher/lib/uploaders/_uploader.rb
165
172
  - lib/allure_report_publisher/lib/uploaders/gcs.rb