Project Management

Manage epics and tasks in Code for Life.

GitHub

Code for Life is managed using GitHub Issues and GitHub Projects.

An issue is a task (most common) or epic that is assigned to a repo (see issue types).

All of Code for Life's repos are prefixed with "codeforlife-" (see), except for rapid-router.

Simply put, a GitHub project allows you to collect issues from one or more repos, visualize them in a variety of views, and create your own custom workflows. From GitHub's docs:

A project is an adaptable table, board, and roadmap that integrates with your issues and pull requests on GitHub to help you plan and track your work effectively at the user or organization level. You can create and customize multiple views by filtering, sorting, slicing, and grouping your issues and pull requests to manage your team backlogs and roadmaps, visualize work with configurable charts, add custom fields to track metadata specific to your team, create templates, share status updates, and automate your projects.

Custom Project Fields

GitHub Projects supports creating custom fields to track different values per issue. Below are the custom fields we define.

How the CFL project-card appears on an issue

Status

[single select] The current status of a task in our Definition of Done.

Options:

  1. To Do - To be completed but haven't started yet.

  2. In Progress - Actively being worked on (unless blocked).

  3. Ready For Review - Ready to be reviewed but haven't started yet.

  4. In Review - Actively being reviewed.

  5. Staging - Has been deployed to staging and needs testing.

  6. Production - Has been deployed to production and needs testing.

  7. Closed - Has been completed.

Size

[single select] Approximately how many man-hours is needed to close a task.

Options:

  1. XS - Extra small (approx. 2hrs / ¼ working day).

  2. S - Small (approx. 4hrs / ½ working day).

  3. M - Medium (approx. 8hrs / 1 working day).

  4. L - Large (approx. 16hrs / 2 working days).

  5. XL - Extra large (approx. 24hrs / 3 working days).

Sprint

[iteration] The sprint the task is scheduled to be worked on. Our sprints are 2-week intervals.

Est. start

[date] The estimated start-date of an epic. Used in our Epic Roadmap.

Est. end

[date] The estimated end-date of an epic. Used in our Epic Roadmap.

Category

[single select] The type of work involved in a task.

Options:

  1. 💻 ( a.k.a. :computer: ) - Software development.

  2. 🎨 ( a.k.a. :art: ) - Design.

  3. 🔍 ( a.k.a. :mag: ) - Research.

  4. 📚 ( a.k.a. :books: ) - Educational resources.

  5. ⚙️ ( a.k.a. :gear: ) - Operations.

Examples of tasks per category

💻 develop a new feature.

💻 squash a bug.

💻 deploy a service.

💻 fix a security vulnerability.

🎨 design a user interface component.

🎨 design a page layout.

🎨 design some imagery/iconography/branding.

🎨 design some marketing/event materials.

🔍 conduct market/competitor research.

🔍 consolidate feedback provided in user-support tickets.

🔍 actively seek feedback on existing functionality.

🔍 investigate which feature to develop next.

📚 write a lesson plan.

📚 plan a game level.

📚 write a brain teaser.

📚 write a coding-club pack.

⚙️ consult with a legal professional about a concern.

⚙️ make a payment/budget.

⚙️ create & schedule a marketing campaign.

⚙️ organize an event.

Definition of Done

Our Definition of Done is defined using our custom Status field. The order of the statuses matter as each subsequent status is one step closer to a task being "closed". As seen on our Task Board, the leftmost/first (No Status) column is where you find newly created tasks and the rightmost column is where you find Closed tasks; the general idea is to move the tasks from the left side of the board to the right.

The status columns in order (from left to right)

Here's a high-level overview of how tasks move throughout the columns (not all possible paths).

Below are the statuses in order, each with:

  • a description of the conditions under which a task qualifies for the status;

  • general do's & do-not's for tasks in this status;

  • a list of acceptable previous/next status changes.

1. No Status

Technically this is the absence of a status and not an actual status. Newly created tasks go here.

When a task is first created, it should NOT be allocated a status.

