Skip to content

Instantly share code, notes, and snippets.

@dragonai
Last active June 7, 2019 20:09
Show Gist options
  • Save dragonai/a1dae02d476f6055f82a to your computer and use it in GitHub Desktop.
Save dragonai/a1dae02d476f6055f82a to your computer and use it in GitHub Desktop.
Atlassian JIRA Sprint Progress Meter

##Preview

Description

Simple Dashing widget that displays a progress meter for your current JIRA sprint, with the completed and total point values at the bottom.

##Usage

#####Dependencies

Add jira-ruby to the gemfile:

gem 'jira-ruby'

and then just run

$ bundle install

#####Setup

To install this widget, simply run dashing install a1dae02d476f6055f82a.

Then substitute the following placeholders in sprint_progress.rb with the appropriate values:

  • ENV['JIRA_USERNAME'] => your JIRA username (optionally can be placed in your environment variables file
  • ENV['JIRA_PASSWORD'] => your JIRA password (also optionally can be placed in your environment variables file
  • https://your-jira-instance.atlassian.net => the location of your JIRA instance
  • SPRINT_WIDGET_DATA_ID => the target HTML element's data-id attribute in your layout

Finally, to include the widget on a dashboard, drop the following snippet into your layout:

<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
  <div data-view="SprintProgress" data-id="whatever_id_you_like"></div>
</li>
class Dashing.SprintProgress extends Dashing.Widget
@accessor 'value', Dashing.AnimatedValue
constructor: ->
super
@observe 'value', (value) ->
$(@node).find(".meter").val(value).trigger('change')
ready: ->
meter = $(@node).find(".meter")
meter.attr("data-bgcolor", meter.css("background-color"))
meter.attr("data-fgcolor", meter.css("color"))
meter.knob()
<h1 class="title" data-bind="title"></h1>
<input class="meter" data-angleOffset=-125 data-angleArc=250 data-width=200 data-readOnly=true data-bind-value="value | shortenedNumber | append '%'" data-bind-data-min="min" data-bind-data-max="max">
<p class="more-info" data-bind="moreinfo"></p>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require 'jira'
SCHEDULER.every '5m', :first_in => 0 do |job|
client = JIRA::Client.new({
:username => ENV['JIRA_USERNAME'],
:password => ENV['JIRA_PASSWORD'],
:site => "https://your-jira-instance.atlassian.net",
:auth_type => :basic,
:context_path => ""
})
closed_points = client.Issue.jql("sprint in openSprints() and status = \"closed\"").map{ |issue| issue.fields['customfield_10004'] }.reduce(:+) || 0
total_points = client.Issue.jql("sprint in openSprints()").map{ |issue| issue.fields['customfield_10004'] }.reduce(:+) || 0
if total_points == 0
percentage = 0
moreinfo = "No sprint currently in progress"
else
percentage = ((closed_points/total_points)*100).to_i
moreinfo = "#{closed_points.to_i} / #{total_points.to_i}"
end
send_event('SPRINT_WIDGET_DATA_ID', { title: "Sprint Progress", min: 0, value: percentage, max: 100, moreinfo: moreinfo })
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: steelblue;
$title-color: rgba(255, 255, 255, 0.7);
$moreinfo-color: rgba(255, 255, 255, 0.5);
$meter-background: darken($background-color, 7%);
// ----------------------------------------------------------------------------
// Widget-sprint-progress styles
// ----------------------------------------------------------------------------
.widget-sprint-progress {
background-color: $background-color;
input.meter {
background-color: $meter-background;
color: #fff;
}
.title {
color: $title-color;
}
.more-info {
color: $moreinfo-color;
}
.updated-at {
color: rgba(0, 0, 0, 0.3);
}
}
@robertolos
Copy link

I finally fixed the JIRA::HTTPError. Instead of using your email use the username that can be found in your Jira profile

@lhtdesignde
Copy link

lhtdesignde commented Jun 1, 2016

could anyone fix the issue with uncaught exception with undefined method? i adjusted the customfield to the one we use for story points. but seems to still not work. any idea why this is happening?

line 24 is:
percentage = ((closed_points/total_points)*100).to_i

scheduler caught exception: undefined method/' for nil:NilClass
jobs/sprint_progress.rb:24:in block in <top (required)>' .rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:230:incall'
.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:230:in trigger_block' .rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:204:inblock in trigger'
.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/scheduler.rb:430:in call' .rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/scheduler.rb:430:inblock in trigger_job'`

@lhtdesignde
Copy link

after loging this better i'm actually getting a 401 Unauthorized.

@Nachiket26
Copy link

I am getting this error :

bundler: failed to load command: thin (/usr/local/bin/thin)
SyntaxError: /var/lib/gems/1.9.1/gems/jira-ruby-1.4.0/lib/jira/resource/project.rb:30:
syntax error, unexpected tLABEL, expecting ')'
def users(start_at: nil, max_results: nil)
^
/var/lib/gems/1.9.1/gems/jira-ruby-1.4.0/lib/jira/resource/project.rb:30:
Can't assign to nil
def users(start_at: nil, max_results: nil)
^
/var/lib/gems/1.9.1/gems/jira-ruby-1.4.0/lib/jira/resource/project.rb:43:
syntax error, unexpected keyword_end, expecting $end
/var/lib/gems/1.9.1/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in
require' /var/lib/gems/1.9.1/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in require_with_backports'
/var/lib/gems/1.9.1/gems/jira-ruby-1.4.0/lib/jira-ruby.rb:21:in
<top (required)>' /var/lib/gems/1.9.1/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in require'
/var/lib/gems/1.9.1/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in
require_with_backports' /home/bpmuser/test/jobs/sprint_progress.rb:1:in <top (required)>'
/var/lib/gems/1.9.1/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in
require' /var/lib/gems/1.9.1/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in require_with_backports'
/var/lib/gems/1.9.1/gems/smashing-1.0.0/lib/dashing/app.rb:171:in
block in require_glob' /var/lib/gems/1.9.1/gems/smashing-1.0.0/lib/dashing/app.rb:170:in each'
/var/lib/gems/1.9.1/gems/smashing-1.0.0/lib/dashing/app.rb:170:in
require_glob' /var/lib/gems/1.9.1/gems/smashing-1.0.0/lib/dashing/app.rb:181:in <top (required)>'
/var/lib/gems/1.9.1/gems/smashing-1.0.0/lib/dashing.rb:3:in require' /var/lib/gems/1.9.1/gems/smashing-1.0.0/lib/dashing.rb:3:in <top (required)>'
config.ru:1:in require' config.ru:1:in block in

'
/var/lib/gems/1.9.1/gems/rack-1.5.5/lib/rack/builder.rb:55:in instance_eval' /var/lib/gems/1.9.1/gems/rack-1.5.5/lib/rack/builder.rb:55:in initialize'
config.ru:1:in new' config.ru:1:in '
/var/lib/gems/1.9.1/gems/thin-1.6.4/lib/rack/adapter/loader.rb:33:in eval' /var/lib/gems/1.9.1/gems/thin-1.6.4/lib/rack/adapter/loader.rb:33:in load'
/var/lib/gems/1.9.1/gems/thin-1.6.4/lib/thin/controllers/controller.rb:182:in
load_rackup_config' /var/lib/gems/1.9.1/gems/thin-1.6.4/lib/thin/controllers/controller.rb:72:in start'
/var/lib/gems/1.9.1/gems/thin-1.6.4/lib/thin/runner.rb:200:in run_command' /var/lib/gems/1.9.1/gems/thin-1.6.4/lib/thin/runner.rb:156:in run!'
/var/lib/gems/1.9.1/gems/thin-1.6.4/bin/thin:6:in <top (required)>' /usr/local/bin/thin:23:in load'
/usr/local/bin/thin:23:in `<top (required)>'

I am using the smashing plugin for Jenkins status collection and on top of it I installed sprint progress.

Could you please help me on this?

@Pritesh-Patel
Copy link

@Nachiket26 the job file needs to be changed to use require 'jira-ruby' instead of require 'jira'

@azakhary
Copy link

Dose this still work? We are using current story points modern version which does not actually have customfield_10004

@azakhary
Copy link

closed_points = client.Issue.jql("sprint in openSprints() and status = \"resolved\" AND sprint not in futureSprints() AND \"Story Points\">0").map{ |issue| issue.fields['customfield_10012'] }.reduce(:+) || 0 total_points = client.Issue.jql("sprint in openSprints() AND sprint not in futureSprints() AND \"Story Points\">0").map{ |issue| issue.fields['customfield_10012'] }.reduce(:+) || 0

This seems to be working now if anyone needs it

@lhtdesignde
Copy link

i finally got it working with the latest jira version. for me it was the 2 factor auth that kept giving me the 401. after disabling that, it connected.

@phdd
Copy link

phdd commented Mar 11, 2019

The following worked for me

  closed_points = client.Issue.jql("sprint in openSprints() and status in (\"Done\", \"Obsolet\")")
    .map { |issue| issue.fields['customfield_10025'] }
    .select { |points| points != nil }
    .reduce(:+) || 0

  total_points = client.Issue.jql("sprint in openSprints()")
    .map { |issue| issue.fields['customfield_10025'] }
    .select { |points| points != nil }
    .reduce(:+) || 0

@musicbyjing
Copy link

Anyone know a way to query all issues for a specific board with the JIRA API?

@SergioGomez321
Copy link

SergioGomez321 commented Jun 7, 2019

I m getting JIRA::HTTPERROR that is a 401 error, Why is this happening? how can i solve it? help me please!
@lhtdesignde what did you do? :(

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