realityforge-buildr 1.5.15 → 1.5.16
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 +4 -4
- data/addon/buildr/api_diff_tool.rb +77 -0
- data/addon/buildr/release_tool.rb +279 -0
- data/lib/buildr/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bb76fb200fe200d5778bc6b4122991ccbea6825da382f688dd07afa06b4305d
|
4
|
+
data.tar.gz: ba1bf6ce47d21b286c346bd9561d0191e93997041ba99fc36240ade14f58e421
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60f9fa50cec1fe1c4a6a806cf8687443963e36891000c0addeb2694204c6950933cde7fe28eb1d9df019207a3e9c380c8df8964858c8bafe6d36300808040289
|
7
|
+
data.tar.gz: 5890f8221a6f8cb2a8e1462cb1d1b88f0f95df67f37a75eb85c37eb173b450a99b02d2d811b9d84035b7cecabc59bd9e1e5e73486cf3e72069922db739a1243e
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Buildr
|
2
|
+
class ApiDiffTool
|
3
|
+
class << self
|
4
|
+
def generate_differences_report(artifact_coordinate, old_version, new_version, new_file, output_file, options = {})
|
5
|
+
revapi = Buildr.artifact('org.realityforge.revapi.diff:revapi-diff:jar:all:0.08')
|
6
|
+
revapi.invoke
|
7
|
+
|
8
|
+
old_artifact = Buildr.artifact("#{artifact_coordinate}:#{old_version}")
|
9
|
+
old_artifact.invoke
|
10
|
+
|
11
|
+
unless new_file
|
12
|
+
new_artifact = Buildr.artifact("#{artifact_coordinate}:#{new_version}")
|
13
|
+
new_artifact.invoke
|
14
|
+
new_file = new_artifact.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
FileUtils.mkdir_p File.dirname(output_file)
|
18
|
+
|
19
|
+
args = []
|
20
|
+
args << Java::Commands.path_to_bin('java')
|
21
|
+
args << '-jar'
|
22
|
+
args << revapi.to_s
|
23
|
+
args << '--old-api'
|
24
|
+
args << "#{artifact_coordinate}:#{old_version}::#{old_artifact.to_s}"
|
25
|
+
if options[:support_libs]
|
26
|
+
options[:support_libs].each do |lib|
|
27
|
+
args << '--old-api-support'
|
28
|
+
args << lib.to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
args << '--new-api'
|
32
|
+
args << "#{artifact_coordinate}:#{new_version}::#{new_file}"
|
33
|
+
if options[:support_libs]
|
34
|
+
options[:support_libs].each do |lib|
|
35
|
+
args << '--new-api-support'
|
36
|
+
args << lib.to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
args << '--output-file'
|
40
|
+
args << output_file.to_s
|
41
|
+
|
42
|
+
sh args.join(' ')
|
43
|
+
if File.exist?(output_file)
|
44
|
+
data = JSON.parse(IO.read(output_file, :encoding => 'UTF-8'))
|
45
|
+
FileUtils.rm_f output_file if data.empty?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_differences_report(artifact_coordinate, old_version, new_version, new_file, output_directory, options = {})
|
50
|
+
output_file = "#{output_directory}/#{old_version}-#{new_version}.json"
|
51
|
+
generate_differences_report(artifact_coordinate, old_version, new_version, new_file, output_file, options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_differences_report(artifact_coordinate, old_version, new_version, new_file, output_directory, options = {})
|
55
|
+
report_file = "#{output_directory}/#{old_version}-#{new_version}.json"
|
56
|
+
tmp = nil
|
57
|
+
begin
|
58
|
+
tmp = Tempfile.open("#{old_version}-#{new_version}.json")
|
59
|
+
tmp.close
|
60
|
+
generate_differences_report(artifact_coordinate, old_version, new_version, new_file, tmp.path, options)
|
61
|
+
|
62
|
+
report_content = File.exist?(report_file) ? IO.read(report_file, :encoding => 'UTF-8') : ''
|
63
|
+
test_content = File.exist?(tmp.path) ? IO.read(tmp.path, :encoding => 'UTF-8') : ''
|
64
|
+
if report_content != test_content
|
65
|
+
if File.exist?(report_file)
|
66
|
+
raise "Differences report at #{report_file} does not record the correct set differences between #{old_version} and #{new_version} for #{artifact_coordinate}"
|
67
|
+
else
|
68
|
+
raise "No differences report at #{report_file} but differences exist between #{old_version} and #{new_version} for #{artifact_coordinate}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
ensure
|
72
|
+
tmp.close unless tmp.nil?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module Buildr
|
16
|
+
class ReleaseTool
|
17
|
+
class << self
|
18
|
+
def define_release_task(options = {})
|
19
|
+
task_name = options[:task_name] || 'perform_release'
|
20
|
+
description = options[:description] || 'Perform a release'
|
21
|
+
workspace_dir = options[:workspace_dir] || File.dirname(Buildr.application.buildfile.to_s)
|
22
|
+
|
23
|
+
ENV['PREVIOUS_PRODUCT_VERSION'] = nil if ENV['PREVIOUS_PRODUCT_VERSION'].to_s == ''
|
24
|
+
ENV['PRODUCT_VERSION'] = nil if ENV['PRODUCT_VERSION'].to_s == ''
|
25
|
+
|
26
|
+
desc description
|
27
|
+
task task_name do
|
28
|
+
in_dir(workspace_dir) do
|
29
|
+
yield ReleaseTool.new
|
30
|
+
end
|
31
|
+
if ENV['STAGE']
|
32
|
+
if ENV['LAST_STAGE'] == ENV['STAGE']
|
33
|
+
puts "LAST_STAGE specified '#{ENV['LAST_STAGE']}', later stages were skipped"
|
34
|
+
else
|
35
|
+
raise "Invalid STAGE specified '#{ENV['STAGE']}' that did not match any stage"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def derive_versions_from_changelog(options = {})
|
42
|
+
ENV['PREVIOUS_PRODUCT_VERSION'] ||= IO.read('CHANGELOG.md')[/^### \[v(\d+\.\d+(\.\d+)?)\]/, 1] || '0.00'
|
43
|
+
ENV['PRODUCT_VERSION'] ||= derive_next_version(ENV['PREVIOUS_PRODUCT_VERSION'], options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def derive_next_version(current_version, options = {})
|
47
|
+
return options[:next_version_action].call(current_version) if options[:next_version_action]
|
48
|
+
version_parts = current_version.split('.')
|
49
|
+
"#{version_parts[0]}.#{sprintf('%02d', version_parts[1].to_i + 1)}#{version_parts.length > 2 ? ".#{version_parts[2]}" : ''}"
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def in_dir(dir)
|
55
|
+
current = Dir.pwd
|
56
|
+
begin
|
57
|
+
Dir.chdir(dir)
|
58
|
+
yield
|
59
|
+
ensure
|
60
|
+
Dir.chdir(current)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def extract_version_from_changelog(options = {})
|
66
|
+
stage('ExtractVersion', 'Extract the last version from CHANGELOG.md and derive next version unless specified', :always_run => true) do
|
67
|
+
Buildr::ReleaseTool.derive_versions_from_changelog(options)
|
68
|
+
# Also initialize release date if required
|
69
|
+
ENV['RELEASE_DATE'] ||= Time.now.strftime('%Y-%m-%d')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def zapwhite
|
74
|
+
stage('ZapWhite', 'Ensure that zapwhite produces no changes') do
|
75
|
+
sh 'bundle exec zapwhite'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def ensure_git_clean
|
80
|
+
stage('GitClean', 'Ensure there is nothing to commit and the working tree is clean') do
|
81
|
+
status_output = `git status -s 2>&1`.strip
|
82
|
+
raise 'Uncommitted changes in git repository. Please commit them prior to release.' if 0 != status_output.size
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def verify_no_todo
|
87
|
+
stage('TodoScan', 'Verify that there are no TODO notes in codebase') do
|
88
|
+
task('todos:scan').invoke
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def cleanup_staging
|
93
|
+
stage('StagingCleanup', 'Remove artifacts from staging repository') do
|
94
|
+
task('staging:cleanup').invoke
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def build(options = {})
|
99
|
+
additional_tasks = options[:additional_tasks] || ''
|
100
|
+
stage('Build', 'Build the project to ensure that the tests pass') do
|
101
|
+
sh "bundle exec buildr clean package #{additional_tasks} install PRODUCT_VERSION=#{ENV['PRODUCT_VERSION']}#{ENV['TEST'].nil? ? '' : " TEST=#{ENV['TEST']}"}#{Buildr.application.options.trace ? ' --trace' : ''}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def patch_changelog(repository_name, options = {})
|
106
|
+
stage('PatchChangelog', 'Patch the changelog to update from previous release') do
|
107
|
+
changelog = IO.read('CHANGELOG.md')
|
108
|
+
from = '0.00' == ENV['PREVIOUS_PRODUCT_VERSION'] ? `git rev-list --max-parents=0 HEAD`.strip : "v#{ENV['PREVIOUS_PRODUCT_VERSION']}"
|
109
|
+
|
110
|
+
header = "### [v#{ENV['PRODUCT_VERSION']}](https://github.com/#{repository_name}/tree/v#{ENV['PRODUCT_VERSION']}) (#{ENV['RELEASE_DATE']}) · [Full Changelog](https://github.com/spritz/spritz/compare/#{from}...v#{ENV['PRODUCT_VERSION']})"
|
111
|
+
|
112
|
+
sub_header_text = ''
|
113
|
+
|
114
|
+
api_diff_directory = options[:api_diff_directory]
|
115
|
+
api_diff_filename = api_diff_directory ? "#{api_diff_directory}/#{ENV['PREVIOUS_PRODUCT_VERSION']}-#{ENV['PRODUCT_VERSION']}.json" : nil
|
116
|
+
if api_diff_filename && File.exist?(api_diff_filename)
|
117
|
+
|
118
|
+
api_diff_site = options[:api_diff_website]
|
119
|
+
if api_diff_site
|
120
|
+
header += " · [API Differences](#{api_diff_site}old=#{ENV['PREVIOUS_PRODUCT_VERSION']}&new=#{ENV['PRODUCT_VERSION']})"
|
121
|
+
end
|
122
|
+
|
123
|
+
changes = JSON.parse(IO.read(api_diff_filename))
|
124
|
+
non_breaking_changes = changes.select { |j| j['classification']['SOURCE'] == 'NON_BREAKING' }.size
|
125
|
+
potentially_breaking_changes = changes.select { |j| j['classification']['SOURCE'] == 'POTENTIALLY_BREAKING' }.size
|
126
|
+
breaking_changes = changes.select { |j| j['classification']['SOURCE'] == 'BREAKING' }.size
|
127
|
+
change_descriptions = []
|
128
|
+
change_descriptions << "#{non_breaking_changes} non breaking API change#{1 == non_breaking_changes ? '' : 's'}" unless 0 == non_breaking_changes
|
129
|
+
change_descriptions << "#{potentially_breaking_changes} potentially breaking API change#{1 == potentially_breaking_changes ? '' : 's'}" unless 0 == potentially_breaking_changes
|
130
|
+
change_descriptions << "#{breaking_changes} breaking API change#{1 == breaking_changes ? '' : 's'}" unless 0 == breaking_changes
|
131
|
+
|
132
|
+
if change_descriptions.size > 0
|
133
|
+
description = "The release includes "
|
134
|
+
if 1 == change_descriptions.size
|
135
|
+
description += "#{change_descriptions[0]}"
|
136
|
+
elsif 2 == change_descriptions.size
|
137
|
+
description += "#{change_descriptions[0]} and #{change_descriptions[1]}"
|
138
|
+
else
|
139
|
+
description += "#{change_descriptions[0]}, #{change_descriptions[1]} and #{change_descriptions[2]}"
|
140
|
+
end
|
141
|
+
|
142
|
+
sub_header_text = description
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
header_suffix = options[:header_suffix]
|
147
|
+
header += header_suffix if header_suffix
|
148
|
+
header += "\n\n#{sub_header_text}" unless sub_header_text.empty?
|
149
|
+
header += "\n"
|
150
|
+
|
151
|
+
header += <<CONTENT
|
152
|
+
|
153
|
+
Changes in this release:
|
154
|
+
CONTENT
|
155
|
+
|
156
|
+
IO.write('CHANGELOG.md', changelog.gsub("### Unreleased\n", header))
|
157
|
+
|
158
|
+
sh 'git reset 2>&1 1> /dev/null'
|
159
|
+
sh 'git add CHANGELOG.md'
|
160
|
+
sh 'git commit -m "Update CHANGELOG.md in preparation for release"'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def patch_maven_version_in_readme
|
165
|
+
stage('PatchReadme', 'Patch the README to update from previous release') do
|
166
|
+
contents = IO.read('README.md')
|
167
|
+
contents = contents.
|
168
|
+
gsub("<version>#{ENV['PREVIOUS_PRODUCT_VERSION']}</version>", "<version>#{ENV['PRODUCT_VERSION']}</version>").
|
169
|
+
gsub("/#{ENV['PREVIOUS_PRODUCT_VERSION']}/", "/#{ENV['PRODUCT_VERSION']}/").
|
170
|
+
gsub("-#{ENV['PREVIOUS_PRODUCT_VERSION']}-", "-#{ENV['PRODUCT_VERSION']}-")
|
171
|
+
IO.write('README.md', contents)
|
172
|
+
|
173
|
+
sh 'git reset 2>&1 1> /dev/null'
|
174
|
+
sh 'git add README.md'
|
175
|
+
sh 'git commit -m "Update README.md in preparation for release"'
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def tag_project
|
180
|
+
stage('TagProject', 'Tag the project') do
|
181
|
+
sh "git tag v#{ENV['PRODUCT_VERSION']}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def stage_release(options = {})
|
186
|
+
release_to = options[:release_to] || (raise "StageRelease stage must specify :release_to configuration")
|
187
|
+
stage('StageRelease', 'Stage the release') do
|
188
|
+
IO.write('_buildr.rb', "repositories.release_to = #{release_to.inspect}")
|
189
|
+
sh 'bundle exec buildr clean upload TEST=no GWT=no'
|
190
|
+
sh 'rm -f _buildr.rb'
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def maven_central_publish(options = {})
|
195
|
+
additional_tasks = options[:additional_tasks] || ''
|
196
|
+
stage('MavenCentralPublish', 'Publish artifacts to Maven Central') do
|
197
|
+
sh "bundle exec buildr clean mcrt:publish_if_tagged #{additional_tasks} TEST=no GWT=no"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def patch_changelog_post_release
|
202
|
+
stage('PatchChangelogPostRelease', 'Patch the changelog post release to prepare for next development iteration') do
|
203
|
+
changelog = IO.read('CHANGELOG.md')
|
204
|
+
changelog = changelog.gsub("# Change Log\n", <<HEADER)
|
205
|
+
# Change Log
|
206
|
+
|
207
|
+
### Unreleased
|
208
|
+
HEADER
|
209
|
+
IO.write('CHANGELOG.md', changelog)
|
210
|
+
|
211
|
+
`bundle exec zapwhite`
|
212
|
+
sh 'git add CHANGELOG.md'
|
213
|
+
sh 'git commit -m "Update CHANGELOG.md in preparation for next development iteration"'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def push_changes
|
218
|
+
stage('PushChanges', 'Push changes to git repository') do
|
219
|
+
sh 'git push'
|
220
|
+
sh 'git push --tags'
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def github_release(repository_name)
|
225
|
+
stage('GithubRelease', 'Create a Release on GitHub') do
|
226
|
+
changelog = IO.read('CHANGELOG.md')
|
227
|
+
start = changelog.index("### [v#{ENV['PRODUCT_VERSION']}]")
|
228
|
+
raise "Unable to locate version #{ENV['PRODUCT_VERSION']} in change log" if -1 == start
|
229
|
+
start = changelog.index("\n", start)
|
230
|
+
start = changelog.index("\n", start + 1)
|
231
|
+
|
232
|
+
end_index = changelog.index('### [v', start)
|
233
|
+
end_index = changelog.length if end_index.nil?
|
234
|
+
|
235
|
+
changes = changelog[start, end_index - start]
|
236
|
+
|
237
|
+
changes = changes.strip
|
238
|
+
|
239
|
+
tag = "v#{ENV['PRODUCT_VERSION']}"
|
240
|
+
|
241
|
+
version_parts = ENV['PRODUCT_VERSION'].split('.')
|
242
|
+
prerelease = '0' == version_parts[0]
|
243
|
+
|
244
|
+
require 'octokit'
|
245
|
+
|
246
|
+
client = Octokit::Client.new(:netrc => true, :auto_paginate => true)
|
247
|
+
client.login
|
248
|
+
client.create_release(repository_name, tag, :name => tag, :body => changes, :draft => false, :prerelease => prerelease)
|
249
|
+
|
250
|
+
candidates = client.list_milestones(repository_name).select { |m| m[:title].to_s == tag }
|
251
|
+
unless candidates.empty?
|
252
|
+
milestone = candidates[0]
|
253
|
+
unless milestone[:state] == 'closed'
|
254
|
+
client.update_milestone(repository_name, milestone[:number], :state => 'closed')
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def stage(stage_name, description, options = {})
|
261
|
+
if ENV['STAGE'].nil? || ENV['STAGE'] == stage_name || options[:always_run]
|
262
|
+
puts "🚀 Release Stage: #{stage_name} - #{description}"
|
263
|
+
begin
|
264
|
+
yield
|
265
|
+
rescue Exception => e
|
266
|
+
puts '💣 Error completing stage.'
|
267
|
+
puts "Fix the error and re-run release process passing: STAGE=#{stage_name}#{ ENV['PREVIOUS_PRODUCT_VERSION'] ? " PREVIOUS_PRODUCT_VERSION=#{ENV['PREVIOUS_PRODUCT_VERSION']}" : ''}#{ ENV['PREVIOUS_PRODUCT_VERSION'] ? " PRODUCT_VERSION=#{ENV['PRODUCT_VERSION']}" : ''}"
|
268
|
+
raise e
|
269
|
+
end
|
270
|
+
ENV['STAGE'] = nil unless options[:always_run]
|
271
|
+
elsif !ENV['STAGE'].nil?
|
272
|
+
puts "Skipping Stage: #{stage_name} - #{description}"
|
273
|
+
end
|
274
|
+
if ENV['LAST_STAGE'] == stage_name
|
275
|
+
ENV['STAGE'] = ENV['LAST_STAGE']
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
data/lib/buildr/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: realityforge-buildr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Apache Buildr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -182,6 +182,7 @@ files:
|
|
182
182
|
- NOTICE
|
183
183
|
- README.md
|
184
184
|
- Rakefile
|
185
|
+
- addon/buildr/api_diff_tool.rb
|
185
186
|
- addon/buildr/checkstyle-report.xsl
|
186
187
|
- addon/buildr/checkstyle.rb
|
187
188
|
- addon/buildr/git_auto_version.rb
|
@@ -189,6 +190,7 @@ files:
|
|
189
190
|
- addon/buildr/gwt.rb
|
190
191
|
- addon/buildr/jacoco.rb
|
191
192
|
- addon/buildr/pmd.rb
|
193
|
+
- addon/buildr/release_tool.rb
|
192
194
|
- addon/buildr/shade.rb
|
193
195
|
- addon/buildr/single_intermediate_layout.rb
|
194
196
|
- addon/buildr/spotbugs.rb
|