Skip to content

Instantly share code, notes, and snippets.

@fonglh
Forked from jsyeo/README.md
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fonglh/5dce922fb5e90fcd2743 to your computer and use it in GitHub Desktop.
Save fonglh/5dce922fb5e90fcd2743 to your computer and use it in GitHub Desktop.

Bamboo Plan Dashing Widget

Dashing widget to display plan build details from your Bamboo instance.

Preview

Bamboo Dashing Widget

Installation

Automatic

To install this widget, run this command from your Dashing directory:

dashing install 5dce922fb5e90fcd2743

Then copy the bamboo-logo.png file into the assets\images folder

Manual

  1. Copy the below coffee/scss/html files into a widget folder named bamboo_deploy
  2. Copy the bamboo_deploy.rb file into the jobs folder
  3. Copy the bamboo-logo.png file into the assets\images folder

Usage

Update job

Update the configuration element in the bamboo_deploy.rb file with your bamboo instance uri and the deployments you wish to monitor.

configuration = {
    :bamboo_uri => 'http://bamboo:8085',
    :credentials => {
         :username => '',
         :password => ''
     },
    :refresh_rate => '10s',
    :plan_keys => %w[deploy_id_1 deploy_id_2]
}

Add to dashboard

To include this widget in your dashboard, add the following snippet of code to the dashboard layout file:

<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
  <div data-id="deploy_id_1" data-view="BambooDeploy" data-title="Deploy ID 1"></div>
</li>

You'll need to update the data-id with the name of your plan to show as defined in the bamboo_deploy.rb file.

class Dashing.BambooDeploy extends Dashing.Widget
@accessor 'value', Dashing.AnimatedValue
constructor: ->
super
refreshWidgetState: =>
node = $(@node)
node.removeClass('success failed unknown')
node.addClass(@get('state').toLowerCase())
ready: ->
@refreshWidgetState()
onData: (data) ->
@refreshWidgetState()
<h1 class="title" data-bind="title"></h1>
<div class="aligner">
<img data-bind-src="avatar_url" />
<h2 class="large-font" data-bind="release_number"></h2>
</div>
<h2 class="state" data-bind="state"></h2>
<p class="duration" data-bind="duration"></p>
<p class="finished" data-bind="finished"></p>
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
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$state-color: #fff;
$background-color: #4b4b4b;
$background-failed-color: #d26771;
$background-success-color: #96bf48;
$background-unknown-color: #999;
$title-color: rgba(255, 255, 255, 1);
$label-color: rgba(255, 255, 255, 0.7);
$duration-color: rgba(255, 255, 255, 0.7);
$finished-color: rgba(0, 0, 0, 0.3);
.widget-bamboo-deploy {
background: url("/assets/bamboo-logo.png") no-repeat center;
background-size: contain;
vertical-align: top;
.title {
color: $title-color;
}
.state {
text-align: center;
display: block;
font-weight: 600;
color: $state-color;
font-size: 40px;
word-wrap: break-word;
}
.finished {
color: $finished-color;
position: absolute;
bottom: 24px;
left: 0;
right: 0;
}
.duration {
color: $duration-color;
position: absolute;
bottom: 48px;
left: 0;
right: 0;
}
&.failed {
background-color: $background-failed-color;
}
&.unknown {
background-color: $background-unknown-color;
}
&.success {
background-color: $background-success-color;
}
.aligner {
display: flex;
align-items: center;
justify-content: center;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment