Skip to content

Instantly share code, notes, and snippets.

@bdotdub
Created October 17, 2010 00:43
Show Gist options
  • Save bdotdub/630410 to your computer and use it in GitHub Desktop.
Save bdotdub/630410 to your computer and use it in GitHub Desktop.
#!/opt/local/bin/ruby
require 'yaml'
require 'net/http'
require 'rubygems'
require 'json'
####################################################################
#
# Broken Build Git Hook
#
# This is a git hook script to check CI if the build is broken. If
# so, it will prevent your `git push` to be rejected until the
# build is green.
#
# -------------
# Conventions
# -------------
# The script will look for CI build names in the format of
# REPO-BRANCH (ie. gilt-qa, other-repo-production) *except*
# for the master branch of the repo. It will just use the
# repo name.
#
# -------------
# Configuration
# -------------
# Since this script is called by itself, the config for the script
# will be set below
#
# REPO_NAME
# this is the repo name in CI (ie. gilt, other-repo, schema)
# BRANCH_OVERRIDES
# a hash to override the CI name for a branch. If the qa branch in
# gilt is not gilt-qa, we'll have to pass in a hash to override it.
# ie. { 'gilt-qa' => 'the-override' }
#
# -------------
# Checking CI
# -------------
# The method to check CI is in status_for_build in the GiltRepo
# class below. If any custom login needed, or new CI used, that
# method will have to change.
#
#
####################################################################
REPO_NAME = 'gilt'
BRANCH_OVERRIDES = {}
################################################
# Probably don't have to edit below this line
################################################
class Repo
class Status
GREEN = 0
RED = 1
end
attr_accessor :ci_format, :overrides
attr_reader :repo
def initialize(repo, format="%R-%b")
@format = format
@repo = repo
@overrides = { 'master' => repo }
end
def build_for_ref_is_broken?(ref)
ci_name = ci_name_for_ref(ref)
status_for_build(ci_name) == Repo::Status::RED
end
def overrides(branch_overrides)
@overrides.merge!(branch_overrides)
end
private
def ci_name_for_ref(ref)
ref.gsub!("refs/heads/", "") # Remove remove branch ref prefix
if !(@overrides && ci_name = @overrides[ref])
ci_name = @format.dup
ci_name.gsub!("%R", self.repo)
ci_name.gsub!("%b", ref)
end
ci_name
end
def status_for_build(ci_name)
status = Repo::Status::RED
begin
Net::HTTP.start('YOUR.CI.HOST.COM') do |http|
request = Net::HTTP::Get.new("/hudson/job/#{@repo}/lastBuild/api/json?token=YOUR_HUDSON_TOKEN")
request.basic_auth 'BASIC_AUTH_USERNAME', 'BASIC_AUTH_PASSWORD'
response = http.request(request)
response_object = JSON.parse(response.body)
status = GiltRepo::Status::GREEN if response_object['result'] == 'SUCCESS'
end
rescue JSON::ParserError => e
puts "*************************"
puts "ERROR : Could not parse the response from CI"
puts "*************************"
exit 1
rescue => e
puts "*************************"
puts "ERROR : Unknown error trying to get CI status of repo"
puts "#{e.inspect}"
puts "*************************"
exit 1
end
status
end
end
repo = Repo.new(REPO_NAME)
repo.overrides = BRANCH_OVERRIDES
STDIN.read.split("\n").each do |ref_line|
rev_old, rev_new, ref = ref_line.split(" ")
next if rev_old =~ /^0+$/ # Skip if new branch
next if rev_new =~ /^0+$/ # Skip if deleting branch
if repo.build_for_ref_is_broken?(ref)
puts "*************************"
puts "ERROR : The build is broken for this repo / branch. You cannot push until the build is green (ref: #{ref})"
puts "*************************"
exit 1
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment