Skip to content

Instantly share code, notes, and snippets.

@rynbyjn
Last active August 29, 2015 14:23
Show Gist options
  • Save rynbyjn/178dd7d7196e8bc42737 to your computer and use it in GitHub Desktop.
Save rynbyjn/178dd7d7196e8bc42737 to your computer and use it in GitHub Desktop.
Generate release notes from closed pull requests.

Generate release notes from PRs

By default this will look at the previous 100 commits from your local .git folder in your project. To Add release notes to an older project you might want to bump that WAY up.

Also you will need a valid GitHub token in your .env file.

GenerateReleaseNotes.new('your_org/your_project', 'path_to_location_of_prev_sha_file/previous-sha.yml', ENV['GITHUB_API_TOKEN'], true)

GITHUB_API_TOKEN=YOUR_TOKEN HERE
source 'https://rubygems.org'
# used for automated release notes
gem 'dotenv'
gem 'git'
gem 'octokit', '~> 3.0'
#!/usr/bin/env ruby
require 'bundler/setup'
require 'dotenv'
require 'git'
require 'octokit'
require 'yaml'
# load .env vars
Dotenv.load
class GenerateReleaseNotes
def initialize(repo_name, previous_sha_file, access_token, is_test=false)
return puts 'You must supply a valid github API token' unless access_token.length > 0
@repo_name = repo_name
@pull_request_notes = ['RELEASE NOTES']
# Grab out previous sha
@previous_sha_file = previous_sha_file
@previous_sha_yaml = YAML::load_file(@previous_sha_file)
@is_test = is_test
set_versions
# create github api client
@client = Octokit::Client.new(access_token: access_token)
# create git
@git = Git.open('./')
commits = @git.log(100)
@newest_sha = commits.first.sha
# start creating the notes
scan_commits commits
# update the notes
update_release_notes
end
# grab out build verion info
def set_versions
@git_release_version = `git describe --tags --always --abbrev=0`.strip()
@number_of_commits = `git rev-list master | wc -l | tr -d ' '`.strip()
end
# add PRs from commits
def scan_commits(commits)
commits.each do |commit|
return true if @previous_sha_yaml['previous-sha'] == commit.sha
match = commit.message.match(/pull request #(\d+) from/)
if match
pr_num = match.captures[0]
pr = @client.pull_request @repo_name, pr_num
if pr[:state] == 'closed'
@pull_request_notes << "#### ##{pr_num} - #{pr[:title]}\n#{pr[:body]}".strip()
end
end
end
end
def update_release_notes
# new release notes
release_notes = "### Build #{@git_release_version}(#{@number_of_commits}) #{Time.now.strftime("%B %-d, %Y")}\n\n"
release_notes << <<-EOF
#{@pull_request_notes.count > 1 ? @pull_request_notes.join("\n\n------\n\n") : 'No completed pull requests since last release.'}
#{"\n------------\n"}
EOF
# add release_notes to
`mkdir tmp`
File.open("tmp/#{@number_of_commits}-release-notes.md", 'w') { |f| f.write release_notes.gsub(/(#+ )/, "") }
if @is_test
puts release_notes.gsub(/(#+ )/, "")
else
# prepend new contents into release-notes
old = File.open('release-notes.md', 'a')
new = File.open('release-notes.new.md', 'w')
File.open(new, 'w') { |f|
f.puts release_notes
f.puts File.read(old)
}
File.rename(new, old)
# update the latest commit from here
@previous_sha_yaml["previous-sha"] = @newest_sha
File.open(@previous_sha_file, 'w') {|f| f.write @previous_sha_yaml.to_yaml }
end
end
end
---
previous-sha: sha_to_start_from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment