Skip to content

Instantly share code, notes, and snippets.

@joepadmiraal
Last active December 21, 2020 16:41
Show Gist options
  • Save joepadmiraal/33e0c2a7a7b00cc2e0aa to your computer and use it in GitHub Desktop.
Save joepadmiraal/33e0c2a7a7b00cc2e0aa to your computer and use it in GitHub Desktop.
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.

@joepadmiraal
Copy link
Author

@ziadvictor
This could be placed below:

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

after line 53.

@levsa
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
Copy link

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
Copy link

@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