|
require 'net/https' |
|
require 'json' |
|
require 'dotenv' |
|
require 'date' |
|
Dotenv.load |
|
|
|
#-------------------------------------------------------------------------------- |
|
# Configuration |
|
#-------------------------------------------------------------------------------- |
|
configuration = { |
|
:base_uri => ENV['BAMBOO_URI'], |
|
:credentials => { |
|
:username => ENV['BAMBOO_USER'], |
|
:password => ENV['BAMBOO_PASSWORD'] |
|
}, |
|
:refresh_rate => '10s', |
|
# manually retrieve by checking http://myhost.com:8085/bamboo/rest/api/latest/project/all |
|
# and getting the environment ID |
|
:deploy_ids => %w[11534337] |
|
} |
|
#-------------------------------------------------------------------------------- |
|
|
|
#-------------------------------------------------------------------------------- |
|
# Helper functions for time calculations |
|
#-------------------------------------------------------------------------------- |
|
|
|
# copied from http://stackoverflow.com/questions/1679266/can-ruby-print-out-time-difference-duration-readily |
|
class Numeric |
|
def duration |
|
secs = self.to_int |
|
mins = secs / 60 |
|
hours = mins / 60 |
|
days = hours / 24 |
|
|
|
if days > 0 |
|
"#{days} days and #{hours % 24} hours" |
|
elsif hours > 0 |
|
"#{hours} hours and #{mins % 60} minutes" |
|
elsif mins > 0 |
|
"#{mins} minutes and #{secs % 60} seconds" |
|
elsif secs >= 0 |
|
"#{secs} seconds" |
|
end |
|
end |
|
end |
|
|
|
# copied from http://camjuarez.com/posts/how-to-create-friendly-relative-timestamps |
|
def timeago(time) |
|
time_ago = ((Time.now - time) / 86400) # returns a number in days |
|
# Less than a day ago |
|
if time_ago < 1 |
|
time_ago *= 24 |
|
# Less than an hour ago |
|
if time_ago < 1 |
|
time_ago *= 60 |
|
# Less than a minute ago |
|
if time_ago < 1 |
|
time_ago *= 60 |
|
return "#{time_ago = time_ago.round}" + ((time_ago == 1) ? " second ago" : " seconds ago") |
|
end |
|
return "#{time_ago = time_ago.round}" + ((time_ago == 1) ? " minute ago" : " minutes ago") |
|
end |
|
return "#{time_ago = time_ago.round}" + ((time_ago == 1) ? " hour ago" : " hours ago") |
|
elsif time_ago == 1 |
|
return "#{time_ago = time_ago.round} day ago" |
|
else |
|
return "#{time_ago = time_ago.round} days ago" |
|
end |
|
end |
|
|
|
class BambooDeploy |
|
def initialize(base_uri, credentials) |
|
@base_uri = base_uri |
|
@credentials = credentials |
|
end |
|
|
|
def plan_status(deploy_id) |
|
begin |
|
deploy = latest_deploy(deploy_id) |
|
deploy_reason = deploy['reasonSummary'] |
|
|
|
author_avatar_url = deploy_reason.match("\/user\/([a-zA-Z]+)") do |match| |
|
avatar_url match[1] |
|
end |
|
author_avatar_url ||= '' |
|
|
|
return { |
|
:state => deploy['deploymentState'], |
|
:release_number => deploy['deploymentVersionName'][8..-1], |
|
:duration => ((deploy['finishedDate'] - deploy['executedDate'])/1000.0).duration, |
|
:finished => timeago(Time.at(deploy['finishedDate']/1000.0)), |
|
:avatar_url => author_avatar_url |
|
} |
|
|
|
rescue => e |
|
puts "Error getting bamboo deploy status: #{e}" |
|
return { |
|
:state => 'Unknown', |
|
:number => '?', |
|
:duration => '', |
|
:finished => '' |
|
} |
|
end |
|
end |
|
|
|
private |
|
|
|
def latest_deploy(deploy_id) |
|
response = make_request(result_endpoint(deploy_id)) |
|
response_json = JSON.parse(response.body) |
|
response_json['results'][0] |
|
end |
|
|
|
def setup_http |
|
@http ||= |
|
begin |
|
uri = URI.parse(@base_uri) |
|
http = Net::HTTP.new(uri.host, uri.port) |
|
if uri.scheme == 'https' |
|
http.use_ssl = true |
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE |
|
end |
|
http |
|
end |
|
end |
|
|
|
def make_request(endpoint) |
|
http = setup_http |
|
request = Net::HTTP::Get.new(endpoint) |
|
if @credentials && @credentials[:username].length > 0 |
|
request.basic_auth @credentials[:username], @credentials[:password] |
|
end |
|
response = http.request(request) |
|
end |
|
|
|
def rest_endpoint |
|
'/bamboo/rest/api/latest' |
|
end |
|
|
|
def auth_param |
|
if @credentials && @credentials[:username].length > 0 |
|
'os_authType=basic' |
|
else |
|
'' |
|
end |
|
end |
|
|
|
def result_endpoint(deploy_id) |
|
"#{rest_endpoint}/deploy/environment/#{deploy_id}/results.json?#{auth_param}&max-results=1" |
|
end |
|
|
|
def avatar_url(username) |
|
jira_url = "#{@base_uri}/jira/secure/useravatar?size=xlarge&ownerId=#{username}" |
|
response = make_request(jira_url) |
|
response['Location'] |
|
end |
|
end |
|
|
|
configuration[:deploy_ids].each do |deploy_id| |
|
SCHEDULER.every configuration[:refresh_rate], :first_in => 0 do |_| |
|
deploy = BambooDeploy.new(configuration[:base_uri], configuration[:credentials]) |
|
status = deploy.plan_status(deploy_id) |
|
send_event(deploy_id, status) |
|
end |
|
end |