Rally Defect state tracking:
The company I work for has many Scrum teams using Rally to track their sprint progress. Each team has it’s own project in Rally. For defects loaded as part of a sprint, the ScheduleState field is useful for tracking sprint progress (i.e. Defined, In-Progress, Completed, or Accepted). We’ve also found that the Defect State field is useful to track defect information outside of sprints (either when a defect has not yet been loaded or has already been reviewed in a prior sprint).
Rally offers two fixed State values – Open and Closed – but allows project administrators to add additional custom State values that can then be assigned. We have created about a dozen different values including “As Designed”, “Is Duplicate”, “Cannot Reproduce”, “Rejected”, etc. In essence, we’ve setup a many-to-one State-to-ScheduleState relationship protocol that we’ve asked our developers to use.
The problem is that the process is complicated. Developers get confused as to which field to update (“Should we update ScheduleState or State? What’s the difference between the two fields?“) Even the developers who update both fields don’t necessarily always get it right. For instance – mismatches like setting ScheduleState:Defined and State:Complete occur. There is no way in the Rally UI to tie the State and ScheduleState fields together and automatically keep them correctly synchronized.
Since Rally offers a RESTful API (see Updating Rally via Ruby), I have written a script that runs at a regular interval in the background that synchronizes Defect State and ScheduleState fields for specific projects. Developers are now asked to only update a defect’s State field. The script then keeps all Defect ScheduleStates up-to-date. Additionally, for each time a ScheduleState is changed, a message is added to the defect’s Notes field containing a timestamp and and what changed. For example:
2013-07-14 20:20:04: ScheduleState auto-updated – State: “Closed”, ScheduleState “In-Progress” => “Accepted”
This helps alleviate any confusion the developer may have on any changes that were made.
I saw that Rally offered SDKs to it’s RESTful API for .NET, Ruby, and Java. I’ve created some basic Rails apps in the past, so I wanted to explore their Ruby interface more. I could have just stuck with a simple Ruby script that updates defects every time it is run, but I knew that I better add some sort of logging to it, too. There is no doubt that an engineer or manager will eventually visit me and say “your script did X!” where X is something bad. I want to be able to pull up a log and say “yes, it did X because…” and be able to explain why. Plus, a decent log helps to audit that the script is working correctly. Sure, I could have just opened a text file and piped messages to it, but where’s the fun in that? Since I’m using Rally’s Ruby SDK already, why not create a Rails app that not only updates Rally, but creates and stores DefectUpdateRecords in a simple sqlite database for each change it makes? That way, it can display a nice web page showing all changes that were made as well as HTML links directly to the modified defects in Rally.
So I setup a Ubuntu Desktop virtual machine and loaded Ruby and Rails. The “rally_api” gem was simple to install, too. From there, I created a Rails “Rally” project. I created a model for DefectUpdateRecords. This model contains many of the same fields of the defect, but it additionally stores the defect’s previous state, the new state, a timestamp when the change occurred (by default with Rails ActiveRecords), and project and object IDs so that I could build an URL link directly to each Rally defect, like this:
https://rally1.rallydev.com/#/<project ObjectID>/detail/defect/<defect object ObjectID>
I then created a “sync_states” method in my model. It’s job is to query Rally for defects that have changed since the last time it checked (using a local file containing a timestamp that is updated each time). It then checks if each defect is in a project that we care about. If so, it syncs each defect’s State and ScheduleState fields. If a change was made, then it also creates a new DefectUpdateRecord in the local database. I used Rails’ basic scaffolding to display an index page of all changed records. A couple tweaks to the view page and then it displays external links directly to each Rally defect as well. Pretty straight-forward.
Now that I had a simple Rails app with a method that can be called to synchronize Rally defect fields, I needed to add some basic automation to do this on a regular basis. Since our original wish was to have this synchronization happen automatically in the UI, I wanted this to run fairly frequently. I chose an interval of every 10 minutes. So the plan was to setup a cron job that calls the DefectUpdateRecord.sync_states method every 10 minutes. Crontab’s syntax is a little cryptic and I wasn’t sure exactly what environment variables I needed to setup, either. Luckily, there’s a great little Ruby gem called Whenever that makes it easy to write Rails cron jobs.
After installing the Whenever gem, all I needed to do was cd to my app’s main directory then type “wheneverize .”. This creates a boilerplate schedule.rb file in my apps config directory. I then added this to the file:
every 10.minutes do runner "DefectUpdateRecord.sync_states" end
Then, in my app’s directory, when I type ‘whenever’, it spits out the crontab text I would need to create the cronjob:
0,10,20,30,40,50 * * * * /bin/bash -l -c 'cd /home/admin/rally && script/rails runner -e production '\''DefectUpdateRecord.sync_states'\''' ## [message] Above is your schedule file converted to cron syntax; your crontab file was not updated. ## [message] Run `whenever --help' for more options.
Last step – redirect whenever’s output to a file, then call “crontab <filename>”. Calling “crontab -l” confirms that the cronjob is all setup and ready to go!
So, in the end, for our in-house development environment, having “sync_state” method cron jobs firing off every 10 minutes and the Rails app up-and-running (to display the DefectUpdateRecord change log) keeps our Rally defect states synchronized and viewable by all.