Skip to content

Commit 1690975

Browse files
donoghucmergify[bot]
authored andcommitted
Ensure docs gen inserts at correct place in file (#18250)
The regex for finding the latest release (as a fallback when current is not in the file) had a bug. This caused the generated docs to be inserted at the wrong place in the file (the end of the file) instead of the top. This commit fixes the logic such that we find the last release when the current is not found. (cherry picked from commit a3228e2) # Conflicts: # tools/release/generate_release_notes_md.rb
1 parent 8e00c87 commit 1690975

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/usr/bin/env ruby
2+
# Licensed to Elasticsearch B.V. under one or more contributor
3+
# license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright
5+
# ownership. Elasticsearch B.V. licenses this file to you under
6+
# the Apache License, Version 2.0 (the "License"); you may
7+
# not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
19+
# Example:
20+
# ruby generate_release_notes.rb 6.4 6.4.1
21+
#
22+
# This:
23+
# * compares the lock file of two commits
24+
# * for each plugin version bumped show CHANGELOG.md of the bumped version
25+
require 'tempfile'
26+
require 'yaml'
27+
require 'json'
28+
require 'net/http'
29+
30+
RELEASE_NOTES_PATH = "docs/release-notes/index.md"
31+
release_branch = ARGV[0]
32+
previous_release_tag = ARGV[1]
33+
user = ARGV[2]
34+
token = ARGV[3]
35+
report = []
36+
37+
`git checkout #{release_branch}`
38+
39+
current_release = YAML.load(IO.read("versions.yml"))["logstash"]
40+
41+
release_notes = IO.read(RELEASE_NOTES_PATH).split("\n")
42+
43+
coming_tag_index = release_notes.find_index {|line| line.match(/^## #{current_release} \[logstash-#{current_release}-release-notes\]$/) }
44+
coming_tag_index += 1 if coming_tag_index
45+
release_notes_entry_index = coming_tag_index || release_notes.find_index {|line| line.match(/^## .*\[logstash-.*-release-notes\]$/) }
46+
47+
unless coming_tag_index
48+
report << "## #{current_release} [logstash-#{current_release}-release-notes]\n\n"
49+
report << "### Features and enhancements [logstash-#{current_release}-features-enhancements]\n"
50+
end
51+
52+
plugin_changes = {}
53+
54+
report << "---------- GENERATED CONTENT STARTS HERE ------------"
55+
report << "=== Logstash Pull Requests with label v#{current_release}\n"
56+
57+
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")
58+
pull_requests = JSON.parse(Net::HTTP.get(uri))
59+
pull_requests['items'].each do |prs|
60+
report << "* #{prs['title']} #{prs['html_url']}[##{prs['number']}]"
61+
end
62+
report << ""
63+
64+
report << "=== Logstash Commits between #{release_branch} and #{previous_release_tag}\n"
65+
report << "Computed with \"git log --pretty=format:'%h -%d %s (%cr) <%an>' --abbrev-commit --date=relative v#{previous_release_tag}..#{release_branch}\""
66+
report << ""
67+
logstash_prs = `git log --pretty=format:'%h -%d %s (%cr) <%an>' --abbrev-commit --date=relative v#{previous_release_tag}..#{release_branch}`
68+
report << logstash_prs
69+
report << "\n=== Logstash Plugin Release Changelogs ==="
70+
report << "Computed from \"git diff v#{previous_release_tag}..#{release_branch} *.release\""
71+
result = `git diff v#{previous_release_tag}..#{release_branch} *.release`.split("\n")
72+
73+
result.each do |line|
74+
# example "+ logstash-input-syslog (3.4.1)"
75+
if match = line.match(/\+\s+(?<plugin>logstash-.+?-.+?)\s+\((?<version>\d+\.\d+.\d+).*?\)/)
76+
plugin_changes[match[:plugin]] ||= []
77+
plugin_changes[match[:plugin]] << match[:version]
78+
elsif match = line.match(/\-\s+(?<plugin>logstash-.+?-.+?)\s+\((?<version>\d+\.\d+.\d+).*?\)/)
79+
plugin_changes[match[:plugin]] ||= []
80+
plugin_changes[match[:plugin]].unshift(match[:version])
81+
else
82+
# ..
83+
end
84+
end
85+
report << "Changed plugin versions:"
86+
plugin_changes.each {|p, v| report << "#{p}: #{v.first} -> #{v.last}" }
87+
report << "---------- GENERATED CONTENT ENDS HERE ------------\n"
88+
89+
report << "### Plugins [logstash-plugin-#{current_release}-changes]\n"
90+
91+
plugin_changes.each do |plugin, versions|
92+
_, type, name = plugin.split("-")
93+
header = "**#{name.capitalize} #{type.capitalize} - #{versions.last}**"
94+
start_changelog_file = Tempfile.new(plugin + 'start')
95+
end_changelog_file = Tempfile.new(plugin + 'end')
96+
changelog = `curl https://raw.githubusercontent.com/logstash-plugins/#{plugin}/v#{versions.last}/CHANGELOG.md`.split("\n")
97+
report << "#{header}\n"
98+
changelog.each do |line|
99+
break if line.match(/^## #{versions.first}/)
100+
next if line.match(/^##/)
101+
line.gsub!(/^\+/, "")
102+
line.gsub!(/ #(?<number>\d+)\s*$/, " https://github.com/logstash-plugins/#{plugin}/issues/\\k<number>[#\\k<number>]")
103+
line.gsub!(/\[#(?<number>\d+)\]\((?<url>[^)]*)\)/, "[#\\k<number>](\\k<url>)")
104+
line.gsub!(/^\s+-/, "*")
105+
report << line
106+
end
107+
report << ""
108+
start_changelog_file.unlink
109+
end_changelog_file.unlink
110+
end
111+
112+
release_notes.insert(release_notes_entry_index, report.join("\n").gsub(/\n{3,}/, "\n\n"))
113+
114+
IO.write(RELEASE_NOTES_PATH, release_notes.join("\n"))
115+
116+
if token.nil?
117+
puts "No token provided, skipping commit and push"
118+
exit
119+
end
120+
121+
puts "Creating commit.."
122+
branch_name = "update_release_notes_#{Time.now.to_i}"
123+
`git checkout -b #{branch_name}`
124+
`git commit #{RELEASE_NOTES_PATH} -m "Update release notes for #{current_release}"`
125+
126+
puts "Pushing commit.."
127+
`git remote set-url origin https://x-access-token:#{token}@github.com/elastic/logstash.git`
128+
`git push origin #{branch_name}`
129+
130+
puts "Creating Pull Request"
131+
pr_title = "Release notes for #{current_release}"
132+
result = `curl -H "Authorization: token #{token}" -d '{"title":"#{pr_title}","base":"#{release_branch}", "head":"#{branch_name}", "draft": true}' https://api.github.com/repos/elastic/logstash/pulls`
133+
puts result
134+
pr_number = JSON.parse(result)["number"]
135+
puts `curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token #{token}" https://api.github.com/repos/elastic/logstash/issues/#{pr_number}/assignees -d '{"assignees":["#{user}"]}'`
136+
puts "Done"

0 commit comments

Comments
 (0)