Using dependencies to understand the state of your in-flight features
On occasion we're going to write about how we use Codetree to build Codetree. In this article, we'll talk about how dependencies can help you answer questions like "How much work is left before this feature is ready to ship" and "who's working on what parts of this Epic".
You can use dependencies to answer several helpful questions about the state of your epics and features during planning and delivery.
In this article we'll first give you some context on our workflow so the rest of the article makes sense.
Then we'll cover how we use dependencies when structuring our relationships between epics, features, and tasks (we call them "work items").
Then, you'll learn why dependencies come in very handy during our workflow.
And finally we'll describe key questions you have about planning and delivering your features and how using dependencies can help you answer them.
Context: Our Workflow
To make sense of this article it's key that you have a sense of the workflow we use to deliver features.
- Untriaged. Any issue without a milestone is untriaged. This is where issues start unless the issue creator makes a judgement call and puts it in a monthly milestone.
- Triaged. Our triage schedule depends on untriaged issue volume. We'll do an article about our triage process later, but when we triage an issue we'll either
- put it in the "Triaged" milestone or
- move it to the current or upcoming month's work milestone. (We slot work into monthly milestones.)
- In Progress. Work that's been started.
- Resolved. Work that's been delivered as done but still needs acceptance testing and code review.
- Done. Work that's been deployed.
We could be a lot more granular with our workflow (for example, splitting resolved into UAT, code review, and ready for deploy stages). But our small team prefers pragmatism over dogma, so we do what works until it doesn't and then reevaluate.
Now that you understand our workflow, let's talk about the relationship between issues.
How We Structure Issue Relationships
To understand how we use dependencies, it's necessary to understand how we break a feature up into atomic units that can be coded. Here's our breakdown.
1. Create Epics
First, we create a parent Epic issue that groups together the features we want to deliver.
Epics help group together related features.
We use a label to specify that an issue is an Epic.
2. Break Epics into Features
The feature's Product Manager breaks the Epic down into smaller "feature issues" of deliverable customer value. Each feature is
needed-by the parent Epic issue (to create a dependency in Codetree you type
needed-by #123 or
needs #456, where 123 and 456 are issue numbers. More on creating dependencies here.)
Looking at an Epic's dependencies is useful because it'll tell you what's been delivered and what's still left to work on.
A feature issue should be a deployable slice of functionality.
3. Break Features into Work Items
The Dev assigned to each feature will either use a checklist or break the feature down into smaller "work item" issues. If the latter, each work item is "needed-by" the feature.
If you use work items, the dependencies table helps you understand what needs to be completed before the feature is ready for acceptance testing.
We usually use checklists as they're lighter weight, but there are certainly more complicated work items that justify having their own issue.
Using Dependencies in our Workflow
Other than specifying relationships between issues when we create epics, features, and work items, there's one place in our workflow where creating dependencies helps us understand what's going on with our project: in acceptance testing.
Filing Issues in Acceptance Testing
When the dev marks his issues as "Resolved" and it's ready for the Product Manager to do acceptance testing against the spec, the PM will files two kinds of issues:
- "Feature bug" issues that are "needed-by" the feature issue. These are for things that are broken with the feature. E.g. if the spec says "do x" and the feature doesn't do x, then the PM will file a feature bug.
- "UX polish" issues that are "needed-by" the feature issue. These are for parts of the experience that are rough around the edges and can be improved.
In this situation dependencies really shine. You're able to see:
How many feature bugs and UX polish issues are open, what stage they're at before the feature is ready for code review, and who owns each feature.
All the bugs and polish issues logged against the feature and decide whether to punt on them.
The number of feature bugs and polish issues are also useful to learn more about whether the spec perhaps needed more polishing, or if perhaps the dev was in over his head. Both useful pieces of information for the next feature you build.
These are all the issues filed against our File Uploading feature.
Answering Your Key Questions
Here's how to answer some of the key questions you may have about planning features and delivering in flight work.
"How many features are left (or delivered) in a specific epic?"
The combo of open/closed and issue stage tells you what work is left to do.
"What's holding up feature XYZ from being delivered?"
Having who's responsible for what and issue stages all in one place will help answer this.
"What work do I have to do to deliver the XYZ feature?"
You can quickly answer questions like this when you look at the stage of the dependencies you're assigned to.
That should give you a good overview of how we use Codetree's dependencies to augment GitHub issues and ship software. Feel free to drop us a line if you have other questions about using dependencies or if you use them in a way we didn't describe. We're always keen to learn!