allure-report-publisher 0.0.6 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be6f833714e1ff2ad413a9b5148cebd6454b23db763f567586b9e91222513524
4
- data.tar.gz: 6984e37c220f693288037522a86716079f3a235634c3ccbdd360056fd186f83c
3
+ metadata.gz: 2212afd20c080df89b88eab18ae8fa96a6b8d00027af95b2b606e9b851b83dde
4
+ data.tar.gz: b6473ed381ddb267af1fcaee0ef6080a3c8063dac4d56ea5cbf0589457c7598e
5
5
  SHA512:
6
- metadata.gz: d11ad18cdfb6c1955e521d8aae653b823f5defcfae4b095ae27f9bc9d1d0c89bca0336ab647c543b4c5d2cb92d2bffcd2c23343266b254aa1331984ac02abae9
7
- data.tar.gz: 023da790f7233de7da68520ea85e2e0388e6c840d3950ba004118a754f46d4c2c0c4570c76ca29add86cf97cc0dc40d859094df430627f4cf57316df89df6bf7
6
+ metadata.gz: e28a752bdaaf619bf293c6a4f995a17e7cdea913c6c1c89be07dcb14c575a2b78264bbb6fad03d2b1ec574c2d0c72fd04ce84431e7920e6ac7180b5f4006c54c
7
+ data.tar.gz: aa8f768c03494a14b6dcafc9ada76764b028f750f6ff104627bb669c431321074fbac76ae81ab84df6510988d7cf161a9863c796c6615e343193ae2708979419
@@ -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"
26
26
  option :copy_latest,
27
27
  type: :boolean,
28
28
  default: false,
@@ -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
@@ -13,12 +13,12 @@ module Publisher
13
13
  # Base class for CI executor info
14
14
  #
15
15
  class Provider
16
- EXECUTOR_JSON = "executor.json".freeze
17
16
  DESCRIPTION_PATTERN = /<!-- allure -->[\s\S]+<!-- allurestop -->/.freeze
17
+ ALLURE_JOB_NAME = "ALLURE_JOB_NAME".freeze
18
18
 
19
- def initialize(results_path, report_url)
20
- @results_path = results_path
19
+ def initialize(report_url:, update_pr:)
21
20
  @report_url = report_url
21
+ @update_pr = update_pr
22
22
  end
23
23
 
24
24
  # :nocov:
@@ -29,27 +29,23 @@ module Publisher
29
29
  def self.run_id
30
30
  raise("Not implemented!")
31
31
  end
32
- # :nocov:
33
32
 
34
- # Write executor info file
33
+ # Get executor info
35
34
  #
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
35
+ # @return [Hash]
36
+ def executor_info
37
+ raise("Not implemented!")
41
38
  end
39
+ # :nocov:
42
40
 
43
41
  # Add report url to pull request description
44
42
  #
45
43
  # @return [void]
46
44
  def add_report_url
47
45
  raise("Not a pull request, skipped!") unless pr?
46
+ return add_comment if comment?
48
47
 
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)
48
+ update_pr_description
53
49
  end
54
50
 
55
51
  # :nocov:
@@ -63,14 +59,7 @@ module Publisher
63
59
 
64
60
  private
65
61
 
66
- attr_reader :results_path, :report_url
67
-
68
- # Get executor info
69
- #
70
- # @return [Hash]
71
- def executor_info
72
- raise("Not implemented!")
73
- end
62
+ attr_reader :report_url, :update_pr
74
63
 
75
64
  # Current pull request description
76
65
  #
@@ -81,13 +70,33 @@ module Publisher
81
70
 
82
71
  # Update pull request description
83
72
  #
84
- # @param [String] _desc
85
73
  # @return [void]
86
- def update_pr_description(_desc)
74
+ def update_pr_description
75
+ raise("Not implemented!")
76
+ end
77
+
78
+ # Add comment with report url
79
+ #
80
+ # @return [void]
81
+ def add_comment
82
+ raise("Not implemented!")
83
+ end
84
+
85
+ # Commit SHA url
86
+ #
87
+ # @return [String]
88
+ def sha_url
87
89
  raise("Not implemented!")
88
90
  end
89
91
  # :nocov:
90
92
 
93
+ # Add report url as comment
94
+ #
95
+ # @return [Boolean]
96
+ def comment?
97
+ update_pr == "comment"
98
+ end
99
+
91
100
  # CI run id
92
101
  #
93
102
  # @return [String]
@@ -95,17 +104,71 @@ module Publisher
95
104
  self.class.run_id
96
105
  end
97
106
 
