[core] updated rake releases to generate markdown; added github_release task to publish to release feed.

This commit is contained in:
Kyle Rames 2014-03-24 09:12:19 -05:00
parent 2be37279e0
commit 15c6f40825
5 changed files with 260 additions and 92 deletions

View File

@ -3,6 +3,8 @@ source "https://rubygems.org"
group :development, :test do
# This is here because gemspec doesn't support require: false
gem 'coveralls', :require => false
gem "netrc", :require => false
gem "octokit", :require => false
end
gemspec

View File

@ -21,7 +21,7 @@ To request a new release please raise an issue.
services)
* Ensure working on **master**
* Update the version number (`lib/fog/version.rb`)
* Run `rake changelog` to update `changelog.txt`
* Run `rake changelog` to update `CHANGELOG.md`
* Run `rake release` to prepare the release which does:
* Prepares the release (`rake release:prepare`)
* Builds the gem
@ -30,6 +30,7 @@ services)
* Publishes the release (`rake release:publish`)
* Pushes commit and tag to Github (Requires Credentials)
* Pushes gem to Rubygems (Requires Credentials)
* Run `rake github_release` to add release to [github release feed](https://github.com/fog/fog/releases.atom) (Requires Credentials)
## Announce the release

View File

@ -208,6 +208,7 @@ YARD::Rake::YardocTask.new do |t|
end
require "tasks/changelog_task"
require "tasks/github_release_task"
Fog::Rake::ChangelogTask.new
task :coveralls_push_workaround do

View File

@ -8,103 +8,200 @@ module Fog
def initialize
desc "Update the changelog since the last release"
task(:changelog) do
timestamp = Time.now.utc.strftime('%m/%d/%Y')
sha = `git log | head -1`.split(' ').last
changelog = ["#{Fog::VERSION} #{timestamp} #{sha}"]
changelog << ('=' * changelog[0].length)
changelog << ''
github_repo_data = Fog::JSON.decode(Excon.get('https://api.github.com/repos/fog/fog', :headers => {'User-Agent' => 'geemus'}).body)
data = github_repo_data.reject {|key, value| !['forks', 'open_issues', 'watchers'].include?(key)}
github_collaborator_data = Fog::JSON.decode(Excon.get('https://api.github.com/repos/fog/fog/collaborators', :headers => {'User-Agent' => 'geemus'}).body)
data['collaborators'] = github_collaborator_data.length
rubygems_data = Fog::JSON.decode(Excon.get('https://rubygems.org/api/v1/gems/fog.json').body)
data['downloads'] = rubygems_data['downloads']
stats = []
for key in data.keys.sort
stats << "'#{key}' => #{data[key]}"
@changelog = []
@changelog << "## #{Fog::VERSION} #{timestamp}"
@changelog << "*Hash* #{sha}"
@changelog << blank_line
@changelog << "Statistic | Value"
@changelog << "------------- | --------:"
@changelog << "Collaborators | #{collaborators}"
@changelog << "Downloads | #{downloads}"
@changelog << "Forks | #{forks}"
@changelog << "Open Issues | #{open_issues}"
@changelog << "Watchers | #{watchers}"
@changelog << blank_line
process_commits
@changelog << "**MVP!** #{mvp}" if mvp
@changelog << blank_line
add_commits_to_changelog
save_changelog
end
end
private
def save_changelog
old_changelog = File.read('CHANGELOG.md')
File.open('CHANGELOG.md', 'w') do |file|
file.write(@changelog.join("\n"))
file.write("\n\n")
file.write(old_changelog)
end
end
def blank_line
''
end
def add_commits_to_changelog
@changes.keys.sort.each do |tag|
@changelog << "#### [#{tag}]"
@changes[tag].each do |commit|
@changelog << "* #{commit}"
end
changelog << "Stats! { #{stats.join(', ')} }"
changelog << ''
@changelog << blank_line
end
end
last_sha = `cat changelog.txt | head -1`.split(' ').last
shortlog = `git shortlog #{last_sha}..HEAD`
changes = {}
committers = {}
for line in shortlog.split("\n")
if line =~ /^\S/
committer = line.split(' (', 2).first
committers[committer] = 0
elsif line =~ /^\s*((Merge.*)|(Release.*))?$/
# skip empty lines, Merge and Release commits
else
unless line[-1..-1] == '.'
line << '.'
end
line.lstrip!
line.gsub!(/^\[([^\]]*)\] /, '')
tag = $1 || 'misc'
changes[tag] ||= []
changes[tag] << (line << ' thanks ' << committer)
committers[committer] += 1
end
end
for committer, commits in committers.to_a.sort {|x,y| y[1] <=> x[1]}
if [
'Aaron Suggs',
'Ash Wilson',
'Brian Hartsock',
'Chris Roberts',
'Christopher Oliver',
'Daniel Reichert',
'Decklin Foster',
'Dylan Egan',
'Erik Michaels-Ober',
'geemus',
'Henry Addison',
'James Bence',
'Kevin Menard',
'Kevin Olbrich',
'Kyle Rames',
'Lincoln Stoll',
'Luqman Amjad',
'Michael Zeng',
'Mike Hagedorn',
'Mike Pountney',
'Nat Welch',
'Nick Osborn',
'nightshade427',
'Patrick Debois',
'Paul Thornthwaite',
'Rodrigo Estebanez',
'Rupak Ganguly',
'Stepan G. Fedorov',
'Wesley Beary'
].include?(committer)
next
end
changelog << "MVP! #{committer}"
changelog << ''
break
end
for tag in changes.keys.sort
changelog << ('[' << tag << ']')
for commit in changes[tag]
changelog << (' ' << commit)
end
changelog << ''
end
old_changelog = File.read('changelog.txt')
File.open('changelog.txt', 'w') do |file|
file.write(changelog.join("\n"))
file.write("\n\n")
file.write(old_changelog)
def process_commits
shortlog = `git shortlog #{last_release_sha}..HEAD`
@changes = {}
@committers = {}
@committer = nil
shortlog.split("\n").each do |line|
@current_line = line
if committer_line?
@committer = committer_match[1]
add_committer
elsif !release_merge_line?
add_period_if_necessary
@current_line.lstrip!
add_commit_line
increment_commits
end
end
end
def add_commit_line
@current_line.gsub!(/^\[([^\]]*)\] /, '')
tag = $1 || 'misc'
@changes[tag] ||= []
@changes[tag] << "#{@current_line} thanks #{@committer}"
end
def increment_commits
@committers[@committer] += 1
end
def add_committer
@committers[@committer] = 0
end
def committers_sorted_by_commits
committer_pairs = @committers.to_a.sort {|x,y| y[1] <=> x[1]}
committer_pairs.reject! {|pair| pair.last < 1 }
committer_pairs.collect {|pair| pair.first }
end
def mvp_eligible?(committer)
[
'Aaron Suggs',
'Ash Wilson',
'Brian Hartsock',
'Chris Roberts',
'Christopher Oliver',
'Daniel Reichert',
'Decklin Foster',
'Dylan Egan',
'Erik Michaels-Ober',
'geemus',
'Henry Addison',
'James Bence',
'Kevin Menard',
'Kevin Olbrich',
'Kyle Rames',
'Lincoln Stoll',
'Luqman Amjad',
'Michael Zeng',
'Mike Hagedorn',
'Mike Pountney',
'Nat Welch',
'Nick Osborn',
'nightshade427',
'Patrick Debois',
'Paul Thornthwaite',
'Rodrigo Estebanez',
'Rupak Ganguly',
'Stepan G. Fedorov',
'Wesley Beary'
].include?(committer)
end
def mvp
return @mvp if @mvp
committers_sorted_by_commits.each do |committer|
if mvp_eligible?(committer)
@mvp = committer
return @mvp
end
end
nil
end
def add_period_if_necessary
@current_line << "." unless @current_line[-1] == '.'
end
def release_merge_line?
@current_line =~ /^\s*((Merge.*)|(Release.*))?$/
end
def committer_line?
committer_match != nil
end
def committer_match
@current_line.match /([\w\s]+)\s+\(\d+\)/
end
def last_release_sha
`cat changelog.md | head -2`.split(' ').last
end
def downloads
repsonse = Excon.get('https://rubygems.org/api/v1/gems/fog.json')
data = Fog::JSON.decode(repsonse.body)
data['downloads']
end
def collaborators
response = Excon.get('https://api.github.com/repos/fog/fog/collaborators', :headers => {'User-Agent' => 'geemus'})
data = Fog::JSON.decode(response.body)
data.length
end
def forks
repo_metadata['forks']
end
def open_issues
repo_metadata['open_issues']
end
def watchers
repo_metadata['watchers']
end
def repo_metadata
return @repo_metadata if @repo_metadata
response = Excon.get('https://api.github.com/repos/fog/fog', :headers => {'User-Agent' => 'geemus'})
data = Fog::JSON.decode(response.body)
@repo_metadata = data.select {|key, value| ['forks', 'open_issues', 'watchers'].include?(key)}
end
def sha
`git log | head -1`.split(' ').last
end
def timestamp
@time ||= Time.now.utc.strftime('%m/%d/%Y')
end
end
end
end

