The project

I have some very simple release data that I would like to report on a weekly basis. The data includes the target release date, and the feature sets and feature set benefits that are targeted for delivery in the current release. Fortunately all of this information is stored in our project management and collaboration system as a result of our release and iteration planning procedure.

Mingle is a project management/collaboration system for agile projects. Since we do all of our planning in mingle, and since the development team uses the it to keep track of their work, it’s always up to date and it’s got all the information I need for this task.

I’m a little bit on the lazy side when it comes to procedure and I’m a firm believer that process and procedure is something that should exist in the background and help us do our jobs. Once you’re spending a lot of time managing your procedures, they cease to be helpful. Enter automation; I don’t want to be bothered with manually extracting information from mingle every week and emailing it. As it turns out, mingle is written in rails and it has a restful API. This makes it very easy to access mingle data via http. My task is made even easier by the fact that rails offers ActiveResource which maps RESTful resouces similarl to the way ActiveRecord maps database objects.

The Setup

We’re using mingle for our planning and team collaboration. We have cards in mingle for Bugs, Spikes, Stories, Iterations, Releases, Feature sets and Segments. We also have card trees for managing relationships between these card types.

Our release planning tree is used for bucketing stories into releases and later into iterations. This tree is constructed as:

    Release > Iteration > Story

Our feature planning tree is used for story writing and starts with very general segments (also referred to as theme’s), then breaks down into feature sets (or epics) and finally to stories, like so:

    Segment > Feature Set > Story

From the above trees it’s possible for stories from a single feature set to be developed in 2 separate iteration or even releases.

The Implementation

I was only able to find very limited documentation on the mingle api, and even less on using active resource with the mingle api. However i did come across this tutorial on using mingle with active resource which was a very close match for what i was trying to do.

The first thing I had to do was create the Card class which implements ActiveResource::Base and configures the site url.

require 'activeresource'
class Card > ActiveResource::Base
  self.site = "http://#{User}:#{Password}@#{host}/projects/#{Project}/"

  ...
end

Our release cards contain a start date and a projected end date, other than that they serve as a top level parent in the release planning tree. I also needed to pull the release date out of our release card. This part was pretty simple:

def Card.find_release(release_name)
  card = Card.find :first,
      :params => { :filters => ["[name][is][#{release_name}]"]}
  card.cp_end_date
end

Following that I need to pull all the feature sets for the current release and extract some description data. Since I know all the stories in a release, the ideal way to retrieve the feature set cards would’ve been to get the stories for the release and then back into the feature sets using the feature set card tree. This turns out to be more difficult than it sounds. Mingle uses 2 fields for identifying cards. There is the id, which is the underlying database index, and there is the number, which is the application level card number. Unfortunately some operations use id and some use number. Specifically, GET uses number and POST uses id. Card tree relationships are defined using id as the foreign key. What this means is that while it’s possible to get a card using its number, then post changes to it using it’s id, it’s not possible to look up a card based on a card tree relationship using foreign key which is an id.

The following will not work based on this id/number issue:

stories = Card.find :all, :params => { :view => "Current Release"}

feature_ids = stories.collect {|story| story.cp_feature_tree___feature_card_id}
feature_ids.uniq!

features = feature_ids.collect do |id|
  Card.find :params => { :filters => ["[id][is][#{id}]"]}
end

Fortunately I had another option. During our release planning process, before we pull stories into a release, we tag the feature set with a release tag (using mingle tags). We use this tag as a bookmark so that we can remember which feature sets should be delivered in the release while we are in the process of story writing and estimating. The mingle API for tags is pretty solid and easy to use.

features = Card.find :all,
    :params => { :tagged_with => release,
                 :filters     => ["[Type][is][Feature Set]"]}

features.each do |feature|
  email_body << "#{feature.name}nBenefit: #{feature.cp_benefit}nn"
end

Although the code ends up simpler, this solution isn’t ideal since previously tags were only an artifact of our planning process and also because the code is less expandable. I am certain that I will eventually want to report additional story level information and I don’t have a way to map feature sets to stories.

This was a very simple automation project. The mingle API is far more sophisticated than this project illustrates. The mingle API shows a lot of promise for integration into our build process.

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

   
© 2012 WeRomans Suffusion theme by Sayontan Sinha