Created
October 17, 2010 00:43
-
-
Save bdotdub/630410 to your computer and use it in GitHub Desktop.
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
#!/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