Skip to content

Commit ccfa770

Browse files
committed
add lockfile bump and release notes draft tools
Fixes #10265
1 parent c58409e commit ccfa770

File tree

3 files changed

+206
-84
lines changed

3 files changed

+206
-84
lines changed

rakelib/bump_plugin_versions.rake

-84
This file was deleted.

tools/release/bump_plugin_versions.rb

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
require 'net/http'
2+
require 'uri'
3+
require 'fileutils'
4+
require 'yaml'
5+
6+
def compute_dependecy(version, allow_for)
7+
gem_version = Gem::Version.new(version)
8+
return version if gem_version.prerelease?
9+
major, minor, patch = gem_version.release.segments
10+
case allow_for
11+
when "major"
12+
then "~> #{major}"
13+
when "minor"
14+
then "~> #{major}.#{minor}"
15+
when "patch"
16+
then "~> #{major}.#{minor}.#{patch}"
17+
end
18+
end
19+
20+
base_branch = ARGV[0]
21+
base_logstash_version = ARGV[1]
22+
allow_bump_for = ARGV[2]
23+
24+
unless ["major", "minor", "patch"].include?(allow_bump_for)
25+
puts "second argument must be one of 'major', 'minor' or 'patch', got '#{allow_bump_for}'"
26+
exit(1)
27+
end
28+
29+
puts "Computing #{allow_bump_for} plugin dependency bump from #{base_logstash_version}.."
30+
31+
puts "Fetching lock file for #{base_logstash_version}.."
32+
uri = URI.parse("https://raw.githubusercontent.com/elastic/logstash/v#{base_logstash_version}/Gemfile.jruby-2.3.lock.release")
33+
result = Net::HTTP.get(uri)
34+
if result.match(/404/)
35+
puts "Lock file or git tag for #{base_logstash_version} not found. Aborting"
36+
exit(1)
37+
end
38+
39+
base_plugin_versions = {}
40+
skip_elements = ["logstash-core", "logstash-devutils", "logstash-core-plugin-api"]
41+
result.split("\n").each do |line|
42+
# match e.g. " logstash-output-nagios (3.0.6)"
43+
if match = line.match(/^ (?<plugin>logstash-.+?)\s\((?<version>.+?)(?:-java)?\)/)
44+
next if skip_elements.include?(match["plugin"])
45+
base_plugin_versions[match["plugin"]] = match["version"]
46+
end
47+
end
48+
49+
computed_dependency = {}
50+
puts "Generating new Gemfile.template file with computed dependencies"
51+
gemfile = IO.read("Gemfile.template")
52+
base_plugin_versions.each do |plugin, version|
53+
dependency = compute_dependecy(version, allow_bump_for)
54+
gemfile.gsub!(/"#{plugin}".*$/, "\"#{plugin}\", \"#{dependency}\"")
55+
end
56+
57+
IO.write("Gemfile.template", gemfile)
58+
59+
puts "Cleaning up before running 'rake artifact:tar'"
60+
FileUtils.rm_f("Gemfile")
61+
FileUtils.rm_f("Gemfile.jruby-2.3.lock.release")
62+
FileUtils.rm_rf("vendor")
63+
64+
# compute new lock file
65+
puts "Running 'rake artifact:tar'"
66+
result = `rake artifact:tar`
67+
68+
puts "Cleaning up generated lock file (removing injected requirements)"
69+
# remove explicit requirements from lock file
70+
lock_file = IO.read("Gemfile.lock")
71+
new_lock = []
72+
lock_file.split("\n").each do |line|
73+
new_lock << line.gsub(/^ (?<plugin>logstash-\w+-.+?) .+?$/, " \\k<plugin>")
74+
end
75+
IO.write("Gemfile.lock", new_lock.join("\n"))
76+
77+
# rename file
78+
puts "Finishing up.."
79+
FileUtils.mv("Gemfile.lock", "Gemfile.jruby-2.3.lock.release")
80+
81+
`git checkout -- Gemfile.template`
82+
83+
puts `git diff Gemfile.jruby-2.3.lock.release`
84+
85+
puts "Creating commit.."
86+
87+
branch_name = "update_lock_#{Time.now.to_i}"
88+
`git checkout -b #{branch_name}`
89+
`git commit Gemfile.jruby-2.3.lock.release -m "Update #{allow_bump_for} plugin versions in gemfile lock"`
90+
91+
puts "Pushing commit.."
92+
`git remote add upstream git@github.com:elastic/logstash.git`
93+
`git push upstream #{branch_name}`
94+
95+
current_release = YAML.parse(IO.read("versions.yml"))["logstash"]
96+
puts "Creating Pull Request"
97+
pr_title = "bump lock file for #{current_release}"
98+
99+
`curl -H "Authorization: token #{ENV['GITHUB_TOKEN']}" -d '{"title":"#{pr_title}","base":"#{base_branch}", "head":"#{branch_name}"}' https://api.github.com/repos/elastic/logstash/pulls`
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Example:
2+
# ruby generate_release_notes.rb 6.4 6.4.1
3+
#
4+
# This:
5+
# * compares the lock file of two commits
6+
# * for each plugin version bumped show CHANGELOG.md of the bumped version
7+
require 'tempfile'
8+
require 'yaml'
9+
require 'json'
10+
require 'net/http'
11+
12+
RELEASE_NOTES_PATH = "docs/static/releasenotes.asciidoc"
13+
release_branch = ARGV[0]
14+
previous_release_tag = ARGV[1]
15+
report = []
16+
17+
`git checkout #{release_branch}`
18+
19+
current_release = YAML.load(IO.read("versions.yml"))["logstash"]
20+
current_release_dashes = current_release.tr(".", "-")
21+
22+
release_notes = IO.read(RELEASE_NOTES_PATH).split("\n")
23+
24+
release_notes.insert(5, "* <<logstash-#{current_release_dashes},Logstash #{current_release}>>")
25+
26+
release_notes_entry_index = release_notes.find_index {|line| line.match(/^\[\[logstash/) }
27+
28+
report << "[[logstash-#{current_release_dashes}]]"
29+
report << "=== Logstash #{current_release} Release Notes\n"
30+
31+
plugin_changes = {}
32+
33+
report << "---------- DELETE FROM HERE ------------"
34+
report << "=== Logstash Pull Requests with label v#{current_release}\n"
35+
36+
uri = URI.parse("https://api.github.com/search/issues?q=repo:elastic/logstash+is:pr+is:closed+label:v#{current_release}&sort=created&order=asc")
37+
pull_requests = JSON.parse(Net::HTTP.get(uri))
38+
pull_requests['items'].each do |prs|
39+
report << "* #{prs['title']} #{prs['html_url']}[##{prs['number']}]"
40+
end
41+
report << ""
42+
43+
report << "=== Logstash Commits between #{release_branch} and #{previous_release_tag}\n"
44+
report << "Computed with \"git log --pretty=format:'%h -%d %s (%cr) <%an>' --abbrev-commit --date=relative v#{previous_release_tag}..#{release_branch}\""
45+
report << ""
46+
logstash_prs = `git log --pretty=format:'%h -%d %s (%cr) <%an>' --abbrev-commit --date=relative v#{previous_release_tag}..#{release_branch}`
47+
report << logstash_prs
48+
report << "\n=== Logstash Plugin Release Changelogs ==="
49+
report << "Computed from \"git diff v#{previous_release_tag}..#{release_branch} *.release\""
50+
result = `git diff v#{previous_release_tag}..#{release_branch} *.release`.split("\n")
51+
52+
result.each do |line|
53+
# example "+ logstash-input-syslog (3.4.1)"
54+
if match = line.match(/\+\s+(?<plugin>logstash-.+?-.+?)\s+\((?<version>\d+\.\d+.\d+).*?\)/)
55+
plugin_changes[match[:plugin]] ||= []
56+
plugin_changes[match[:plugin]] << match[:version]
57+
elsif match = line.match(/\-\s+(?<plugin>logstash-.+?-.+?)\s+\((?<version>\d+\.\d+.\d+).*?\)/)
58+
plugin_changes[match[:plugin]] ||= []
59+
plugin_changes[match[:plugin]].unshift(match[:version])
60+
else
61+
# ..
62+
end
63+
end
64+
report << "Changed plugin versions:"
65+
plugin_changes.each {|p, v| report << "#{p}: #{v.first} -> #{v.last}" }
66+
report << "---------- DELETE UP TO HERE ------------\n"
67+
68+
report << "==== Plugins\n"
69+
70+
plugin_changes.each do |plugin, versions|
71+
_, type, name = plugin.split("-")
72+
header = "*#{name.capitalize} #{type.capitalize}*"
73+
start_changelog_file = Tempfile.new(plugin + 'start')
74+
end_changelog_file = Tempfile.new(plugin + 'end')
75+
changelog = `curl https://raw.githubusercontent.com/logstash-plugins/#{plugin}/v#{versions.last}/CHANGELOG.md`.split("\n")
76+
report << "#{header}\n"
77+
changelog.each do |line|
78+
break if line.match(/^## #{versions.first}/)
79+
next if line.match(/^##/)
80+
line.gsub!(/^\+/, "")
81+
line.gsub!(/ #(?<number>\d+)\s*$/, " https://github.com/logstash-plugins/#{plugin}/issues/\\k<number>[#\\k<number>]")
82+
line.gsub!(/^\s+-/, "*")
83+
report << line
84+
end
85+
report << ""
86+
start_changelog_file.unlink
87+
end_changelog_file.unlink
88+
end
89+
90+
release_notes.insert(release_notes_entry_index, report.join("\n").gsub(/\n{3,}/, "\n\n"))
91+
92+
IO.write(RELEASE_NOTES_PATH, release_notes.join("\n"))
93+
94+
puts "Creating commit.."
95+
branch_name = "update_release_notes_#{Time.now.to_i}"
96+
`git checkout -b #{branch_name}`
97+
`git commit docs/static/releasenotes.asciidoc -m "Update release notes for #{current_release}"`
98+
99+
puts "Pushing commit.."
100+
`git remote add upstream git@github.com:elastic/logstash.git`
101+
`git push upstream #{branch_name}`
102+
103+
puts "Creating Pull Request"
104+
pr_title = "Release notes draft for #{current_release}"
105+
`curl -H "Authorization: token #{ENV['GITHUB_TOKEN']}" -d '{"title":"#{pr_title}","base":"#{ENV['branch_specifier']}", "head":"#{branch_name}"}' https://api.github.com/repos/elastic/logstash/pulls`
106+
107+
puts "Done"

0 commit comments

Comments
 (0)