As promised in the previous post, here is a little update on what I've been doing with customized workflows in Trac. I've only recently convinced everybody at work to move over to Trac, so we're still in the process of streamlining everything. It wasn't a hard sell, the last couple of projects have been set up with a shared document in Google docs, where they've had a hard time telling which "tickets" have been started, finished, or are even supposed to be included in the current milestone. However, as they have started using Trac in a more serious manner, and now even letting customers into the system, I've gotten a couple of customization requests.
For example, just because a feature is implemented or a bug is fixed, the ticket is not considered ready to be closed. It's only closed once the code has been deployed to the production server. From the get go we tried to work around this, since in Trac a ticket is either open or closed. By having different resolutions and reopening the ticket and then closing it again with a new resolution, we were able to almost get what we wanted. However this does not look good in many places around Trac, for example in the timeline, and when the customer sees the ticket as closed, they expect it to be live on the production server as well.
Thankfully Trac 0.11 introduces a new feature which solves this completely for us -
Customizable Workflows. It's an amazingly powerful yet simple to use feature and I got a sample setup up and running surprisingly quickly. The showworkflow command line tool that ships with Trac now was extremely helpful and made it even easier to see that you set things up the way you planned without requiring extensive testing when you make modifications. It simply takes your configuration file and generates, using graphviz, a flowchart of your workflow:
As you can see when comparing the default and my sample workflows above, we've added a couple of extra steps in between the accepted and closed states. Once you've accepted a ticket it cannot be closed, the only possible actions are to either reassign it or to submit it for review by the project manager. When you submit it for review, it ends up in a new Status called validation. While in this state, the manager can choose whether to let it pass the review or to reopen the ticket and send it back to the developer.
Once it has passed the review it ends up in yet another new Status - ready_for_deployment. From this state the developers can choose to either deploy the new code to the shared development server and demo it to the customer, or directly deploy it to the production server. It's also still possible to reopen the ticket from this point. If they however deploy it to the development server the ticket ends up in yet another new status called deployed_dev. Only when a deployment on the production server is completed the ticket will be closed. This can be performed either from the ready_for_deployment status, or from the deployed_dev status.
While we haven't put this new workflow to the test yet, I'm certain it will work much better than the previous system with different resolutions. Since I find this feature to be well-documented I don't see any need to repeat the steps needed here, however I will post the [ticket-workflow] section from my trac.ini here for your reference:
[ticket-workflow]
accept = new,assigned,accepted,reopened -> accepted
accept.operations = set_owner_to_self
accept.permissions = TICKET_MODIFY
leave = * -> *
leave.default = 1
leave.operations = leave_status
reassign = new,assigned,accepted,reopened -> assigned
reassign.operations = set_owner
reassign.permissions = TICKET_MODIFY
reopen = closed,deployed_dev,ready_for_deployment -> reopened
reopen.operations = del_resolution
reopen.permissions = TICKET_CREATE
resolve = new,assigned,accepted,reopened -> closed
resolve.operations = set_resolution
resolve.permissions = TICKET_MODIFY
review = accepted -> validation
review.name = Submit for Review
review.permissions = TICKET_MODIFY
reject = validation -> reopened
reject.name = Failed Review, return to developer
pass = validation -> ready_for_deployment
pass.name = Passes Review
pass.permissions = TICKET_MODIFY
deploy_dev = ready_for_deployment -> deployed_dev
deploy_dev.name = Deployed to Development server
deploy_dev.permissions = TICKET_MODIFY
deploy_live = ready_for_deployment,deployed_dev -> closed
deploy_live.name = Deployed to Production server
deploy_live.permissions = TICKET_MODIFY
deploy_live.operations = set_resolution
deploy_live.set_resolution = fixed
Things I have planned for the future is customizing the permissions so that indeed only the manager can say a ticket has passed the review (With the configuration above, any developer can do it since they all have the TICKET_MODIFY permission) as well as modifying the milestone status page to account for the new states.