Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

2. Project Management on GitHub

Time: 25 minutes. Code is only half of a project; the other half is knowing what to do next, who does it and when it is done. You plan the first release of calc-app with issues, labels, a milestone and a project board, then fix a bug with a pull request that closes its issue automatically.

The ideas in two minutes

ToolWhat it isIn our project
IssueOne unit of work: a bug, a feature, a task. It has a discussion, an assignee, and is open or closed“Dividing by zero crashes”
LabelA coloured tag to classify issuesbug, enhancement, ci
MilestoneA group of issues with a due date, usually a release, with a progress barv1.0
ProjectA board or table that shows the issues of one or more repositories, with custom fields and automation“Calc App roadmap”
Closing keywordCloses #12 in a pull request: merging it closes issue #12the bug-fix PR

2.1 Create the issues

Open the Issues tab of your repository and click New issue. You are offered a Bug report and a Feature request form. They come from the .github/ISSUE_TEMPLATE/ folder of the project: issue templates are just files in the repository.

Create these four issues:

#3: the bug. Choose Bug report:

The form adds the bug label for you.

#4: a feature. Choose Feature request:

#5: documentation. Choose Blank issue:

#6: a task, with a new label. First create the label: Issues → Labels → New label, name ci, description Automation and pipelines, pick a colour → Create label. Then a blank issue:

On each issue, under Assignees, click assign yourself. In a comment, you could notify a teammate by writing @ and their username, or reference another issue by typing # and its number.

2.2 Plan a release with a milestone

  1. Issues → Milestones → New milestone.

  2. Title: v1.0. Due date: next week. Description: First release: no known bugs, a power operation, CI and a Docker image.

  3. Create milestone.

Now put the four issues in it: in the Issues list, tick the checkbox of all four, open the Milestone menu above the list, and choose v1.0. The milestone page shows 0% complete, with 4 open issues.

2.3 Visualise the work on a project board

  1. Open the Projects tab of your repository and click New project (it may be under the Link a project menu).

  2. Choose Board, name it Calc App roadmap, and click Create project.

  3. The board has three columns: Todo, In Progress and Done. At the bottom of Todo, click + Add item, type #, pick your calc-app repository, and select an issue. Repeat for all four.

  4. Drag the bug issue to In Progress: that’s what you work on next.

Try the other views: the Table layout (⋯ next to the view name → Layout) shows the same items as a spreadsheet, where you can add fields such as Priority or Estimate.

The board updates itself: open ⋯ (top right) → Workflows. The Item closed and Pull request merged workflows are on, so when an issue closes, its card moves to Done by itself.

2.4 Fix the bug with a pull request that closes the issue

Start from an up-to-date main, on a new branch:

git switch main
git pull
git switch -c fix-divide-by-zero

The fix. In app/calculator.py, make divide refuse a zero divisor:

calculator.py
def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

In app/main.py, at the end of calculate, turn that error into a clean 400 Bad Request answer instead of a crash:

main.py
    try:
        result = OPERATIONS[operation](a, b)
    except ValueError as error:
        return jsonify(error=str(error)), 400
    return jsonify(operation=operation, a=a, b=b, result=result)

The tests. A fixed bug deserves a test, so that it can never come back unnoticed. In tests/test_calculator.py, add import pytest as the first line, and this test at the end:

def test_divide_by_zero():
    with pytest.raises(ValueError):
        divide(1, 0)

And at the end of tests/test_api.py:

test_api.py
def test_divide_by_zero_is_a_client_error():
    response = client.get("/api/divide?a=1&b=0")
    assert response.status_code == 400
    assert response.get_json()["error"] == "Cannot divide by zero"

If you have Python, run pytest -v: 10 tests pass. Then commit and push:

git add .
git commit -m "Return a clear error when dividing by zero"
git push -u origin fix-divide-by-zero

Open a pull request. In its description, link the issue with a closing keyword:

Dividing by zero now returns a 400 error with a clear message,
instead of a 500 Internal Server Error.

Closes #3

Open issue #3: in its sidebar, under Development, the pull request is linked. Back in the PR, Merge pull request → Confirm merge → Delete branch. Then watch three things happen by themselves:

  1. Issue #3 is closed, with a note that the PR closed it.

  2. On the project board, its card moved to Done.

  3. The v1.0 milestone is now 25% complete.

Update your local copy:

git switch main
git pull

What you learned

Issues and issue templates, labels, task lists, assignees, milestones, project boards and their automation, and closing issues from pull requests. Every change now has a reason (an issue) and a review (a pull request). But nothing checks that a change doesn’t break the code. That is next. Continue with Part 3.