1. All Blogs 2. About Me 3. Contact Me 4. Visit My Website 5. Visit My Venture

Part 4: Issues, Milestones, and GitHub Projects

font_size 100%
font
contrast
listen

Part 4: Issues, Milestones, and GitHub Projects

Nothing drains engineering energy faster than spending half an hour every morning updating ticket statuses in an external project tracker that is completely disconnected from your code. When your issue tracking lives in GitHub Issues and GitHub Projects V2, your branches, commits, and pull requests update the board for you.

In Part 3, we covered pull request workflows. Now let's set up structured issue intake and automated project tracking.

Issues, Milestones and GitHub Projects V2 GraphQL Engine

1. YAML Issue Forms Instead of Blank Text Boxes

Old Markdown issue templates (.github/ISSUE_TEMPLATE/bug.md) just pre-fill a text box. People routinely delete the prompts and submit a one-line issue that says "login doesn't work".

YAML Issue Forms (.github/ISSUE_TEMPLATE/*.yml) replace that freeform text box with actual form fields—dropdowns, text inputs, checkboxes, and required validations. Pair them with .github/ISSUE_TEMPLATE/config.yml (blank_issues_enabled: false) so every bug report comes in with a severity level, version number, and reproduction steps, while general questions get redirected to Discussions or your security advisory page.

2. Sub-Issues, Milestones, and Projects V2

  • Sub-Issues: GitHub Issues natively support parent-child Sub-Issues (up to 8 levels deep) and organization Issue Types (Bug, Feature, Task, Incident). You can create one parent issue for a large feature, break it into 5 sub-issues across your backend and frontend repos, and watch the parent issue's completion bar update as each sub-issue's PR merges.
  • Milestones vs. Iterations: Use repository Milestones for release targets (v2.5.0, Q4 Security Audit). Use Projects V2 Iteration fields for recurring timeboxes like 2-week sprints.
  • Projects V2 Views & Filters: A single GitHub Project can pull in issues and PRs from multiple repositories and display the exact same items as a Table, a Kanban Board, or a Roadmap grouped by custom fields (Priority, Iteration, Story Points).

You can filter any Project view using a simple query syntax:

# Open P0/P1 work in the current sprint
is:open iteration:@current priority:P0,P1 -status:"Done"

# PRs waiting on review for more than 3 days
is:pr is:open status:"In Review" updated:<@today-3d

3. Let Git Drive the Board (Fixes #ID)

Nobody on your team should have to drag cards across columns by hand. Combine GitHub's built-in closing keywords (Fixes #104, Closes #104, or Resolves org/repo#104) in your PR descriptions with Projects V2 built-in workflows:

  • Issue opened → Added to the Project with Status: Triage.
  • PR opened referencing #104 → Status moves to In Review.
  • PR merged into main → Issue #104 closes automatically and Status moves to Done.

4. Walkthrough: Setting Up a Bug Form and Auto-Triage Workflow

Let's add a validated bug form and a small GitHub Action that adds new issues to a Project board and tags SEV-1 issues as priority:P0.

Step 1: Create .github/ISSUE_TEMPLATE/config.yml and bug_report.yml

# .github/ISSUE_TEMPLATE/config.yml
blank_issues_enabled: false
contact_links:
  - name: Security Vulnerability Report
    url: https://github.com/Ace-Vector-Labs/platform/security/advisories/new
    about: Report security vulnerabilities privately via GitHub Security Advisories.
# .github/ISSUE_TEMPLATE/bug_report.yml
name: "Production Bug Report"
description: "Report a reproducible bug in production or staging."
title: "[BUG]: "
labels: ["type:bug", "triage:pending"]
body:
  - type: dropdown
    id: severity
    attributes:
      label: "Severity"
      options:
        - "SEV-1: Production outage or data loss"
        - "SEV-2: Core feature broken, no workaround"
        - "SEV-3: Minor bug or workaround available"
    validations:
      required: true

  - type: input
    id: version
    attributes:
      label: "Commit SHA or Release Tag"
      placeholder: "e.g., v2.4.1 or a4c91f2"
    validations:
      required: true

  - type: textarea
    id: repro
    attributes:
      label: "Steps to Reproduce"
      value: |
        1. Send request...
        2. Observe response...
    validations:
      required: true

Step 2: Auto-Add Issues to Projects V2 and Escalate SEV-1 Bugs

# .github/workflows/project-auto-triage.yml
name: Projects V2 Auto-Triage
on:
  issues:
    types: [opened]

permissions:
  issues: write

jobs:
  sync-to-project:
    runs-on: ubuntu-latest
    steps:
      - name: Add Issue to Project Board
        uses: actions/add-to-project@v1.0.2
        with:
          project-url: https://github.com/orgs/Ace-Vector-Labs/projects/4
          github-token: ${{ secrets.PROJECT_AUTOMATION_TOKEN }}

      - name: Escalate SEV-1 Bugs to P0
        if: contains(github.event.issue.body, 'SEV-1')
        env:
          GH_TOKEN: ${{ secrets.PROJECT_AUTOMATION_TOKEN }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
          REPO: ${{ github.repository }}
        run: |
          gh issue edit "$ISSUE_NUMBER" --repo "$REPO" \
            --add-label "priority:P0" \
            --remove-label "triage:pending"

Quick Checklist

  • Turn off blank issues: Set blank_issues_enabled: false in .github/ISSUE_TEMPLATE/config.yml and use YAML forms so bug reports always include reproduction steps.
  • Keep labels clean with prefixes: Stick to four clear label groups: type:* (bug, feat, chore), priority:* (P0–P3), area:* (api, frontend, infra), and status:* (blocked, needs-repro).
  • Always link PRs with Fixes #ID: Make it a habit to include Fixes #123 in every PR body so issues close and boards update the moment code lands on main.

Series Navigation: ← Previous: Part 3: Mastering Pull Requests & Code Reviews | Next: Part 5: GitHub Pages, Gists, and Developer Portfolios → | All Articles

← Back to all articles