allure-report-publisher 0.0.1 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +42 -11
- data/lib/allure_report_publisher.rb +4 -5
- data/lib/allure_report_publisher/commands/upload.rb +90 -0
- data/lib/allure_report_publisher/{helpers.rb → lib/helpers/helpers.rb} +25 -25
- data/lib/allure_report_publisher/lib/helpers/spinner.rb +109 -0
- data/lib/allure_report_publisher/lib/providers/_provider.rb +111 -0
- data/lib/allure_report_publisher/lib/providers/github.rb +102 -0
- data/lib/allure_report_publisher/lib/providers/gitlab.rb +103 -0
- data/lib/allure_report_publisher/lib/report_generator.rb +4 -7
- data/lib/allure_report_publisher/lib/uploaders/_uploader.rb +146 -24
- data/lib/allure_report_publisher/lib/uploaders/gcs.rb +104 -0
- data/lib/allure_report_publisher/lib/uploaders/s3.rb +107 -0
- data/lib/allure_report_publisher/version.rb +1 -1
- metadata +60 -7
- data/lib/allure_report_publisher/commands/upload_s3.rb +0 -41
- data/lib/allure_report_publisher/lib/uploaders/s3_uploader.rb +0 -96
@@ -0,0 +1,102 @@
|
|
1
|
+
require "octokit"
|
2
|
+
|
3
|
+
module Publisher
|
4
|
+
module Providers
|
5
|
+
# Github implementation
|
6
|
+
#
|
7
|
+
class Github < Provider
|
8
|
+
# Run id
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
def self.run_id
|
12
|
+
@run_id ||= ENV["GITHUB_RUN_ID"]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Pull request run
|
16
|
+
#
|
17
|
+
# @return [Boolean]
|
18
|
+
def pr?
|
19
|
+
ENV["GITHUB_EVENT_NAME"] == "pull_request"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Executor info
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
27
|
+
def executor_info
|
28
|
+
{
|
29
|
+
name: "Github",
|
30
|
+
type: "github",
|
31
|
+
reportName: "AllureReport",
|
32
|
+
url: server_url,
|
33
|
+
reportUrl: report_url,
|
34
|
+
buildUrl: build_url,
|
35
|
+
buildOrder: run_id,
|
36
|
+
buildName: build_name
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Github api client
|
41
|
+
#
|
42
|
+
# @return [Octokit::Client]
|
43
|
+
def client
|
44
|
+
@client ||= begin
|
45
|
+
raise("Missing GITHUB_AUTH_TOKEN environment variable!") unless ENV["GITHUB_AUTH_TOKEN"]
|
46
|
+
|
47
|
+
Octokit::Client.new(access_token: ENV["GITHUB_AUTH_TOKEN"], api_endpoint: ENV["GITHUB_API_URL"])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Pull request description
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
def pr_description
|
55
|
+
@pr_description ||= client.pull_request(repository, pr_id)[:body]
|
56
|
+
end
|
57
|
+
|
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
|
+
# Pull request id
|
67
|
+
#
|
68
|
+
# @return [Integer]
|
69
|
+
def pr_id
|
70
|
+
@pr_id ||= JSON.parse(File.read(ENV["GITHUB_EVENT_PATH"]))["number"]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Server url
|
74
|
+
#
|
75
|
+
# @return [String]
|
76
|
+
def server_url
|
77
|
+
@server_url ||= ENV["GITHUB_SERVER_URL"]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Build url
|
81
|
+
#
|
82
|
+
# @return [String]
|
83
|
+
def build_url
|
84
|
+
@build_url ||= "#{server_url}/#{repository}/actions/runs/#{run_id}"
|
85
|
+
end
|
86
|
+
|
87
|
+
# Job name
|
88
|
+
#
|
89
|
+
# @return [String]
|
90
|
+
def build_name
|
91
|
+
@build_name ||= ENV["GITHUB_JOB"]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Github repository
|
95
|
+
#
|
96
|
+
# @return [String]
|
97
|
+
def repository
|
98
|
+
@repository ||= ENV["GITHUB_REPOSITORY"]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require "gitlab"
|
2
|
+
|
3
|
+
module Publisher
|
4
|
+
module Providers
|
5
|
+
# Gitlab implementation
|
6
|
+
#
|
7
|
+
class Gitlab < Provider
|
8
|
+
# Get ci run ID without creating instance of ci provider
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
def self.run_id
|
12
|
+
@run_id ||= ENV["CI_PIPELINE_ID"]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Pull request run
|
16
|
+
#
|
17
|
+
# @return [Boolean]
|
18
|
+
def pr?
|
19
|
+
ENV["CI_PIPELINE_SOURCE"] == "merge_request_event"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get executor info
|
23
|
+
#
|
24
|
+
# @return [Hash]
|
25
|
+
def executor_info
|
26
|
+
{
|
27
|
+
name: "Gitlab",
|
28
|
+
type: "gitlab",
|
29
|
+
reportName: "AllureReport",
|
30
|
+
url: server_url,
|
31
|
+
reportUrl: report_url,
|
32
|
+
buildUrl: build_url,
|
33
|
+
buildOrder: run_id,
|
34
|
+
buildName: build_name
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
# Current pull request description
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
def pr_description
|
42
|
+
@pr_description ||= client.merge_request(project, mr_iid).description
|
43
|
+
end
|
44
|
+
|
45
|
+
# Update pull request description
|
46
|
+
#
|
47
|
+
# @param [String] desc
|
48
|
+
# @return [void]
|
49
|
+
def update_pr_description(desc)
|
50
|
+
client.update_merge_request(project, mr_iid, description: desc)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get gitlab client
|
54
|
+
#
|
55
|
+
# @return [Gitlab::Client]
|
56
|
+
def client
|
57
|
+
@client ||= begin
|
58
|
+
raise("Missing GITLAB_AUTH_TOKEN environment variable!") unless ENV["GITLAB_AUTH_TOKEN"]
|
59
|
+
|
60
|
+
::Gitlab::Client.new(
|
61
|
+
endpoint: "#{server_url}/api/v4",
|
62
|
+
private_token: ENV["GITLAB_AUTH_TOKEN"]
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Merge request iid
|
68
|
+
#
|
69
|
+
# @return [Integer]
|
70
|
+
def mr_iid
|
71
|
+
@mr_iid ||= ENV["CI_MERGE_REQUEST_IID"]
|
72
|
+
end
|
73
|
+
|
74
|
+
# Server url
|
75
|
+
#
|
76
|
+
# @return [String]
|
77
|
+
def server_url
|
78
|
+
@server_url ||= ENV["CI_SERVER_URL"]
|
79
|
+
end
|
80
|
+
|
81
|
+
# Build url
|
82
|
+
#
|
83
|
+
# @return [String]
|
84
|
+
def build_url
|
85
|
+
@build_url ||= ENV["CI_PIPELINE_URL"]
|
86
|
+
end
|
87
|
+
|
88
|
+
# Job name
|
89
|
+
#
|
90
|
+
# @return [String]
|
91
|
+
def build_name
|
92
|
+
@build_name ||= ENV["CI_JOB_NAME"]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Github repository
|
96
|
+
#
|
97
|
+
# @return [String]
|
98
|
+
def project
|
99
|
+
@project ||= ENV["CI_PROJECT_PATH"]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -20,11 +20,8 @@ module Publisher
|
|
20
20
|
#
|
21
21
|
# @return [void]
|
22
22
|
def generate
|
23
|
-
|
24
|
-
|
25
|
-
aggregate_results
|
26
|
-
generate_report
|
27
|
-
end
|
23
|
+
aggregate_results
|
24
|
+
generate_report
|
28
25
|
end
|
29
26
|
|
30
27
|
private
|
@@ -36,7 +33,7 @@ module Publisher
|
|
36
33
|
# @return [void]
|
37
34
|
def aggregate_results
|
38
35
|
results = Dir.glob(results_glob)
|
39
|
-
|
36
|
+
raise(NoAllureResultsError, "Missing allure results") if results.empty?
|
40
37
|
|
41
38
|
FileUtils.cp(results, results_dir)
|
42
39
|
end
|
@@ -48,7 +45,7 @@ module Publisher
|
|
48
45
|
out, _err, status = Open3.capture3(
|
49
46
|
"allure generate --clean --output #{report_dir} #{results_dir}"
|
50
47
|
)
|
51
|
-
|
48
|
+
raise(AllureError, out) unless status.success?
|
52
49
|
end
|
53
50
|
end
|
54
51
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Publisher
|
2
2
|
module Uploaders
|
3
|
+
class HistoryNotFoundError < StandardError; end
|
4
|
+
|
3
5
|
# Uploader implementation
|
4
6
|
#
|
5
7
|
class Uploader
|
@@ -13,28 +15,164 @@ module Publisher
|
|
13
15
|
"retry-trend.json"
|
14
16
|
].freeze
|
15
17
|
|
16
|
-
def initialize(results_glob
|
18
|
+
def initialize(results_glob:, bucket:, update_pr: false, prefix: nil, copy_latest: false)
|
17
19
|
@results_glob = results_glob
|
18
|
-
@
|
19
|
-
@
|
20
|
+
@bucket_name = bucket
|
21
|
+
@prefix = prefix
|
22
|
+
@update_pr = update_pr
|
23
|
+
@copy_latest = !!(Providers.provider && copy_latest) # copy latest for ci only
|
20
24
|
end
|
21
25
|
|
22
26
|
# Execute allure report generation and upload
|
23
27
|
#
|
24
28
|
# @return [void]
|
25
29
|
def execute
|
26
|
-
|
30
|
+
generate_report
|
31
|
+
upload
|
32
|
+
add_url_to_pr
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generate allure report
|
36
|
+
#
|
37
|
+
# @return [void]
|
38
|
+
def generate_report
|
39
|
+
add_history
|
40
|
+
add_executor_info
|
41
|
+
|
42
|
+
ReportGenerator.new(results_glob, results_dir, report_dir).generate
|
43
|
+
end
|
44
|
+
|
45
|
+
# Upload report to storage provider
|
46
|
+
#
|
47
|
+
# @return [void]
|
48
|
+
def upload
|
49
|
+
run_uploads
|
50
|
+
end
|
51
|
+
|
52
|
+
# Add allure report url to pull request description
|
53
|
+
#
|
54
|
+
# @return [void]
|
55
|
+
def add_url_to_pr
|
56
|
+
return unless update_pr && ci_provider
|
57
|
+
|
58
|
+
ci_provider.add_report_url
|
59
|
+
end
|
60
|
+
|
61
|
+
# Uploaded report urls
|
62
|
+
#
|
63
|
+
# @return [Hash<String, String>] uploaded report urls
|
64
|
+
def report_urls
|
65
|
+
urls = { "Report url" => report_url }
|
66
|
+
urls["Latest report url"] = latest_report_url if copy_latest
|
67
|
+
|
68
|
+
urls
|
69
|
+
end
|
70
|
+
|
71
|
+
# Executed in PR pipeline
|
72
|
+
#
|
73
|
+
# @return [Boolean]
|
74
|
+
def pr?
|
75
|
+
ci_provider&.pr?
|
27
76
|
end
|
28
77
|
|
29
78
|
private
|
30
79
|
|
31
|
-
attr_reader :results_glob, :
|
80
|
+
attr_reader :results_glob, :bucket_name, :prefix, :update_pr, :copy_latest
|
81
|
+
|
82
|
+
# :nocov:
|
83
|
+
|
84
|
+
# Cloud provider client
|
85
|
+
#
|
86
|
+
# @return [Object]
|
87
|
+
def client
|
88
|
+
raise("Not Implemented!")
|
89
|
+
end
|
32
90
|
|
33
91
|
# Report url
|
34
92
|
#
|
35
93
|
# @return [String]
|
36
94
|
def report_url
|
37
|
-
raise(
|
95
|
+
raise("Not Implemented!")
|
96
|
+
end
|
97
|
+
|
98
|
+
# Latest report url
|
99
|
+
#
|
100
|
+
# @return [String]
|
101
|
+
def latest_report_url
|
102
|
+
raise("Not Implemented!")
|
103
|
+
end
|
104
|
+
|
105
|
+
# Download allure history
|
106
|
+
#
|
107
|
+
# @return [void]
|
108
|
+
def download_history
|
109
|
+
raise("Not implemented!")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Upload history to s3
|
113
|
+
#
|
114
|
+
# @return [void]
|
115
|
+
def upload_history
|
116
|
+
raise("Not implemented!")
|
117
|
+
end
|
118
|
+
|
119
|
+
# Upload report to s3
|
120
|
+
#
|
121
|
+
# @return [void]
|
122
|
+
def upload_report
|
123
|
+
raise("Not implemented!")
|
124
|
+
end
|
125
|
+
|
126
|
+
# Upload copy of latest run
|
127
|
+
#
|
128
|
+
# @return [void]
|
129
|
+
def upload_latest_copy
|
130
|
+
raise("Not implemented!")
|
131
|
+
end
|
132
|
+
# :nocov:
|
133
|
+
|
134
|
+
# Add allure history
|
135
|
+
#
|
136
|
+
# @return [void]
|
137
|
+
def add_history
|
138
|
+
create_history_dir
|
139
|
+
download_history
|
140
|
+
rescue HistoryNotFoundError
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
|
144
|
+
# Add CI executor info
|
145
|
+
#
|
146
|
+
# @return [void]
|
147
|
+
def add_executor_info
|
148
|
+
return unless ci_provider
|
149
|
+
|
150
|
+
ci_provider.write_executor_info
|
151
|
+
end
|
152
|
+
|
153
|
+
# Run upload commands
|
154
|
+
#
|
155
|
+
# @return [void]
|
156
|
+
def run_uploads
|
157
|
+
upload_history unless !run_id || copy_latest
|
158
|
+
upload_report
|
159
|
+
upload_latest_copy if copy_latest
|
160
|
+
end
|
161
|
+
|
162
|
+
# Get run id
|
163
|
+
#
|
164
|
+
# @return [String]
|
165
|
+
def run_id
|
166
|
+
@run_id ||= Providers.provider&.run_id
|
167
|
+
end
|
168
|
+
|
169
|
+
# Get CI provider
|
170
|
+
#
|
171
|
+
# @return [Publisher::Providers::Base]
|
172
|
+
def ci_provider
|
173
|
+
return @ci_provider if defined?(@ci_provider)
|
174
|
+
|
175
|
+
@ci_provider = Providers.provider&.new(results_dir, report_url)
|
38
176
|
end
|
39
177
|
|
40
178
|
# Fetch allure report history
|
@@ -47,21 +185,14 @@ module Publisher
|
|
47
185
|
# Report path prefix
|
48
186
|
#
|
49
187
|
# @return [String]
|
50
|
-
def
|
51
|
-
@
|
188
|
+
def full_prefix
|
189
|
+
@full_prefix ||= [prefix, run_id].compact.yield_self do |pre|
|
52
190
|
break if pre.empty?
|
53
191
|
|
54
192
|
pre.join("/")
|
55
193
|
end
|
56
194
|
end
|
57
195
|
|
58
|
-
# Run ID
|
59
|
-
#
|
60
|
-
# @return [String]
|
61
|
-
def run_id
|
62
|
-
@run_id ||= ENV["RUN_ID"]
|
63
|
-
end
|
64
|
-
|
65
196
|
# Aggregated results directory
|
66
197
|
#
|
67
198
|
# @return [String]
|
@@ -84,15 +215,6 @@ module Publisher
|
|
84
215
|
.glob("#{report_dir}/**/*")
|
85
216
|
.reject(&:directory?)
|
86
217
|
end
|
87
|
-
|
88
|
-
# Generate allure report
|
89
|
-
#
|
90
|
-
# @return [void]
|
91
|
-
def generate_report
|
92
|
-
fetch_history if run_id
|
93
|
-
|
94
|
-
ReportGenerator.new(results_glob, results_dir, report_dir).generate
|
95
|
-
end
|
96
218
|
end
|
97
219
|
end
|
98
220
|
end
|