Skip to content

Instantly share code, notes, and snippets.

@mavimo mavimo/Readme.md forked from steintore/Readme.md
Last active Jul 29, 2019

Embed
What would you like to do?

Description

Dashing widget to display a Jenkins build status and build progress

The widget is based on the meter-widget which is default in the Dashing installation

The widget can also see the progress of a "pre-build", i.e if you have a job triggering the actual build you want to define, you can configure this job in the jenkins_build.rb as a prebuild.

For more information, please see Coding Like a tosser

Installation

Put the files jenkins_build.coffee, jenkins_build.html and jenkins_build.scss goes in the /widget/jenkins_build directory and the jenkins_build.rb in the /jobs directory

Otherwise you can install this plugin typing:

dashing install GIST_ID

Usage (jenkins_build.rb)

Change the JENKINS_URI to your correct uri for Jenkins, eg.:

JENKINS_URI = URI.parse("http://ci.yourserver.com")

Add jenkins credential (if required) in JENKINS_AUTH, eg.:

JENKINS_AUTH = {
  'name' => 'username',
  'password' => 'password'
}

Put all the jobnames and pre job names in the job_mapping, eg.:

job_mapping = {
  'job1' => { :job => 'Job Name 1'},
  'job2' => { :job => 'Job Name 2', :pre_job => 'Job Name 3'},
}

Put the following in your dashingboard.erb file to show the status:

<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
  <div data-id="job1" data-view="JenkinsBuild" data-title="Build title" data-description="A little description of build" data-min="0" data-max="100"></div>
</li>

Multiple jobs can add in dashboard repeating the snippet and changing data-id in accord with job name specified in job_mapping. Widget support title and description via data attributes, this attributest can be omitted if you do not like to display this information.

class Dashing.JenkinsBuild extends Dashing.Widget
@accessor 'value', Dashing.AnimatedValue
@accessor 'bgColor', ->
if @get('currentResult') == "SUCCESS"
"#96bf48"
else if @get('currentResult') == "FAILURE"
"#D26771"
else if @get('currentResult') == "PREBUILD"
"#ff9618"
else
"#999"
constructor: ->
super
@observe 'value', (value) ->
$(@node).find(".jenkins-build").val(value).trigger('change')
ready: ->
meter = $(@node).find(".jenkins-build")
$(@node).fadeOut().css('background-color', @get('bgColor')).fadeIn()
meter.attr("data-bgcolor", meter.css("background-color"))
meter.attr("data-fgcolor", meter.css("color"))
meter.knob()
onData: (data) ->
if data.currentResult isnt data.lastResult
$(@node).fadeOut().css('background-color', @get('bgColor')).fadeIn()
<h2 class="title" data-bind="title"></h2>
<input class="jenkins-build" data-angleOffset=-125 data-angleArc=250 data-width=200 data-readOnly=true data-bind-value="value | shortenedNumber" data-bind-data-min="min" data-bind-data-max="max">
<p class="more-info" data-bind="description"></p>
<p class="last-built" data-bind="lastBuilt"></p>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require 'net/http'
require 'json'
require 'time'
JENKINS_URI = URI.parse("http://localhost:8080")
JENKINS_AUTH = {
'name' => nil,
'password' => nil
}
# the key of this mapping must be a unique identifier for your job, the according value must be the name that is specified in jenkins
job_mapping = {
'JOB' => { :job => 'BUILD', :pre_job => 'PRE_BUILD'}
}
def get_number_of_failing_tests(job_name)
info = get_json_for_job(job_name, 'lastCompletedBuild')
info['actions'][4]['failCount']
end
def get_completion_percentage(job_name)
build_info = get_json_for_job(job_name)
prev_build_info = get_json_for_job(job_name, 'lastCompletedBuild')
return 0 if not build_info["building"]
last_duration = (prev_build_info["duration"] / 1000).round(2)
current_duration = (Time.now.to_f - build_info["timestamp"] / 1000).round(2)
return 99 if current_duration >= last_duration
((current_duration * 100) / last_duration).round(0)
end
def get_json_for_job(job_name, build = 'lastBuild')
job_name = URI.encode(job_name)
http = Net::HTTP.new(JENKINS_URI.host, JENKINS_URI.port)
request = Net::HTTP::Get.new("/job/#{job_name}/#{build}/api/json")
if JENKINS_AUTH['name']
request.basic_auth(JENKINS_AUTH['name'], JENKINS_AUTH['password'])
end
response = http.request(request)
JSON.parse(response.body)
end
job_mapping.each do |title, jenkins_project|
current_status = nil
SCHEDULER.every '10s', :first_in => 0 do |job|
last_status = current_status
build_info = get_json_for_job(jenkins_project[:job])
current_status = build_info["result"]
if build_info["building"]
current_status = "BUILDING"
percent = get_completion_percentage(jenkins_project[:job])
elsif jenkins_project[:pre_job]
pre_build_info = get_json_for_job(jenkins_project[:pre_job])
current_status = "PREBUILD" if pre_build_info["building"]
percent = get_completion_percentage(jenkins_project[:pre_job])
end
send_event(title, {
currentResult: current_status,
lastResult: last_status,
timestamp: build_info["timestamp"],
value: percent
})
end
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #4b5f24;
$title-color: rgba(255, 255, 255, 1);
$moreinfo-color: rgba(255, 255, 255, 0.7);
$meter-background: rgba(20, 20, 20, 1);
// ----------------------------------------------------------------------------
// Widget-jenkins-build styles
// ----------------------------------------------------------------------------
.widget-jenkins-build {
background-color: $background-color;
input.jenkins-build {
background-color: $meter-background;
color: #fff;
}
.title {
color: $title-color;
}
.more-info {
color: $moreinfo-color;
}
.updated-at {
color: rgba(0, 0, 0, 1);
}
}
@rdohms