107
+ # Check if PR already has report urls
108
+ #
109
+ # @return [Boolean]
110
+ def reported?
111
+ @reported ||= pr_description.match?(DESCRIPTION_PATTERN)
112
+ end
113
+
114
+ # Full PR description
115
+ #
116
+ # @return [String]
117
+ def updated_pr_description
118
+ reported? ? existing_pr_description : initial_pr_descripion
119
+ end
120
+
121
+ # Updated PR description
122
+ #
123
+ # @return [String]
124
+ def existing_pr_description
125
+ pr_description.gsub(DESCRIPTION_PATTERN, pr_body).strip
126
+ end
127
+
128
+ # Initial PR description
129
+ #
130
+ # @return [String]
131
+ def initial_pr_descripion
132
+ "#{pr_description}\n\n#{pr_body}".strip
133
+ end
134
+
135
+ # Heading for report urls
136
+ #
137
+ # @return [String]
138
+ def heading
139
+ @heading ||= <<~HEADING.strip
140
+ # Allure report
141
+ `allure-report-publisher` generated allure report for #{sha_url}!
142
+ HEADING
143
+ end
144
+
98
145
  # Allure report url pr description
99
146
  #
100
147
  # @return [String]
101
- def description_template
102
- <<~DESC
148
+ def pr_body
149
+ @pr_body ||= <<~DESC
103
150
  <!-- allure -->
104
151
  ---
105
- 📝 [Latest allure report](#{report_url})
152
+ #{heading}
153
+
154
+ #{job_entry}
106
155
  <!-- allurestop -->
107
156
  DESC
108
157
  end
158
+
159
+ # Allure report url comment body
160
+ #
161
+ # @return [String]
162
+ def comment_body
163
+ @comment_body ||= pr_body.gsub("---\n", "")
164
+ end
165
+
166
+ # Single job report URL entry
167
+ #
168
+ # @return [String]
169
+ def job_entry
170
+ @job_entry ||= "**#{build_name}**: 📝 [allure report](#{report_url})"
171
+ end
109
172
  end
110
173
  end
111
174
  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]
@@ -19,8 +25,6 @@ module Publisher
19
25
  ENV["GITHUB_EVENT_NAME"] == "pull_request"
20
26
  end
21
27
 
22
- private
23
-
24
28
  # Executor info
25
29
  #
26
30
  # @return [Hash]
@@ -37,6 +41,8 @@ module Publisher
37
41
  }
38
42
  end
39
43
 
44
+ private
45
+
40
46
  # Github api client
41
47
  #
42
48
  # @return [Octokit::Client]
@@ -48,26 +54,50 @@ module Publisher
48
54
  end
49
55
  end
50
56
 
51
- # Pull request description
57
+ # Update pull request description
52
58
  #
53
- # @return [String]
54
- def pr_description
55
- @pr_description ||= client.pull_request(repository, pr_id)[:body]
59
+ # @return [void]
60
+ def update_pr_description
61
+ client.update_pull_request(repository, pr_id, body: updated_pr_description)
56
62
  end
57
63
 
58
- # Update pull request description
64
+ # Add comment with report url
59
65
  #
60
- # @param [String] _desc
61
66
  # @return [void]
62
- def update_pr_description(desc)
63
- client.update_pull_request(repository, pr_id, body: desc)
67
+ def add_comment
68
+ return client.add_comment(repository, pr_id, comment_body) unless comment
69
+
70
+ client.update_comment(repository, comment[:id], 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
+ comment[:body].match?(DESCRIPTION_PATTERN)
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)
87
+ end
88
+
89
+ # Pull request description
90
+ #
91
+ # @return [String]
92
+ def pr_description
93
+ @pr_description ||= client.pull_request(repository, pr_id)[:body]
64
94
  end
65
95
 
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
@@ -35,6 +35,8 @@ module Publisher
35
35
  }
36
36
  end
37
37
 
38
+ private
39
+
38
40
  # Current pull request description
39
41
  #
40
42
  # @return [String]
@@ -44,10 +46,27 @@ module Publisher
44
46
 
45
47
  # Update pull request description
46
48
  #
47
- # @param [String] desc
48
49
  # @return [void]