View File

@ -0,0 +1,67 @@
require "rake"
require "rake/tasklib"
require 'octokit'
require 'netrc'
module Fog
module Rake
class ChangelogTask < ::Rake::TaskLib
def initialize
desc "Update the changelog since the last release"
task(:github_release) do
File.open('CHANGELOG.md', 'r') do |file|
file.each_line do |line|
@current_line = line
if release_header?
create_release if !release_exists? && @release
@release_tag = release_match[1]
@release = line
else
@release << line
end
end
end
end
end
private
def create_release
github.create_release "fog/fog", "v#{@release_tag}", {:name => "v#{@release_tag}", :body => @release}
puts "creating release #{@release_tag}"
end
def releases
return @releases if @releases
response = github.releases("fog/fog")
@releases = response.collect {|r| r.tag_name }
end
def release_exists?
releases.find {|r| r == "v#{@release_tag}" } != nil
end
def release_header?
release_match != nil
end
def release_match
@current_line.match /## (\d+\.\d+\.\d+) \d+\/\d+\d+/
end
def github
unless @github
Octokit.auto_paginate = true
@github = Octokit::Client.new :netrc => true
unless @github.login
@github = nil
raise "Please create a ~.netrc file to authenticate with github. For more information please see https://github.com/octokit/octokit.rb/blob/master/README.md#using-a-netrc-file"
end
end
@github
end
end
end
end