Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Jenkins build status widget for Dashing

##Preview See images below.

Description

Simple Dashing widget (and associated job) to display the current build status of a Jenkins server. When all jobs are fine a blue background with a thumbs-up icons is shown. When one or more jobs are in a failed state, they are listed on a red background. If culprits are available the user which has broken the build will also be shown. When the Speech Synthesis API is available on the browser it will say one of the predefined texts out loud every 5 minutes. See jenkins_build_status.coffee for the texts and the timeBetweenSounds parameter.

Calls are made to the Jenkins API to retrieve the build status and culprits if they are available.

Please leave a comment below or click on the star if you are using this widget :-)

Installing the widget

Create the folder widgets/jenkins_build_status and put these files in it:

  • jenkins_build_status.coffee
  • jenkins_build_status.html
  • jenkins_build_status.scss

Place the following file in your jobs/ folder:

  • jenkins_build_status.rb

Configuring the widget for use with your Jenkins instance

There are a few parameters that must be set up before using this widget with your Jenkins instance.

In the jenkins_build_status.rb file, modify the following parameters according to your needs:

Parameter Meaning
JENKINS_URI Jenkins base URL
JENKINS_AUTH Jenkins user credentials

Adding the Jenkins build status widget to your dashboard

To add this widget to your dashboard, add the following to your [Dashboard-filename].erb file:

    <li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
      <div data-id="jenkinsBuildStatus" data-view="JenkinsBuildStatus" data-title="Jenkins"></div>
    </li>
class Dashing.JenkinsBuildStatus extends Dashing.Widget
lastPlayed: 0
timeBetweenSounds: 300000
onData: (data) ->
if data.failed
$(@node).find('div.build-failed').show()
$(@node).find('div.build-succeeded').hide()
$(@node).css("background-color", "red")
if 'speechSynthesis' of window
@playSoundForUser data.failedJobs[0].value if Date.now() - @lastPlayed > @timeBetweenSounds
else
$(@node).find('div.build-failed').hide()
$(@node).find('div.build-succeeded').show()
$(@node).css("background-color", "#12b0c5")
playSoundForUser: (user) ->
@lastPlayed = Date.now()
texts = ["#{user} has broken the build.", "The build is broken by #{user}", "#{user} is great, but lacks some programming skills", "Oops, I did it again."]
textNr = Math.floor((Math.random() * texts.length));
@playSound texts[textNr]
playSound: (text) ->
msg = new SpeechSynthesisUtterance(text)
msg.voice = speechSynthesis.getVoices()[0]
speechSynthesis.speak msg
<div class="build-failed">
<h1 class="jenkins-status"><span data-bind="title"></span> FAILED</h1>
<ul class="list-nostyle list-failed">
<li data-foreach-item="failedJobs">
<div class="label" data-bind="item.label"></div>
<div class="value" data-bind="item.value"></div>
</li>
</ul>
</div>
<div class="build-succeeded">
<h1 class="jenkins-status">All <span data-bind="title"></span> builds are successful</h1>
<i class="fa fa-thumbs-o-up"></i>
</div>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require 'net/http'
require 'json'
JENKINS_URI = "http://localhost:8080/"
JENKINS_AUTH = {
'name' => null,
'password' => null
}
SCHEDULER.every '10s' do
json = getFromJenkins(JENKINS_URI + 'api/json?pretty=true')
failedJobs = Array.new
succeededJobs = Array.new
array = json['jobs']
array.each {
|job|
next if job['color'] == 'disabled'
next if job['color'] == 'notbuilt'
next if job['color'] == 'blue'
next if job['color'] == 'blue_anime'
jobStatus = '';
if job['color'] == 'yellow' || job['color'] == 'yellow_anime'
jobStatus = getFromJenkins(job['url'] + 'lastUnstableBuild/api/json')
elsif job['color'] == 'aborted' || job['color'] == 'aborted_anime'
jobStatus = getFromJenkins(job['url'] + 'lastUnsuccessfulBuild/api/json')
else
jobStatus = getFromJenkins(job['url'] + 'lastFailedBuild/api/json')
end
culprits = jobStatus['culprits']
culpritName = getNameFromCulprits(culprits)
if culpritName != ''
culpritName = culpritName.partition('<').first
end
failedJobs.push({ label: job['name'], value: culpritName})
}
failed = failedJobs.size > 0
send_event('jenkinsBuildStatus', { failedJobs: failedJobs, succeededJobs: succeededJobs, failed: failed })
end
def getFromJenkins(path)
uri = URI.parse(path)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
if JENKINS_AUTH['name']
request.basic_auth(JENKINS_AUTH['name'], JENKINS_AUTH['password'])
end
response = http.request(request)
json = JSON.parse(response.body)
return json
end
def getNameFromCulprits(culprits)
culprits.each {
|culprit|
return culprit['fullName']
}
return ''
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #ec663c;
$title-color: rgba(255, 255, 255, 0.7);
$label-color: rgba(255, 255, 255, 0.7);
$value-color: #fff;
// ----------------------------------------------------------------------------
// Widget-text styles
// ----------------------------------------------------------------------------
.widget-jenkins-build-status {
background-color: $background-color;
.title {
color: $title-color;
}
.updated-at {
color: rgba(255, 255, 255, 0.7);
}
ol, ul {
margin: 0 15px;
text-align: left;
color: $label-color;
}
li {
margin-bottom: 5px;
font-size: 40px;
}
.label {
color: $label-color;
}
.value {
margin-left: 12px;
font-weight: 600;
color: $value-color;
}
.updated-at {
color: rgba(0, 0, 0, 0.3);
}
.build-failed {
display: none;
}
.fa {
font-size: 10em;
color: $label-color;
}
}