Acceptable status changes:

  • ➡️ To Do - if a task is assigned to the current sprint or a previous sprint.

  • ➡️ In Progress - if a task is actively being worked on, regardless of sprint.

  • ➡️ Closed - if a task is closed, no longer relevant or a duplicate of another task.

2. To Do

Tasks that have been prioritized for this sprint and are aimed to be completed by end-of-sprint. Tasks not started from previous sprints will remain in this column.

Acceptable status changes:

  • No Status ⬅️ - if a task is unassigned from the current sprint or assigned to a future sprint.

  • ➡️ In Progress - if a task is actively being worked on, regardless of sprint.

  • ➡️ Closed - if a task is closed, no longer relevant or a duplicate of another task.

3. In Progress

Tasks actively being worked on, regardless if they're assigned to a sprint or not.

If a task is blocked, by which we mean it cannot be progressed by the assignee(s), it should be labelled with (search "blocked" in labels to find these):

  • "🛑" if the task can be unblocked by someone inside of Ocado;

  • "🌍🛑" if the task can ONLY be unblocked by someone outside of Ocado.

Acceptable status changes:

  • No Status ⬅️ - if a task is no longer being worked on and was unassigned from the current sprint or assigned to a future sprint.

  • To Do ⬅️ - if a task is no longer being worked on and is assigned to the current sprint.

  • ➡️ Ready For Review - if a task's assignee(s) believe they have delivered the requirements.

  • ➡️ Closed - if a task is closed, no longer relevant or a duplicate of another task.

4. Ready For Review

Tasks that are ready to be reviewed but haven't started being reviewed yet.

Acceptable status changes:

  • In Progress ⬅️ - if a task's assignee(s) realize that changes are required to the deliverables.

  • ➡️ In Review - if a reviewer has started reviewing a task's deliverables.

  • ➡️ Closed - if a task is closed, no longer relevant or a duplicate of another task.

5. In Review

Tasks that are actively being reviewed.

Assignees should NOT review their own task; we do peer reviewing.

When a task is reviewed, the task's deliverables will either be accepted or the reviewer will request changes. If changes are requested, the task will go back to In Progress and the assignee(s) must request another review. It's normal for a task to go through multiple rounds of review before its deliverables are accepted. If a reviewer accepts, they should comment "LGTM" (an acronym for "looks good to me").

Acceptable status changes:

  • In Progress ⬅️ - if a reviewer requests changes on a task's deliverables.

  • ➡️ Staging - if a dev-task (💻) was accepted and has been deployed to our staging environment.

  • ➡️ Closed - if a task is closed, no longer relevant or a duplicate of another task.

6. Staging

Dev-tasks (💻) that have been deployed to our staging environment and require manual testing.

A clear description of how to manually test a task's deliverables should be provided by the assignee(s) in a comment. At least 2 different testers (not including the assignees) should test the task's deliverables. If a tester approves, they should comment "LGTM" (an acronym for "looks good to me").

Acceptable status changes:

  • In Progress ⬅️ - if a bug or missing requirement managed to slip through the reviews.

  • ➡️ Production - if a dev-task (💻) was accepted in our staging environment.

  • ➡️ Closed - if a task is closed, no longer relevant or a duplicate of another task.

7. Production

Dev-tasks (💻) that have been deployed to our production environment and require manual testing.

A clear description of how to manually test a task's deliverables should be provided by the assignee(s) in a comment. At least 2 different testers (not including the assignees) should test the task's deliverables. If a tester approves, they should comment "LGTM" (an acronym for "looks good to me").

Acceptable status changes:

  • In Progress ⬅️ - if a bug or missing requirement managed to slip through the reviews.

  • ➡️ Closed - if a task is closed, no longer relevant or a duplicate of another task.

8. Closed

Tasks that have been completed.

Acceptable status changes:

  • No Status ⬅️ - if a task's requirements weren't delivered and aren't scheduled in the current sprint.

  • To Do ⬅️ - if a task's requirements weren't delivered and are scheduled in the current sprint.

  • In Progress ⬅️ - if a task's requirements weren't delivered and are actively being worked on.