This comment has been minimized.

Copy link

commented Oct 11, 2013

You have a bug here: https://gist.github.com/mavimo/6334816#file-jenkins_build-rb-L36

This line should read request = Net::HTTP::Get.new("/job/#{job_name}/#{build}/api/json")

Otherwise you get "undefined method `set_body_internal’ for #" errors.

@byteme206

This comment has been minimized.

Copy link

commented Oct 18, 2013

TIP: If you're accessing Jenkins via https, you'll also need to add the following two lines immediately following request = Net::HTTP::Get.new("/job/#{job_name}/#{build}/api/json"):
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

@bitle

This comment has been minimized.

Copy link

commented Feb 25, 2014

Can you add screenshots please?

@bhaku

This comment has been minimized.

Copy link

commented Mar 6, 2014

Can you correct the error found by @rdohms ?

@softweardev

This comment has been minimized.

@mavimo

This comment has been minimized.

Copy link
Owner Author

commented Oct 31, 2014

@bhaku @rdohms fixed.

@TinajaLabs

This comment has been minimized.

Copy link

commented Jan 22, 2015

Anyone have any tips about how to narrow this down to a single widget that indicates if there are any current build failures? We have about 30 active projects and trying to watch them all in one page... the widgets are too big to see them all at a glance. We really only need to have a single high level indication of any fails... which will alert us to investigate further. Thanks, Chris.

@joepadmiraal

This comment has been minimized.

Copy link

commented Feb 6, 2015

@TinajaLabs I just added our Jenkins Build Status widget which does exactly what you want.

@ghost

This comment has been minimized.

Copy link

commented May 5, 2015

I still cannot get this to work when using HTTPS for jenkins. I just get a widget displayed with 0

@xastarothx

This comment has been minimized.

Copy link

commented May 29, 2015

If Jenkins has his own context and uses https you have to replace get_json_for_job with:

def get_json_for_job(job_name, build = 'lastBuild')
  job_name = URI.encode(job_name)
  http = Net::HTTP.new(JENKINS_URI.host, JENKINS_URI.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  request = Net::HTTP::Get.new(JENKINS_URI.path + "/job/#{job_name}/#{build}/api/json")
  if JENKINS_AUTH['name']
    request.basic_auth(JENKINS_AUTH['name'], JENKINS_AUTH['password'])
  end
  response = http.request(request)
  JSON.parse(response.body)
end
@slipstream1

This comment has been minimized.

Copy link

commented Jul 13, 2015

@aspence7
check your dashingboard.erb and make sure <div data-id="job1" matches the job name in jenkins_build.rb job_mapping = {
'JOB'

code says JOB but the example at the tope says job1

@spudtheimpaler

This comment has been minimized.

Copy link

commented Dec 4, 2015

The "Coding like a tosser" link is no longer valid

@aditeedesale

This comment has been minimized.

Copy link

commented May 22, 2017

Hi guys, can anyone suggest how to show recent 10 changes in a specific job in jenkins to dashing

@ChrisWeissNike

This comment has been minimized.

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.