Created
March 30, 2011 23:28
-
-
Save dpmcnevin/895521 to your computer and use it in GitHub Desktop.
Git post-receive hook to modify stories in Pivotal Tracker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'mail' | |
require 'pivotal_tracker' | |
require 'git' | |
class Pivotal | |
attr_reader :story, :project | |
def initialize(story_id) | |
@project = Pivotal.set_auth! | |
@story = @project.stories.find(story_id) | |
end | |
def self.set_auth! | |
## PivotalTracker::Client.token('[email protected]', 'secretpassword') | |
PivotalTracker::Client.token = '..........' | |
## project id for gobbler | |
PivotalTracker::Project.find(123456) | |
end | |
def self.create!(title, story_type = "feature") | |
@project = set_auth! | |
new_story = @project.stories.create(:name => title, :story_type => story_type, :estimate => 1) | |
puts new_story.id | |
end | |
def description | |
<<-EOP | |
#{@story.name} | |
Requested By: #{@story.requested_by} :: Owned By #{@story.owned_by} | |
#{@story.url} | |
EOP | |
end | |
def start!(note) | |
if @story.estimate >= 0 && @story.current_state == "unscheduled" | |
@story.update(:current_state => "started") | |
@story.notes.create(:text => note) | |
elsif @story.estimate == -1 | |
warning_message("Story ID: ##{@story.id} does not have a points estimate\n\n#{@story.url}") | |
else | |
warning_message("Story ID: ##{@story.id} not marked as unscheduled (current: #{@story.current_state})\n\n#{@story.url}") | |
end | |
end | |
def finish!(note, params = {}) | |
## Allow stories to be started if they aren't already | |
options = {:allow_unstarted => true}.merge(params) | |
if (@story.current_state == "unscheduled" && options[:allow_unstarted]) || @story.current_state == "started" | |
@story.update(:current_state => "finished") | |
@story.notes.create(:text => note) | |
else | |
warning_message("Story ID: ##{@story.id} not marked as started (current: #{@story.current_state})\n\n#{@story.url}") | |
end | |
end | |
def deliver!(note) | |
if @story.current_state == "finished" | |
@story.update(:current_state => "delivered") | |
@story.notes.create(:text => note) | |
else | |
warning_message("Story ID: ##{@story.id} not marked as finished (current: #{@story.current_state})\n\n#{@story.url}") | |
end | |
end | |
def warning_message(text) | |
puts "***********************************************" | |
puts text | |
puts "***********************************************" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'hooks/pivotal' | |
stdins = []; stdins << $_ while gets | |
stdins.each do |str| | |
arr = str.split | |
refs = arr[2].split('/') | |
@old_rev = arr[0] | |
@new_rev = arr[1] | |
@ref_type = refs[1] | |
@ref_name = refs[2] | |
end | |
## if we are pushing tags, we don't need to continue | |
exit unless @ref_type == "heads" | |
@stories = [] | |
## If we want to get all of the commits, we need to have a big value for git log, doesn't look like you can disable it. | |
## We need to check to see if the original rev is all 0's, since git will pass that if it's the first commit. | |
@repo = Git.bare(".") | |
if @old_rev =~ /^00000/ | |
@logs = @repo.log(10000) | |
else | |
@logs = @repo.log(10000).between(@old_rev, @new_rev) | |
end | |
@logs.each do |log| | |
log_stories = log.message.scan(/[\#|\/]([0-9]{8})/) | |
if log_stories.size > 0 | |
@stories << { | |
:stories => log_stories, | |
:story_note => "SHA: #{log.sha}\nAuthor: #{log.committer.name}\n#{log.committer.date}\n\n#{log.message}" | |
} | |
end | |
end | |
if @ref_name == "release" | |
@resolved = @stories.map {|story| story[:stories] }.flatten.uniq | |
@message = "===> Pivotal Stories Resolved:\n" | |
@resolved.each do |story| | |
begin | |
@message << Pivotal.new(story).description | |
rescue | |
## uh oh | |
end | |
end | |
@message << "\n\n===> Git Commits:\n" | |
@logs.each do |log| | |
@message << "#{log.sha[0..6]} :: #{log.committer.email} :: #{log.message.gsub(/\n/," ")[0..70]}\n" | |
end | |
puts "====> Emailing about the commit to Release" | |
## Send mail | |
mail = Mail.new do | |
from "[email protected]" | |
to "[email protected]" | |
subject "[GIT] New Commit to Release Branch" | |
end | |
mail.body = "There has been a commit to the release branch. The release includes the following commits:\n\n#{@message}" | |
mail.delivery_method :sendmail | |
mail.deliver | |
else | |
@finished_stories = [] | |
@stories.each do |match| | |
match[:stories].flatten.each do |story| | |
## Only perform actiion once per story | |
next if @finished_stories.include?(story) | |
@finished_stories << story | |
begin | |
pivotal_story = Pivotal.new(story) | |
if @ref_name == "rc" | |
puts "===> Delivering Story ##{story} in Pivotal Tracker" | |
pivotal_story.deliver!("Story merged into RC\n\n#{match[:story_note]}") | |
elsif @ref_name == "master" | |
puts "===> Finishing Story ##{story} in Pivotal Tracker" | |
pivotal_story.finish!("Story marked as finished\n\n#{match[:story_note]}") | |
end | |
rescue Exception => e | |
puts "====> There was an error with the story ##{story}" | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment