CruiseControl Progress Charts

by Phlip

CruiseControl.rb, by ThoughtWorks, is an elegant Continuous Integration dashboard for Ruby projects. This article shows how to call the RoR command "rake stats" once per build, capture the results, and chart them to track trends over time.

Our goal is this chart:

cc_gnuplot.png

9 Comments

bryanl
2008-03-18 08:38:28
You don't have to bounce the whole server. All you really might have to do is restart your builder processes.
Phlip
2008-03-18 08:47:35
tx. Got a link to a page describing that feature?
johanvdb
2008-03-18 13:46:28
Here's a little contraption I made for our CCrb implementation at my work (shameless plug):
http://www.vandenbrande.com/twiki/bin/view/Johanvdb/ExtremeFeedbackDevice


For our 'dashboard', which lives outside of CCrb, we populate an SQLite DB from the build script and use a nifty ruby cgi script to chart it all using tables and css...

Phlip
2008-03-18 15:10:24
"...an SQLite..."


The International Standards Organization has requested we pronounce "SQL" like "ess-queue-ell". I approve of your grammatic compliance, but feel compelled to advise the committee(s) that I personally will continue to pronounce it "squirrel".

Sergey Pashin
2008-03-21 17:41:32
Here is an example of how build statistics charts look like in commercial systems (Parabuild in our case):


http://www.viewtier.com/products/parabuild/screenshots/screen_shot_statistics.htm


Serge

Phlip
2008-03-22 07:12:51
Tx. That chart shows passing builds-per-day over failing builds-per-day, revealling the weekly work cycle. I suspect my system censors failing builds, and only shows the metrics for passing builds.


I want a system that lets me add a metric tool, such as 'rcov' or a cyclic redundancy check, and it will add these to the chart. (Ideally, test coverage should go up while the CRC goes down.)


Further, the script should go back in time, with the version controller, and collects these metrics retroactively.

Sean
2008-04-22 10:56:47
I'm having trouble getting this to run correctly. When I go to http://localhost:3333/projects/statistics/my_project, I get an error:


Processing ProjectsController#statistics (for 63.251.131.253 at 2008-04-22 12:54:05) [GET]
Parameters: {"action"=>"statistics", "id"=>"my_project", "controller"=>"projects"}



NoMethodError (undefined method `[]' for nil:NilClass):
.//app/models/project.rb:531:in `fetch_codelines'
.//app/models/project.rb:531:in `map'
.//app/models/project.rb:531:in `fetch_codelines'
.//app/models/project.rb:581:in `gnu_plot_stats'
.//app/models/project.rb:577:in `map'
.//app/models/project.rb:577:in `gnu_plot_stats'
.//app/models/project.rb:574:in `map'
.//app/models/project.rb:574:in `gnu_plot_stats'
/usr/local/lib/ruby/gems/1.8/gems/gnuplot-2.2/lib/gnuplot.rb:77:in `initialize'
.//app/models/project.rb:552:in `new'
.//app/models/project.rb:552:in `gnu_plot_stats'
/usr/local/lib/ruby/gems/1.8/gems/gnuplot-2.2/lib/gnuplot.rb:59:in `open'
/usr/local/lib/ruby/gems/1.8/gems/gnuplot-2.2/lib/gnuplot.rb:59:in `popen'
/usr/local/lib/ruby/gems/1.8/gems/gnuplot-2.2/lib/gnuplot.rb:59:in `open'
.//app/models/project.rb:551:in `gnu_plot_stats'
.//app/controllers/projects_controller.rb:8:in `statistics'
.//vendor/rails/actionpack/lib/action_controller/base.rb:1095:in `send'
.//vendor/rails/actionpack/lib/action_controller/base.rb:1095:in `perform_action_without_filters'
.//vendor/rails/actionpack/lib/action_controller/filters.rb:632:in `call_filter'
.//vendor/rails/actionpack/lib/action_controller/filters.rb:619:in `perform_action_without_benchmark'
.//vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
/usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
.//vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
.//vendor/rails/actionpack/lib/action_controller/rescue.rb:83:in `perform_action'
.//vendor/rails/actionpack/lib/action_controller/base.rb:430:in `send'
.//vendor/rails/actionpack/lib/action_controller/base.rb:430:in `process_without_filters'
.//vendor/rails/actionpack/lib/action_controller/filters.rb:624:in `process_without_session_management_support'
.//vendor/rails/actionpack/lib/action_controller/session_management.rb:114:in `process'
.//vendor/rails/actionpack/lib/action_controller/base.rb:330:in `process'
.//vendor/rails/railties/lib/dispatcher.rb:41:in `dispatch'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:78:in `process'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:76:in `synchronize'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:76:in `process'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:618:in `process_client'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:617:in `each'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:617:in `process_client'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `initialize'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `new'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:720:in `initialize'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:720:in `new'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:720:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/configurator.rb:271:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/configurator.rb:270:in `each'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/configurator.rb:270:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:127:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/command.rb:211:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:243
.//vendor/rails/activesupport/lib/active_support/dependencies.rb:488:in `load'
.//vendor/rails/activesupport/lib/active_support/dependencies.rb:488:in `load'
.//vendor/rails/activesupport/lib/active_support/dependencies.rb:342:in `new_constants_in'
.//vendor/rails/activesupport/lib/active_support/dependencies.rb:488:in `load'
.//vendor/rails/railties/lib/commands/servers/mongrel.rb:60
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
.//vendor/rails/activesupport/lib/active_support/dependencies.rb:495:in `require'
.//vendor/rails/activesupport/lib/active_support/dependencies.rb:342:in `new_constants_in'
.//vendor/rails/activesupport/lib/active_support/dependencies.rb:495:in `require'
.//vendor/rails/railties/lib/commands/server.rb:40
./script/server:42:in `require'
./script/server:42
./cruise:6:in `load'
./cruise:6:in `start'
./cruise:68:in `send'
./cruise:68
/usr/local/lib/ruby/1.8/fileutils.rb:121:in `chdir'
/usr/local/lib/ruby/1.8/fileutils.rb:121:in `cd'
./cruise:67



PJ
2008-04-23 11:13:11
@Sean -- I had the same issue -- turns out it was trying to collect data from components, which I wasn't using. Check the ALL_CODE constant and delete anything you're not getting data for, or just change fetch_codelines to ignore nils.
Sean
2008-04-25 06:44:29
@PJ - That was it! Thanks!