|
#!/usr/bin/env ruby |
|
# Lookup Travis CI build status of the current branch. |
|
# Exit with error status if build in progress or has failed. |
|
# |
|
# Dependenices: json (on ruby 1.8), hub |
|
|
|
begin |
|
require 'rubygems' |
|
require 'json' |
|
require 'time' |
|
require 'net/https' |
|
require 'uri' |
|
require 'hub/context' |
|
require 'hub/ssh_config' |
|
rescue LoadError |
|
abort $! |
|
end |
|
|
|
## helper methods |
|
|
|
include Hub::Context |
|
|
|
def get(url) |
|
uri = URI(url) |
|
http = Net::HTTP.new(uri.host, uri.port) |
|
http.use_ssl = true |
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER |
|
http.ca_path = '/etc/ssl/certs' if File.exists?('/etc/ssl/certs') |
|
|
|
case response = http.request_get(uri.request_uri) |
|
when Net::HTTPSuccess then JSON.parse(response.body) |
|
when Net::HTTPNotFound then abort "error: project not found on Travis" |
|
else abort "error: Travis API returned status #{response.code}" |
|
end |
|
end |
|
|
|
def to_branch(name) |
|
name = "refs/heads/#{name}" unless name.include?('/') |
|
Branch.new(local_repo, name) |
|
end |
|
|
|
## figure out current repo state |
|
|
|
branch = ARGV[0] ? to_branch(ARGV[0]) : current_branch or abort "no git branch" |
|
project = current_project or abort "git remote not pointing to a GitHub project" |
|
upstream = branch.upstream || to_branch("refs/remotes/#{project.remote}/#{branch.short_name}") |
|
pushed_rev = git_command("rev-parse #{upstream}") or abort "invalid upstream branch: #{upstream}" |
|
upstream_name = upstream.to_s.sub('refs/remotes/', '') |
|
|
|
## warn about unpushed commits |
|
|
|
if local_commits = git_command("rev-list --cherry #{upstream}...") |
|
warn "%d commits not yet pushed to %s" % [ |
|
local_commits.split("\n").size, |
|
upstream_name |
|
] |
|
end |
|
|
|
## talk to Travis |
|
|
|
builds = get('https://travis-ci.org/%s/builds.json' % current_project.name_with_owner) |
|
|
|
if build = builds.find {|b| b['commit'] == pushed_rev } |
|
if build['result'] |
|
if build['result'] == 0 |
|
puts "%s built OK." % upstream_name |
|
else |
|
warn "%s build failed." % upstream_name |
|
exit build['result'] |
|
end |
|
else |
|
started_at = Time.parse build['started_at'] |
|
seconds = Time.now - started_at |
|
abort "build in progress (%d seconds)" % seconds |
|
end |
|
else |
|
queue_name = case current_project.owner |
|
when 'rails', 'spree' then current_project.owner |
|
else |
|
conf = '.travis.yml' |
|
(File.exist?(conf) && File.read(conf) =~ /\blanguage:\s*(\w+)\b/) ? |
|
(%w[java scala groovy clojure].include?($1) ? 'jvm' : $1) : |
|
'common' |
|
end |
|
|
|
# check if build is waiting in the queue |
|
if queue = get("https://travis-ci.org/jobs.json?state=created&queue=builds.#{queue_name}") and !queue.empty? |
|
repo_id = builds.any? ? builds.first['repository_id'] : |
|
get('https://travis-ci.org/%s.json' % current_project.name_with_owner)['id'] |
|
|
|
if queue.any? { |b| b['repository_id'] == repo_id } |
|
abort "builds are waiting in the queue" |
|
end |
|
end |
|
|
|
abort "no build for #{upstream_name}" |
|
end |