Instantly share code, notes, and snippets.

What would you like to do?
Circle CI Build Status widget for Dashing (Single Builds)


Dashing widget to show the build status of a CircleCI project.


  • Get a Circle API Token from your Account Dashboard and set it in your environment as CIRCLE_CI_AUTH_TOKEN
  • Add the httparty to your Gemfile and run bundle install


  1. Copy the below coffee/scss/html files into a widget folder named circle_ci
  2. Copy the circle_ci.rb file into the jobs folder

OR dashing install 5494978

Then copy the CircleCI logo below into your assets folder

CircleCI Dashing Widget

There is also another version for more compactly displaying multiple builds which you can see here

class Dashing.CircleCi extends Dashing.Widget
onData: (data) ->
_checkStatus: (status) ->
$(@node).removeClass('failed pending passed')
<h1 class="title" data-bind="title"></h1>
<img class="background" src="/assets/logo-circle-ci.png">
<span class="label small" data-bind="build_id"></span>
<div class="commit-info">
<img data-bind-src="avatar_url" />
<span class="label committer-name" data-bind="committer_name"></span>
<span class="label small commit-body" data-bind="commit_body"></span>
<div class="clearfix"></div>
<h2 class="state" data-bind="state"></h2>
<span class="label small" data-bind="time"></span>
<p class="more-info" data-bind="moreinfo"></p>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require 'httparty'
require 'digest/md5'
projects = [
{ user: 'MY_GITHUB_USER_OR_ORG', repo: 'XXX', branch: 'master' },
{ user: 'MY_GITHUB_USER_OR_ORG', repo: 'YYY', branch: 'dev' },
def duration(time)
secs = time.to_int
mins = secs / 60
hours = mins / 60
days = hours / 24
if days > 0
"#{days}d #{hours % 24}h ago"
elsif hours > 0
"#{hours}h #{mins % 60}m ago"
elsif mins > 0
"#{mins}m #{secs % 60}s ago"
elsif secs >= 0
"#{secs}s ago"
def calculate_time(finished)
finished ? duration( - Time.parse(finished)) : "--"
def translate_status_to_class(status)
statuses = {
'success' => 'passed',
'fixed' => 'passed',
'running' => 'pending',
'failed' => 'failed'
statuses[status] || 'pending'
def build_data(project, auth_token)
api_url = ''
api_url = api_url % [project[:user], project[:repo], project[:branch], auth_token]
api_response = HTTParty.get(api_url, :headers => { "Accept" => "application/json" } )
api_json = JSON.parse(api_response.body)
return {} if api_json.empty?
latest_build ={ |build| build['status'] != 'queued' }.first
email_hash = Digest::MD5.hexdigest(latest_build['committer_email'])
build_id = "#{latest_build['branch']}, build ##{latest_build['build_num']}"
data = {
build_id: build_id,
repo: "#{project[:repo]}",
branch: "#{latest_build['branch']}",
time: "#{calculate_time(latest_build['stop_time'])}",
state: "#{latest_build['status'].capitalize}",
widget_class: "#{translate_status_to_class(latest_build['status'])}",
committer_name: latest_build['committer_name'],
commit_body: "\"#{latest_build['body']}\"",
avatar_url: "{email_hash}"
return data
SCHEDULER.every '10s', :first_in => 0 do
projects.each do |project|
data_id = "circle-ci-#{project[:user]}-#{project[:repo]}-#{project[:branch]}"
data = build_data(project, ENV['CIRCLE_CI_AUTH_TOKEN'])
send_event(data_id, data) unless data.empty?
$state-color: #FFF;
$background-color: #8fb347;
$background-error-color: #A31F1F;
$background-passed-color: #8fb347;
$background-pending-color: #47bbb3;
$title-color: rgba(255, 255, 255, 1);
$label-color: rgba(255, 255, 255, 0.7);
$moreinfo-color: rgba(255, 255, 255, 0.7);
background-color: $background-color;
vertical-align: top;
img.background {
width: 100% !important;
position: absolute;
left: 0;
top: 30px;
opacity: 0.05;
.committer-info {
margin: 10px 0px;
padding: 5px;
background: rgba(255, 255, 255, 0.3);
img {
.label {
text-align: left;
padding-left: 90px;
font-size: 20px;
&.small {
font-size: 14px;
.title {
color: $title-color;
ol, ul {
margin: 0 15px;
text-align: left;
color: $label-color;
ol {
list-style-position: inside;
li {
margin-bottom: 5px;
.list-nostyle {
list-style: none;
.label {
text-align: center;
display: block;
color: $label-color;
font-size: 24px;
word-wrap: break-word;
&.small {
font-size: 18px;
.state {
text-align: center;
display: block;
font-weight: 600;
color: $state-color;
font-size: 40px;
word-wrap: break-word;
.updated-at {
color: rgba(0, 0, 0, 0.3);
.more-info {
color: $moreinfo-color;
&.failed {
background-color: $background-error-color;
&.pending {
background-color: $background-pending-color;
&.passed {
background-color: $background-passed-color;

This comment has been minimized.

joergrech commented May 4, 2013

Does this widget still work? I get the following error every activation of circle-ci.rb:

scheduler caught exception:

can't convert String into Integer
.../dashing_dashboard/jobs/circle_ci.rb:50:in `[]'

Refering to the line:

email_hash = Digest::MD5.hexdigest(latest_build['committer_email'])

And on startup I get from circle_ci.rb (I installed both your widgets):

.../dashing_dashboard/jobs/circle_ci_list.rb:4: warning: already initialized constant PROJECTS

Btw: before getting so far I needed to specify the gem "httparty" in my gemfile and call "bundle install".


This comment has been minimized.


petehamilton commented May 21, 2013

HTTParty should be a dependency, apologies for not adding that to the README, will do that now.

For the error on line 50, I'm not entirely sure why that's being caused. latest_build should be a valid hash and 'committer_email' should be a valid index. Could you debug the response from CircleCI, anonymise and post?

PROJECTS is being reinitialised because I used a constant. I will update it to be a lowercase variable projects instead, should still work fine, but remove the conflict.


This comment has been minimized.

gaelrottier commented Jun 27, 2013

When I try to get the CircleCI logo, I get a 403 error page, is the logo private ?


This comment has been minimized.

camswords commented Aug 8, 2013

I'm having the same error on line 50 can't convert String into Integer.

The response that fails to parse has the contents:

"message" : "You must log in first."


This comment has been minimized.

camswords commented Aug 8, 2013

I fixed the log in error by logging out, logging back in and creating a new api key. I don't really understand why circle ci's rest api didn't work the first time for me.


This comment has been minimized.

camswords commented Aug 8, 2013

Also make sure you change the projects on line 4 of circle_ci.rb to your specific project settings.


This comment has been minimized.

wcamarao commented Aug 30, 2013

This is great. Thanks @petehamilton!

Same here as @camswords - on Circle CI I needed to logout, login and regen an api token.

Now I'm thinking if I'm missing something. The projects hash contains enough data to build a dashboard .erb for circle, rendering one li element for each project. Is that handled by some code already?


This comment has been minimized.

burly commented Nov 17, 2013

Hi @petehamilton!

I have a pipeline with 3 stages in, I'd like to have 3 widgets to display the status of each stage (if it's been ran). Is this possible/easy to do with this?



This comment has been minimized.

bradrobertson commented Mar 5, 2014

works great! FYI, I found that the commit body was always blank, but subject is populated with the commit msg. Not sure if that's a change to the CircleCI api.


This comment has been minimized.

machadolab commented Sep 17, 2014

You might document how to set the data-id attribute on the dashboard widget. I had to dig into the job to find its name must be:



This comment has been minimized.

jjgs commented Mar 30, 2016

Example dashboard.erb file:

<% content_for(:title) { "Build Status" } %>
<div class="gridster">
    <li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
      <div data-id="circle-ci-USER-PROJECT-BRANCH" data-view="CircleCi" data-title="Foo Project"></div>

This comment has been minimized.

joergrech commented Jun 23, 2016

Info: The commit message isn't shown anymore. Maybe CircleCI change something in their API?


This comment has been minimized.

nekocentral commented Nov 13, 2017

How hard would it be to make a version of this for ?


This comment has been minimized.

jeromelachaud commented Jan 22, 2018

in circle_ci.rb:
line 41, should be: api_url = ''
and line 59: commit_body: "\"#{latest_build['subject']}\""

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment