Recently we chose Jira as our new bug database, for reasons mostly explained in my previous post (at least, those were my reasons – other people were involved, no doubt with their own reasons). We were on Bugzilla before, which did us proud for many years, but we needed something a little more fully-featured in order to rely on the bug database as a more complete project management system. I don’t think Jira is the only choice that fits those criteria; there are several other good products out there (Fogbugz would have had a much better chance if version 7 had been out when we were deciding). I don’t want to spend a lot of time talking about Jira specifically – their website does a pretty good job of selling their product already – instead, I wanted to mention how important the plugin system is to us. I’ve touched briefly before on how useful plugin systems are; in Jira’s case, it’s a fantastic system that makes all the difference between a great product that we’d have to bend ourselves slightly to fit, and a product that can do exactly what we want. It’s probably the first time I’ve used a plugin system in anger, and I’ve been delighted.
You can get a good glimpse of how cool it is by looking at their plugin page, and you can gain a lot just by grabbing some of the existing ones, but it’s also very easy to create your own. Here are some of the customisations we’ve made in a short space of time.
You can define custom fields to do all kinds of interesting things:
- Calculated fields don’t store any data in the back-end database, but calculate their value (in a Java function) based on all the other fields in the issue. For example, we created a “reopen count” field that just looks back at the bug’s history and counts how many times it’s been reopened. Once you’ve created this field, you can search and sort bugs to find problematic issues that have been reopened a lot. Similarly, we have a “last status change” date that helps you search for bugs that are a in a given state and entered it recently, for example. We’ve created a field that automatically hyperlinks into some custom web-based in-house QA software. And we have a calculated field that simply mirrors data from the parent issue (Jira has a parent/child issue hierarchy), allowing you to use the search interface to search for issues based on data in their parent, which it doesn’t ordinarily do.
- We’ve created some other fields that present different user interfaces to the built-in choices. The built-in “select” field lets you choose “none” as an option (effectively storing NULL in the database) – we wanted certain fields to always have a value, so we’ve just customised the UI to remove the “none” option. We also created a “combo box” field that supports select-list UI as well as typing your own value (with nice autocomplete). We just used scriptaculous to do all the hard work :)
- Perhaps my favourite one is a “trick” implementation of issue locking. Here’s the backstory: imagine that two developers go to edit the same bug, around the same time. One of them changes the priority and submits their change. The other developer changes the description and submits their change. We have a conflict! In Bugzilla, the second developer gets a “mid-air collision” warning, with the choice of overwriting the other person’s change, or backing out of their own change. Jira doesn’t do this … the second developer quietly overwrites the first, which isn’t ideal. We managed to recreate Bugzilla’s behaviour by creating a clever custom field: it calculates its value to be the “last-updated” timestamp of the issue, stores this value as a hidden element on the HTML form, so the user can’t edit it but it gets uploaded when they submit, and we then override the field validation hook to cause the user’s submission to fail (with a “mid-air collision” error message) if the submitted value is older than the issue’s current “last-updated” timestamp. Phew!
Fake searching with reports
Jira’s built-in search functionality didn’t do as good a job as we’d have liked. As it happens, they’re fixing all of that in 4.0, but in the meantime, we’re making do with a couple of reports. The plugin system lets you write your own reports, so we just added reports that present a search interface for the “report configuration” step, perform the search and just show the resulting issue list as the report output. It’s not as good as using the built-in search system, because you miss out on standard functions of searches (the ability to save and share them, subscribe to them, and the ability to perform a bulk edit on the resulting list of issues), but it does perform the primary goal of a search: to find a set of issues! The specific search functions we added this way are:
- Specifying a list of issue keys – this is something that Bugzilla always supported (separated by spaces), and that people relied on, so we just added it. To make it even easier to access, we created a portlet so people could access this directly from their dashboard.
- Specifying a boolean combination of searches – again, something that Bugzilla supported. In our report, you have to create saved searches as the predicates, and then you can type a freeform boolean expression of these predicates. The report reuses the underlying search system to find the issues efficiently, and then performs the boolean on those results (term negation leads to a fun little programming problem that’s worth thinking about if you’re curious … given that the scope of a negation on its own is unclear, with a Jira instance consisting of multiple projects, components and so on).
Jira uses a workflow system for modelling the lifecycle of an issue. That’s a bit of an abstract mouthful, but it basically means that you have a little state machine to control the status of an issue, and the possible transitions between different status values. I’m not a huge fan of over-using this feature to create wacky state machines (the standard, built-in workflow has had some good thought behind it), but there are some useful hooks to customise on the transitions. On each workflow transition, you have 3 possible points of customisation:
- A workflow condition, which is a snippet of Java code that evaluates whether the transition should even be presented as an option to the user. I don’t think we’ve actually used this much – its main purpose seems to be for permissions, and the conditions that ship with Jira fill that need completely.
- A workflow validator, which checks that any user-entered data (a transition can present a user interface to ask for certain data to be entered) is valid. We’ve added a couple here – requiring the comment field to be non-empty, for example, or checking that the text entered in a text box is in fact a valid issue key.
- A workflow function, which is a snippet of Java code that fires after the workflow transition has been executed. We’ve created a function that sets a given field to the current user (effectively allowing us to keep track of the user who performed a particular action last, and hence search based on this), and a bunch of functions to auto-assign a bug based on some special rules of our own (Jira’s built-in assignment is purely component-based but we sometimes want to do some other things, like assign certain bugs based on the branch they’re reported in).
Reporting on the data in Jira is a pretty obvious use of the plugin system. We’ve got a load of different reports, and no doubt many more to come, that slice and dice this data and present high-level summaries, such as a grid breaking down work for each sub-team, for each upcoming version, together with their projected finish date, critical path team member, and a hyperlink (using the search system) to the list of work they have left. It even takes into account projected future hires for the team. I think we’ll have a lot more of this kind of stuff to add … for example, I’ve been thinking about whether a simple version of EBS could be possible :)
Last time I mentioned the idea of a “swim-lane” chart to show a team’s schedule. We now have this in Jira, with each block being a draggable item: drag within a developer’s row to re-order their work, and drag between developers to reassign work. This was actually really easy to do – ended up using the Yahoo UI library to handle all the dirty details of drag-and-drop in the browser, and communicating the edits with Jira was really straightforward.
For me, this is all an incredibly good illustration of the power of a decent plugin system. Interestingly, using the plugin system has also revealed how it can never do everything you want – there’s always a plugin customisation point where you just want one extra parameter the author didn’t think to provide, or a place in the application that they didn’t let you hook into. In Jira’s case, you’re ok as you get the source code – and we’ve managed to do some other cool things that way – but using the plugin system is always the first choice, because it’s so much lower-maintenance when they release updates.