The MIT License (MIT)

Copyright (c) 2014 David Underwood

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@wp-davisona

This comment has been minimized.

Copy link

wp-davisona commented Feb 12, 2015

To get the correct culprit on build failure, the lines:

if job["color"] != "blue" && job["color"] != "blue_anime"

      jobStatus = getFromJenkins("job/" + job["name"] + "/lastSuccessfulBuild/api/json")
      culprits = jobStatus["culprits"]

should read

if job["color"] != "blue" && job["color"] != "blue_anime"

      jobStatus = getFromJenkins("job/" + job["name"] + "/lastFailedBuild/api/json")
      culprits = jobStatus["culprits"]

Other than that, this is perfect for us! Thanks!

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Feb 12, 2015

Thanks, I updated the gist to use lastFailedBuild.

@estiens

This comment has been minimized.

Copy link

estiens commented Feb 18, 2015

Fails if a Jenkins name includes spaces. I recommend either using the following


jobStatus = getFromJenkins("job/" + name_url_fragment + "/lastFailedBuild/api/json")```

or just grabbing the url parameter from the JSON and using that
@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Feb 20, 2015

It now gets the url from the incoming JSON.
It now also fails on unstable builds instead only on failing builds.

@eimarfandino

This comment has been minimized.

Copy link

eimarfandino commented Feb 26, 2015

i followed all the steps and i still get an error like ["str", [Tilt::StringTemplate]]....

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Feb 27, 2015

Hi eimarfandino.
This error happens when the widget filenames do not match with the directory they are in. I changed the description so they will match now.

@ChethanaPuneeth

This comment has been minimized.

Copy link

ChethanaPuneeth commented Mar 9, 2015

Hi joepadmiraal,
I tried to include this widget to get Jenkins feed in our dashboard, but we are stuck with coffee script file. Whenever i include any single line in Jenkins_build_status.coffee, nothing is displaying in dashboard and its displaying as " All Jenkins builds are successful". It is not checking for condition.

Getting error
"scheduler caught exception:
undefined method `request_uri'"

Please guide on how to overcome this issue.What changes need to be done to get rid of this error..

Thanks and Regards,
Chethana Puneeth

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Mar 10, 2015

This could be caused by a non http/https uri.
How did you specify the JENKINS_URI?

@ChethanaPuneeth

This comment has been minimized.

Copy link

ChethanaPuneeth commented Mar 11, 2015

JENKINS_URI="http://172.19.82.14:8090/" where 172.19.82.14 is the Jenkins server IP and port number is 8090

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Mar 11, 2015

That seems ok.
Can you supply some more info about your environment so I can try to reproduce the issue?

@sbange

This comment has been minimized.

Copy link

sbange commented Mar 12, 2015

Hi Joe,

I'm trying to get this to run on Mac OS X (Yosemite) with Ruby 2.0, gem 2.4.6 and Bundler 1.8.5. The following error occurs:

/Library/Ruby/Gems/2.0.0/gems/backports-3.6.4/lib/backports/std_lib.rb:9:in require': cannot load such file -- httpclient (LoadError) from /Library/Ruby/Gems/2.0.0/gems/backports-3.6.4/lib/backports/std_lib.rb:9:inrequire_with_backports'
from /Users/sbange/workspaces/dashboards/fricke/jobs/jenkins_build_status.rb:1:in <top (required)>' from /Library/Ruby/Gems/2.0.0/gems/backports-3.6.4/lib/backports/std_lib.rb:9:inrequire'
from /Library/Ruby/Gems/2.0.0/gems/backports-3.6.4/lib/backports/std_lib.rb:9:in `require_with_backports'

I'm new to ruby, I tried "gem install httpclient" and "bundler install", which both worked fine, but the error persists. Any ideas how to move on?

Thanks and Regards,
Sven.

@sbange

This comment has been minimized.

Copy link

sbange commented Mar 13, 2015

Figured it out: I did not add httpclient to the Gemfile. Nice widget, thanks!

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Mar 13, 2015

Ah great, I will update the gist with this info.

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Mar 17, 2015

sbange, the httpclient is now removed from the job file as it was not used.

@gambastian

This comment has been minimized.

Copy link

gambastian commented Apr 8, 2015

Hi Joe, (Thanks by the way)

I'm having the same problem described by ChethanaPuneeth, did you solve it? My widget keeps saying "All Jenkins builds are successful" with orange background, but in the log:

scheduler caught exception:
getaddrinfo: Name or service not known
/usr/lib/ruby/1.9.1/net/http.rb:763:in initialize' /usr/lib/ruby/1.9.1/net/http.rb:763:inopen'
/usr/lib/ruby/1.9.1/net/http.rb:763:in block in connect' /usr/lib/ruby/1.9.1/timeout.rb:55:intimeout'
/usr/lib/ruby/1.9.1/timeout.rb💯in timeout' /usr/lib/ruby/1.9.1/net/http.rb:763:inconnect'
/usr/lib/ruby/1.9.1/net/http.rb:756:in do_start' /usr/lib/ruby/1.9.1/net/http.rb:745:instart'
/usr/lib/ruby/1.9.1/net/http.rb:1285:in request' /home/dev/git/dashboard/jobs/jenkins_build_status.rb:66:ingetFromJenkins'
/home/dev/git/dashboard/jobs/jenkins_build_status.rb:13:in block in <top (required)>' /var/lib/gems/1.9.1/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:230:incall'
/var/lib/gems/1.9.1/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:230:in trigger_block' /var/lib/gems/1.9.1/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:204:inblock in trigger'
/var/lib/gems/1.9.1/gems/rufus-scheduler-2.0.24/lib/rufus/sc/scheduler.rb:430:in call' /var/lib/gems/1.9.1/gems/rufus-scheduler-2.0.24/lib/rufus/sc/scheduler.rb:430:inblock in trigger_job'

Thanks
Sebastian

@gambastian

This comment has been minimized.

Copy link

gambastian commented Apr 8, 2015

Hi Again,

I found the problem, in my case the Jenkins configurations replaced the jenkins host for localhost (I saw this making a get request to the json api : http://jenkins_HOST:jenkins_PORT/api/json?pretty=true) in the jobs urls, so in the begining it connected successfully to the host when looking for jobs, but when it tried to retrieve the job status it was trying to reach a jenkins in localhost.

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Apr 13, 2015

Hi gambastian, thanks for the info.
I will see if I can add some kind of error message which describes what's going on.

@larrycai

This comment has been minimized.

Copy link

larrycai commented Apr 14, 2015

If https, then need below codes

http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE 
@larrycai

This comment has been minimized.

Copy link

larrycai commented Apr 14, 2015

JENKINS_URI actually works for Jenkins View as well, which help you to monitor one group of jobs instead of all jobs from one jenkins instance

@larrycai

This comment has been minimized.

Copy link

larrycai commented Apr 14, 2015

Can we have title in the widget ? (so it is jenkins view, it will be better to show view name in title)

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Apr 17, 2015

@larrycai, I updated the html to use the data-title from the dashboard.erb file.

@ghost

This comment has been minimized.

Copy link

ghost commented May 5, 2015

I cannot get this to work for HTTPS. I just get the "All jenkins builds are sucessful" message

@lethe3000

This comment has been minimized.

Copy link

lethe3000 commented May 15, 2015

hi, if I have tow jenkins servers to show, which is the correct approach?
I simply copy jenkins_build_status.rb to jenkins_build_status-2.rb
and modify the name of JENKINS_URI, JENKINS_AUTH to JENKINS_URI_2 and JENKINS_AUTH_2,but met such error:

/usr/local/rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.7/lib/eventmachine.rb:526:in start_tcp_server': no acceptor (port is in use or requires root privileges) (RuntimeError) from /usr/local/rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.7/lib/eventmachine.rb:526:instart_server'
from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/lib/thin/backends/tcp_server.rb:16:in connect' from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/lib/thin/backends/base.rb:63:inblock in start'
from /usr/local/rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in call' from /usr/local/rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:inrun_machine'
from /usr/local/rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in run' from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/lib/thin/backends/base.rb:73:instart'
from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/lib/thin/server.rb:162:in start' from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/lib/thin/controllers/controller.rb:87:instart'
from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/lib/thin/runner.rb:200:in run_command' from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/lib/thin/runner.rb:156:inrun!'
from /usr/local/rvm/gems/ruby-2.1.2/gems/thin-1.6.3/bin/thin:6:in <top (required)>' from /usr/local/rvm/gems/ruby-2.1.2/bin/thin:23:inload'
from /usr/local/rvm/gems/ruby-2.1.2/bin/thin:23:in <main>' from /usr/local/rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:ineval'
from /usr/local/rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:in `