49
- def update_pr_description(desc)
50
- client.update_merge_request(project, mr_iid, description: desc)
50
+ def update_pr_description
51
+ client.update_merge_request(project, mr_iid, description: updated_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, comment_body) unless comment
59
+
60
+ client.edit_merge_request_note(project, mr_iid, comment.id, 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
+ comment.body.match?(DESCRIPTION_PATTERN)
69
+ end
51
70
  end
52
71
 
53
72
  # Get gitlab client
@@ -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
@@ -10,10 +10,10 @@ 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
@@ -26,7 +26,7 @@ module Publisher
26
26
 
27
27
  private
28
28
 
29
- attr_reader :results_glob, :results_dir, :report_dir
29
+ attr_reader :results_glob, :results_path, :report_path
30
30
 
31
31
  # Copy all results files to results directory
32
32
  #
@@ -35,7 +35,7 @@ module Publisher
35
35
  results = Dir.glob(results_glob)
36
36
  raise(NoAllureResultsError, "Missing allure results") if results.empty?
37
37
 
38
- FileUtils.cp(results, results_dir)
38
+ FileUtils.cp(results, results_path)
39
39
  end
40
40
 
41
41
  # Generate allure report
@@ -43,7 +43,7 @@ module Publisher
43
43
  # @return [void]
44
44
  def generate_report
45
45
  out, _err, status = Open3.capture3(
46
- "allure generate --clean --output #{report_dir} #{results_dir}"
46
+ "allure generate --clean --output #{report_path} #{results_path}"
47
47
  )
48
48
  raise(AllureError, out) unless status.success?
49
49
  end
@@ -7,6 +7,7 @@ module Publisher
7
7
  class Uploader
8
8
  include Helpers
9
9
 
10
+ EXECUTOR_JSON = "executor.json".freeze
10
11
  HISTORY = [
11
12
  "categories-trend.json",
12
13
  "duration-trend.json",
@@ -15,7 +16,7 @@ module Publisher
15
16
  "retry-trend.json"
16
17
  ].freeze
17
18
 
18
- 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)
19
20
  @results_glob = results_glob
20
21
  @bucket_name = bucket
21
22
  @prefix = prefix
@@ -39,7 +40,7 @@ module Publisher
39
40
  add_history
40
41
  add_executor_info
41
42
 
42
- ReportGenerator.new(results_glob, results_dir, report_dir).generate
43
+ ReportGenerator.new(results_glob, results_path, report_path).generate
43
44
  end
44
45
 
45
46
  # Upload report to storage provider
@@ -147,7 +148,9 @@ module Publisher
147
148
  def add_executor_info
148
149
  return unless ci_provider
149
150
 
150
- ci_provider.write_executor_info
151
+ File.open("#{results_path}/#{EXECUTOR_JSON}", "w") do |file|
152
+ file.write(ci_provider.executor_info.to_json)
153
+ end
151
154
  end
152
155
 
153
156
  # Run upload commands
@@ -172,14 +175,14 @@ module Publisher
172
175
  def ci_provider
173
176
  return @ci_provider if defined?(@ci_provider)
174
177
 
175
- @ci_provider = Providers.provider&.new(results_dir, report_url)
178
+ @ci_provider = Providers.provider&.new(report_url: report_url, update_pr: update_pr)
176
179
  end
177
180
 
178
181
  # Fetch allure report history
179
182
  #
180
183
  # @return [void]
181
184
  def create_history_dir
182
- FileUtils.mkdir_p(path(results_dir, "history"))
185
+ FileUtils.mkdir_p(path(results_path, "history"))
183
186
  end
184
187
 
185
188
  # Report path prefix
@@ -196,15 +199,15 @@ module Publisher
196
199
  # Aggregated results directory
197
200
  #
198
201
  # @return [String]
199
- def results_dir
200
- @results_dir ||= Dir.mktmpdir("allure-results")
202
+ def results_path
203
+ @results_path ||= Dir.mktmpdir("allure-results")
201
204
  end
202
205
 
203
206
  # Allure report directory
204
207
  #
205
208
  # @return [String]
206
- def report_dir
207
- @report_dir ||= Dir.mktmpdir("allure-report")
209
+ def report_path
210
+ @report_path ||= Dir.mktmpdir("allure-report")
208
211
  end
209
212
 
210
213
  # Report files
@@ -212,7 +215,7 @@ module Publisher
212
215
  # @return [Array<Pathname>]
213
216
  def report_files
214
217
  @report_files ||= Pathname
215
- .glob("#{report_dir}/**/*")
218
+ .glob("#{report_path}/**/*")
216
219
  .reject(&:directory?)
217
220
  end
218
221
  end
@@ -43,7 +43,7 @@ module Publisher
43
43
  file = bucket.file(key(prefix, "history", file_name))
44
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,7 +40,7 @@ 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
  )
@@ -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.6"
4
+ VERSION = "0.1.0"
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.6
4
+ version: 0.1.0
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-09 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