Issue Relationships & Types

As documented by GitHub, you can add sub-issues to an issue which creates a child & parent relationship between issues. Depending on these relationships, we define different types of issues.

The terms "sub-issue" and "child-issue" are interchangeable.

Below is an example relationship-graph between various issues.

Legend:

  • --🛑-- > = blocking relationship ("this issue is blocking that issue").

  • 👶— > = child relationship ("this issue has that issue as a child").

Epics

(In graph: A, B, G) Issues that...

  • ...do have a sub-issue.

Epics are not tasks to be completed in themselves. Rather, epics represent initiatives that comprise multiple tasks. Epics are closed by closing all the sub-issues within them.

Top [Level] Epics

(In graph: A, G) Issues that...

  • ...do have a sub-issue...

  • ...and do NOT have a parent-issue.

Top-level epics contain sub-epics and/or tasks. These are useful for breaking down larger initiatives into smaller ones, each with their own tasks.

Tasks

(In graph: C, D, E, F, H, I, J, K) Issues that...

  • ...do NOT have a sub-issue.

Tasks are the actual work that needs to be completed.

Orphan Tasks

(In graph: J, K) Issues that...

  • ...do NOT have a sub-issue...

  • ...and do NOT have a parent-issue.

Orphan tasks are one-off tasks that are NOT part of an epic.

(In graph: C, D) Issues that...

  • ...do NOT have a sub-issue...

  • ...and are blocking another issue.

Blocking tasks define a sequence in which tasks must be closed ("this task must be done before that task").

(In graph: D, E) Issues that...

  • ...do NOT have a sub-issue...

  • ...and are being blocked by another issue.

Blocked tasks define a sequence in which tasks must be closed ("this task must be done after that task").

Project Views

In GitHub, a project-view is a way to visualize the issues in a project. A project can have 1 or more views, where each view has its own visualization-customizations and preset filters. Fundamentally, GitHub supports 3 different view types:

  1. Table - a spreadsheet comprised of issues.

  2. Board - spreads issues across customizable columns.

  3. Roadmap - a high-level visualization of issues across a configurable timespan.

Common Filters

There are a few filters common across our views. It's highly recommended you memorize them.

  1. is:open - An issue that has not been closed.

  2. has:sub-issues-progress - An issue that has sub-issues (a.k.a. child-issues).

  3. has:parent-issue - An issue that is a sub-issue (and therefore has a parent).

Our Custom Views

Below are our custom project-views, each with:

  • a short description of the insight it gives us into our project;

  • the preset filters (and what they do).

You can tab between views

All tasks, grouped by Status.

This helps us to explore all the tasks in our project (also see Open Task Table).

Preset filters ("Filter to issues that..."):

  1. -has:sub-issues-progress - ...do NOT have sub-issues.

All open tasks assigned to the current or a previous Sprint, grouped by Status and by Assignee.

This helps to see how many open tasks are remaining in the current sprint, including tasks carried over from previous sprints.

