On a couple projects I’ve used GitHub Issues as the primary technique to organize the project, and I’ve generally enjoyed it, but it took some playing around to come up with a process. You, reader, may also like this process, so I will describe it for you.
GitHub Issues has a slim set of features:
- Issues, of course
- Issues can be assigned
- Issues belong to zero or one milestone
- Issues can have any number of tags
This isn’t a lot to work with, so we had to play around a bit to figure out a good pattern.
We decided there was only a couple things we actually wanted to track:
- What are we doing right now?
- What aren’t we doing right now?
- What aren’t we sure about?
We have to regularly reevaluate where issues fit into these categories, so we break category 2 into:
2a. Stuff we’ll probably do soon
2b. Stuff we probably won’t do soon
We tried using labels for this but it was no good. There’s only a small number of queries you can do with labels, foiling any clever ideas. Instead we have milestones:
Stuff we are doing right now: this is the “main” milestone. We give it a name (like Alpha 2 or Strawberry Rhubarb Pie) and we write down what we are trying to accomplish with the milestone. We create a new milestone when we are ready for the next iteration.
Stuff we’ll probably do soon: this is a standing “Next Tasks” milestone. We never change or rename this milestone.
Stuff we probably won’t do soon: this is a standing “Blue Sky” milestone. We refer to these tickets and sometimes look through them, but they are easy to ignore, somewhat intentionally ignored.
What aren’t we sure about?: issues with no milestone.
We use a permanent “Next Tasks” milestone (as opposed to renaming it to “Alpha 3” or actual-next-iteration milestone) because we don’t want to presume or default to including something in the real next iteration. When we’re ready to start planning the next iteration we’ll create a new milestone, and only deliberately move things into that milestone.
The Triage Meeting
We use the triage process to organize many of our meetings. The issues give us our first run at an agenda.
We have a label: needs discussion. We start each meeting by querying everything (regardless of milestone) that has that label, and discussing each item. Once we’re done discussing we usually remove the label, but sometimes we couldn’t decide whatever we wanted to decide and so we leave the label there, pushing the item to the next meeting.
It’s helpful to use “needs discussion” liberally. It might be for some big things, like we add a ticket “Decide who our target market is” — that’s kind of a big deal, and we might keep adding notes over the course of weeks. But it might just be a small issue where there seems to be some confusion or an open question.
These are small team meetings, so we aren’t trying to use this to close off discussion or restrict the agenda, and anyone can bring up a topic at any time. But if you want to be sure to talk about something then opening and labeling a ticket is as good a way as anything. Also the issues become our meeting notes (they aren’t date-organized meeting notes, but I seldom want date-organized meeting notes).
Issues without a milestone
GitHub lets you query all issues that have no milestone. It doesn’t let you query issues without a particular label, which made our label-based attempts at organization unproductive.
So next in the meeting we go through each item without a milestone, oldest first. Sometimes we skim, and if someone says “next tasks?” then usually the answer is “yes”.
Outside of a meeting if any of us sees something in Next Tasks or Blue Sky that we should do sooner, that person clears the milestone. It’s often better to clear the milestone than to just assign it to the current iteration, as it brings it in front of the entire team.
An exception is when someone breaks a big issue down into smaller tasks, or creates a dependent bug — then whoever does that usually assigns the milestone at the same time.
Starting a new iteration
When we’re ready to start a new iteration we first create a new milestone, and agree on our goal.
Sometimes if we’re not sure what our goal for the next iteration is we’ll create a ticket, “decide on goal for the next iteration” (and mark it needs-discussion of course).
We’ll go through the meeting as normal, then look at any open issues in the previous iteration. It’s pretty common that we move these issues to “Next Tasks” instead of the next iteration. Issues that didn’t get fixed often turned out to not be as important as we thought.
We sometimes go through Next Tasks, but it can also take too long to do that together. Part of me thinks we should slog through anyway, and use that as a chance to clean up Next Tasks — move stuff to Blue Sky, or close issues we no longer plan to address at all, or check for things that have already been fixed.
But instead one of us will often do an initial triage on Next Tasks, clearing the milestone for anything that might be worth looking at again. Also it’s a chance to close issues and find duplicates. It’s good to err on the side of clearing the milestone. It’s best not to assign a task directly to the next iteration because even talking about a ticket for a moment is useful.
Blue Sky unfortunately is a bit of a dumping ground. The only way issues emerge is when we search and happen upon something that was put into Blue Sky. Arguably we shouldn’t create a bucket for things we don’t want to pay attention to. But the issue list is also an idea collection area, and I like that. I’d like if we had a process to recover things from Blue Sky.
Sometimes we assign all the tickets in the current iteration. The primary purpose of assigning all the tickets is to identify the issues that no one is planning to address (and fix that).
I haven’t had a lot of luck using assignments for more than this. Something I wish I could do with an assignment is hand a task off to someone — like sometimes I can only finish half of an issue and I need someone else to finish the work (or vice versa). But unless that person is carefully watching what is assigned to them this won’t accomplish what I want. So I have to change the assignment and leave a comment. This leads to a lot of out-of-date chatter in the comments.
Generally I am unhappy with the notifications that GitHub provides. Are there third party products that can help here? Also it’s hard to know how someone else’s notifications are configured, so I don’t know what will trigger a response. Most people will occasionally catch some updates, leading to a false sense of security. (It would be great if I saw a list of everyone who was notified when I created or changed an issue.)
We have at times tried to use assignments to “claim” a ticket. I.e., use it as a declaration of intent to avoid two people working on the same thing. I did not find this productive, and it was hard to maintain.
In my Hotdish fantasy world I’d know who else in my team had looked at the ticket and when, and I could get a sense of what people were thinking about from that.
Maintaining the tickets
It’s important that tickets have proper titles. Sometimes I have left bad titles in place and it would cause repeated confusion — constantly asking myself and other people, what was this ticket about? GitHub has editable titles and you should use them. Editing the main ticket description for clear mistakes (broken links, s/now/not/, etc) is also useful.
Still issues have a limited lifetime. When the main description of the issue is no longer what you intend to implement it’s time to open a new issue, and close the original with a reference to the new issue. Long comment threads are not useful. Comments should indicate additions and clarifications, but when a comment changes the goal of the issue it’s too easy to skim over. Also when a debate happens in the comments and is resolved, it’s hard to separate the resolution from the debate, and a new ticket fixes that.
Sometimes there’s a collection of work that goes together. We tried two approaches, but neither stuck:
Create a label for the group of issues: in this model I might create a
webrtc label and label a bunch of issues. This would help me figure out just how much work was left on that area and what bugs I should keep in mind as I look at a particular area of code, and maybe help find bugs or at least be sure I wasn’t forgetting about something.
It’s easy to think that you should start building a taxonomy of bugs. The default GitHub labels imply something like this (like “bug”, “duplicate”, “enhancement”). I would sometimes find myself using these just because they are there, but always ask: why did I bother? Then I started deleting these labels to remove the temptation. I want only actionable labels.
An aside: the labels
invalid are (a) unnecessary, and (b) socially dangerous. If something is a duplicate you can close it with the comment “Dup of #123”. Often that’s not exactly what happened though, you might say “rendered moot by #123” or “once #123 is fixed this won’t be an issue” or something specific. And
wontfix is the worst, it’s like a way of telling someone to fuck off, but that you don’t even care enough to actually tell them why they should fuck off. If it’s a team member they won’t take offense, but it’s easy to fire it at some unwitting member of the public. Take the time to close the bug with a comment about why you won’t fix it. Invalid is like the vague passive aggressive combination of the other two. Maybe it’s because we like to imagine we’ll do some kind of reporting on these statuses, but I find myself pretty bored by history.
Create a master issue: in this case you create an issue that links to all the sub-issues that need to be tackled.
To do this you can’t just use backlinks (the link created whenever one issue references another): all backlinks look the same, and you can’t tell if a bug that references the master is a dependency of the master, or depends on the master, or just mentions it in passing.
Instead we list all the bugs in the main description of the master issue, and edit as necessary. You can use
[ ] to make the bug list a checkable list. Unfortunately issue links don’t get crossed out when they are closed (but they should, that would be a very helpful improvement).
The master ticket works okay but feels like it requires a lot of manual record keeping, and it’s easy for your master issue to get out of sync with the sub-issues. Also as you add or remove items from the list of dependent bugs you have to edit the main ticket description (anything in the comments would be too easy to lose) and there aren’t notifications for those edits.
I’ve only tried this approach with a small dedicated team. It wouldn’t match the less consistent rhythm of an open source project, and I have no idea how it would work with a larger team (maybe okay?)
One attribute is notably and deliberately missing: priorities, severities, and time estimates. We played with these and I never knew what to do with them. There’s no single equation that determines what you should work on, and trying to create such an equation seems pointless — you probably won’t include everything you need to include, and if you do then it’s unlikely that all parameters are filled in accurately and so you can’t trust the results.
The goals for me, and the team, is to keep things somewhat organized, to remember important things, and to come to a shared understanding of what we’re trying to accomplish and how. Because of that last point some parts of the process deliberately force conversation where a tighter process wouldn’t need it. Specifically I don’t want important things expressed through labels because there’s no opportunity to discuss labels, they just appear and disappear. Issue trackers that encourage complex taxonomies of bugs make me worry that the taxonomy will be used to assert things about process that need to be communicated directly and explicitly and via a two-way channel.
GitHub’s permissive approach to editing (titles, descriptions, and comments) is reflective of the kind of process I also want to support: everyone should be able to do everything in the service of the project. It’s better to give people more power: it’s actually helpful if people can overreach because it is an opportunity to establish where the limits really are and what purpose those limits have. Most tools have a strict append-only approach which I do not like (though it does make notifications easier, and notifications are my greatest frustration with GitHub Issues).
From your experience with GitHub issues do you have ideas to add to this?
Great report. Thank you. This is very similar to how we want to organize work on our team. I like the 'sky blue' bucket and 'next tasks' buckets as a permanent storage. In first bucket I would store things like 'yep, great idea but we are not doing it right now, maybe later maybe not" and second "yep, that's probably into next iteration milestons". Do you strive for milestones timeboxed to the same time lenght? 2 weeks? or is each milestone theme based?
Thanks for sharing and links to your projects.
We did theme-based milestones, so the times were variable, but we tried to keep them as short as we could.
David Allen, of "Getting Things Done" fame, in a podcast, called the GTD equivalent of your "Blue Sky dumping ground" the "Big Box Labeled 'Crap'". In general, GTD is about clearing your inbox regularly and putting things in their "proper place" according to the GTD workflow. The podcast listener asked about "the stuff you just aren't ready to break down, or deal with, or whatever?"
One of the important cornerstones of the GTD methodology is the "weekly review". Inbox processing happens continuously, at almost realtime. The weekly review is about the larger picture. Somewhere in there (perhaps not every week) is where you would trawl the BBLC and see what you could ditch, what you could convert into a project, and what just needed to go back in.
The point of this essay is to say that making some regular block of time, in whatever period is useful to you, for reviewing the Blue Sky issues may be more fruitful than relying on serendipity. I'm a big believer in serendipity, but I don't delegate *everything* to her.
I haven't spent much time with GitHub issues, but our team is moving our SCM to GitHub, and the integration of issues, commit messages, forks, and pull requests is very compelling. At the same time, I've had the most success with, and the most pleasure using FogBugz. It's opinionated, which, I think, is part of the reason I like it. With BugZilla and the other super-flexible tools I used, I found myself tweaking the tracker more than tracking the tweaks (through no fault of the tools... I tweak. I'm like the Miley Cyrus of coding. Except it's tweaking. Not twerking. Anyway.)
FogBugz comes with "philosophy included". It has "just enough" configurability and extensibility to address most common pain points, but it goes from zero to useful very quickly.
Contrary to how it may seem, I'm not actually trying to sell FogBugz... If you haven't used it, though, it's worth reviewing its opinions (well described in an APress(?) book: Project Management with FogBugz (?)) and seeing how many of them translate. I especially thought of this when you mentioned estimates and deadlines. FB's estimating and tracking tools are the secret sauce that makes me hesitate every time I think about moving to something else. It's what has me on the fence about switching to GitHub's issue tracker. Their "Evidence-Based Scheduling (EBS)" is useful both for managing expectations about the project as a whole, and, individually, for honing your task breakdown and estimating skills.
So... it's worth taking a test drive (perhaps to track a small personal project), along with reading the (thin) book, then applying what ports to your GitHub workflow.
Nice summary Ian! I found it still inspiring even if we work with GitHub Issues in similar manner for quite a long time already. You might want to have a look at http://overv.io we wrote to address most of the mentioned shortcomings.
We still use https://waffle.io/
Visually manage tasks easier (ex. https://waffle.io/itcase/sa...