'

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented May 29, 2015

@aspence7 Please provide some more information. What do the logs say. Did you follow the tip from larrycai?

@larrycai

This comment has been minimized.

Copy link

larrycai commented Aug 19, 2015

Hi Joe:

Curious to know where is fa-thumbs-o-up, how can I see the thumb icon ?

@bemosior

This comment has been minimized.

Copy link

bemosior commented Aug 20, 2015

Thanks for sharing this, @joepadmiraal!

Found a minor bug. Line 29 of jenkins_build_status.rb should probably accommodate the aborted_anime "color", as it's the state entered when an aborted build becomes in-progress again:

elsif job['color'] == 'aborted' || job['color'] == 'aborted_anime'

@bemosior

This comment has been minimized.

Copy link

bemosior commented Aug 20, 2015

@larrycai: The Font Awesome icon set is used: https://fortawesome.github.io/Font-Awesome/icons/

@meichau

This comment has been minimized.

Copy link

meichau commented Oct 9, 2015

Thanks for sharing this @joepadmiraal.

Since you unfortunately didn't provide a license file with it: could you make clear under which license this project has been provided? Did you intend to use the MIT as given in the Dashing dashboard itself? Or anything else?

Thanks for any clarification.

@bean5

This comment has been minimized.

Copy link

bean5 commented Oct 27, 2015

@joepadmiraal Could you ad a license to this? It might be the only thing keeping it from being merged in...is that right @meichau.

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Nov 12, 2015

@bemosior Thanks for sharing the fix. I will update the script.
@meichau I'll add the MIT license

@meichau

This comment has been minimized.

Copy link

meichau commented Dec 16, 2015

@joepadmiraal Great, thanks.

@ch0wdan

This comment has been minimized.

Copy link

ch0wdan commented Jan 21, 2016

@joepadmiraal - My jenkins server is behind Okta integration. Due to this, running a redirect to Okta signin occurs, which triggers an exception of the widget. Ideas/tips on how to account for this?

scheduler caught exception:
757: unexpected token at '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
                                        <meta http-equiv="content-type" content="text/html; charset=utf-8">
                                        <title>Redirect</title>
                                </head><body><h1>Redirect</h1><p>You were redirected to: <a id="redirlink" href=
@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Jan 29, 2016

@ch0wdan Looking at your exception it seems like Otwa is returning a normal html page for its redirect. So there is no way for me to create a generic redirect function for this. I guess you would have to parse the html response yourself in the jenkins_build_status.rb file and use the link from redirlink to connect to your Jenkins server.

@ziadvictor

This comment has been minimized.

Copy link

ziadvictor commented Jun 14, 2016

I got this in the console:
"You're speaking plain HTTP to an SSL-enabled server port."
Where should I put these lines for HTTPS ?
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

@joepadmiraal

This comment has been minimized.

Copy link
Owner Author

joepadmiraal commented Jun 15, 2016

@ziadvictor
This could be placed below:

http = Net::HTTP.new(uri.host, uri.port)

after line 53.

@levsa

This comment has been minimized.

Copy link

levsa commented Sep 26, 2016

Default values for JENKINS_AUTH['name'] and JENKINS_AUTH['password'] should be nil, null is not a valid ruby value.

@dramamask

This comment has been minimized.

Copy link

dramamask commented Apr 13, 2017

jenkins_build_status.rb needs the following line:

next if job['color'].nil?

Because jobs of the 'jenkins.branch.OrganizationFolder' do not have a color.

@ak-roche

This comment has been minimized.

Copy link

ak-roche commented Jan 18, 2018

@joepadmiraal thank you.

I would like to monitor specific jobs on my jenkins server -- currently is shows all jobs on my server

ie one release of our product consists of 3 jenkins jobs out of the many we have running.

I would also like to include the iframe widget to show our sonar status of the above 3 git repositories.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.