Preset filters ("Filter to issues that..."):

  1. -has:sub-issues-progress - ...do NOT have sub-issues...

  2. sprint:<=@current - ...and are in the current or previous sprints...

  3. has:status - ...and have a status (aren't in the No Status column)...

  4. -status:Closed - ...and are NOT in the Closed column (this hides the column).

All open tasks.

Similar to our Task Board, this helps us to explore all the open tasks in our project but see them in a dense spreadsheet format that supports bulk-editing field values by multi-selecting cells.

Preset filters ("Filter to issues that..."):

  1. -has:sub-issues-progress - ...do NOT have sub-issues...

  2. is:open - ...and are open.

All open top-level epics.

This helps us to estimate the timelines (start & end) of each top-level epic so that we can roughly plan the year ahead. Generally, the next quarter (3 months) should be understood to be well planned, with each proceeding quarter having rougher estimations.

The only thing that is constant is change — Heraclitus

Preset filters ("Filter to issues that..."):

  1. has:sub-issues-progress - ...have sub-issues...

  2. -has:parent-issue - ...and do NOT have a parent-issue...

  3. is:open - ...and are open.

Roles & Responsibilities

Below are the roles we define when managing our project, each with their own responsibilities and assignee(s).

[Sprint] Planner 🧭

Prioritizes tasks by assigning them to the current or upcoming sprints.

Responsibilities:

  1. (Un)assigns tasks to a sprint.

  2. Chases CFL team members to curate tasks which are assigned to next sprint.

  3. Consults CFL team members for potential blocking tasks.

Assignees: CFL's team lead, Sidi Jow.

[House] Keeper 🧹

Curates tasks to maintain a clean project with well defined requirements.

Responsibilities:

  1. Writes a full description.

  2. Writes the required deliverables.

  3. Sets the correct labels.

  4. Sets the correct Size.

  5. Sets the correct Category.

  6. Sets the correct relationships.

  7. Checks with other CFL team members if there are any doubts on any details.

  8. Closes tasks that are no longer relevant.

Assignees: Everyone in CFL.

[Trouble] Maker 💣

Creates new tasks to track work that needs to be done at some point.

Responsibilities:

  1. Searches existing tasks to ensure no duplicate tasks already exist.

  2. Creates new tasks with full descriptions and correct field values.

Assignees: Everyone in CFL.

[Project] Contributor 💪

Is assigned to tasks, delivers their requirements, and follows our Definition of Done [to close tasks].

Responsibilities:

  1. Updates the Status to reflect the current situation.

  2. Regularly comments significant progress-updates.

  3. Comments any discoveries which are perceived to be 'blockers'.

  4. Comments any discoveries which are believed to change the required deliverables.

  5. Attaches or links to the required deliverables in a comment.

  6. Addresses all feedback (through multiple review rounds if necessary) until the reviewer accepts.

  7. Avoids sharing PII of others and security vulnerabilities, which others could use to exploit.

  8. Is kind, collaborative and patient with everyone.

Assignees: Anyone. Become a Contributor

Automated Workflows

To keep our project 'clean' we've created @cfl-bot whose job it is to monitor to all issues and:

  • nudge user(s) or team(s) to create clean issues by commenting on them with change requests;

  • perform actions on others' behalf when prompted;

  • enforce rules (unless ignored).

Prompts

Contributors can instruct @cfl-bot to perform actions on their behalf by commenting one of the following prompts:

Usually contributors will NOT have the permissions to perform these actions themselves.

"assign me"

Description: Assigns you to an issue.

Use When: You want to work on an issue.

"unassign me"

Description: Unassigns you from an issue.

Use When: You no longer want to work on an issue.

"ready for review"

Description: Sets the status of an issue to Ready For Review.

Use When: You've attached deliverables to an issue and you would like a CFL team member to review it.

"requires changes"

Description: Sets the status of an issue to In Progress.

Use When: You've realized that your deliverables are missing something.

Description: Links a pull request to an issue.

Arguments:

  1. <number> The number of the PR to link.

  2. <repo?> The repo the PR is in.* Defaults to the issue's repo.

Use When: You want to associate your code changes with an issue.

Examples:

  1. link pr 1

  2. link pr 1 codeforlife-portal

  3. link pr 1 portal

Description: Unlinks a pull request from an issue.

Arguments:

  1. <number> The number of the PR to unlink.

  2. <repo?> The repo the PR is in.* Defaults to the issue's repo.

Use When: You want to disassociate your code changes with an issue.

Examples:

  1. unlink pr 1

  2. unlink pr 1 codeforlife-portal

  3. unlink pr 1 portal

Prompt Notes

*Only CFL repos may be specified. You can optionally omit the "codeforlife-" prefix.

Bot-Ignore Labels

If a CFL team member wants an issue to be ignored by the bot, they can add the bot-ignore label.

  • "🤖" ( a.k.a. :robot: ) - ignores all rules.

Last updated

Was this helpful?