Saturday 3 March 2012

Redmine Implementation Notes

We recently decided to use Redmine + Backlogs to manage a series of projects and I have been knee-deep implementing it to suit our needs and provide information to the various project stakeholders.

Redmine provides a bunch of features out-of-the-box (basic task/sub-task management, Gantt chart, wiki, etc) but like many packages there are a few features that either just aren't right, or are plain missing. The good news is that Redmine supports a plugin architecture with many freely available plugins provided by the Redmine community. As with all things free: buyer beware; and be prepared to wade through some wacky features (why would you subject yourself to advertisements on an internal project management tool? Why?).  The next bit of good news is that it is open source, so if you don't like something you can always roll-up your sleeves, embrace the Ruby and change it.

My Redmine MVPs (Most Valuable Plugins):
  • Better Gantt Chart - provides a mildly better Gantt UI, but the big benefit is for task-rescheduling. Redmine's default task management works for pushing dates out but is hopeless for pulling dates back in on a task (and subsequent linked tasks).
  • Redmine Auto Percent - When a task is moved to 'Done', automatically set the percentage complete to 100%. I have plans to extend this plugin so that when a task moves from the Backlog to "In Progress" it will automatically set the percentage complete to 10% (ie. not zero).
  • Redmine Wiki UNC - Provide the ability to create UNC links in the Redmine wiki.

My Redmine MVCs (Most Valuable Code-Changes):
  • Change Field Labels - Redmine's default unit of time is hours. We normally estimate effort in days, so it made sense to change the field labels to prevent any confusion from the various stakeholders who use the tool. The quickest way to do this is to edit the appropriate language .yml file (eg. en-GB.yml) and change any references within that. A nicer way that will survive upgrades is to make a copy of the language file you are using and set both the language code and identifier to a unique name. Remember to re-start the web server and choose your new language file in the administration console. Language files are located at:
    • \Redmine\config\locales
    • \Redmine\vendor\plugins\redmine_backlogs\config\locales
  • Change Issues query to display Parent Story Name instead of Parent Story ID in results - The version of Redmine we are using unhelpfully displays the ID of the parent story which makes it hard to develop meaningful reports. The following code changes in the \Redmine\app\helpers directory allow the Parent Story Name to be shown:
    • queries_helper.rb - Modify method "column_content", specifically case statement option "Issue" to modify "link_to_issue" parameter "Subject" from false to true. This change by itself will make the Parent Task column display both the ID and the Name together.
    • application_helper.rb - Modify method "link_to_issue" so that only the parent task subject is displayed. Code changes highlighted below.

  def link_to_issue(issue, options={})
    title = nil
    subject = nil
    if options[:subject] == false
      title = truncate(issue.subject, :length => 60)
    else
      subject = issue.subject
      if options[:truncate]
        subject = truncate(subject, :length => options[:truncate])
      end
    end
 ####################################################
 # Modified code follows
 # Purpose: Display parent task name instead of ID in query results.
 ####################################################
 if options[:subject] == true
  s = link_to "#{h subject}", {:controller => "issues", :action => "show", :id => issue},
   :class => issue.css_classes,
   :title => title
 else
  s = link_to "#{issue.tracker} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue},
   :class => issue.css_classes,
   :title => title
  s << ": #{h subject}" if subject
  s = "#{h issue.project} - " + s if options[:project]
 end
 #
 ####################################################
 # Original Code follows (Replaced by changes above)
 ####################################################
 #s = link_to "#{issue.tracker} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue},
 #                                             :class => issue.css_classes,
 #                                             :title => title
 #s << ": #{h subject}" if subject
 #s = "#{h issue.project} - " + s if options[:project]
 ####################################################
    s
  end

These changes have resulted in a much more useful and usable project management tool. It's still not perfect (linked task date re-scheduling is a pain), but vastly improved for how we need to use the tool. Hopefully this information is useful to anyone else going down a similar path.