|
| 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