Chapter 05Lesson 03~120 minutes

Issues, Labels, Milestones, Templates, Forms, Discussions, and Triage: Configuration, Design Choices, and Tradeoffs

Choose intentionally among free-form issues, Markdown templates, YAML issue forms, Discussions, pull requests, label taxonomies, milestones, and automation while preserving human judgment and a free-compatible operating path.

Intake designTaxonomyHuman judgmentTradeoffs

Learning objectives

  • Select free-form issues, Markdown templates, or YAML issue forms according to uncertainty and validation needs.
  • Separate Issue, Discussion, and Pull Request responsibilities so planning records and implementation review do not collapse into one queue.
  • Design a shallow label taxonomy and purposeful milestone policy that remain queryable as the repository grows.
  • Distinguish automation that gathers or suggests evidence from automation that makes irreversible triage decisions.
  • Account for plan/account/deployment/organization-policy variation without making paid features mandatory.
  • Use a decision table to justify maintainability, security, governance, reliability, compatibility, and cost.
Availability: All core design exercises are documentation/policy work and require no paid plan. Live examples can use a personal GitHub Free repository. Organization issue types/issue fields are optional organization-level capabilities. Issue forms are public preview and should be treated as a changing product interface. GitHub Enterprise Server users must verify their server-version documentation before adopting GitHub.com syntax/features.

1. Start with the uncertainty of the work, not with the coolest intake UI

A mature intake system does not force every thought through the same form. Highly repeatable bug reports benefit from required structured fields. Exploratory architecture conversations do not. A trusted maintainer may need an escape hatch for unusual operational work. The design question is: what evidence is mandatory before this class of work can enter the queue?

2. Free-form issue versus Markdown template versus issue form

Criterion Free-form issue Markdown template YAML issue form
Structure Low Medium guidance High, rendered fields
Required-field enforcement No No Yes for supported input validations
Reporter flexibility Highest High Controlled
Configuration risk Minimal Low YAML/schema + preview changes
Best fit Trusted maintainers, edge cases Flexible feature/support intake Repeatable bug/security-adjacent intake where omissions are costly
Failure mode Unstructured queue Users delete/ignore prompts Form becomes bureaucracy or collects irrelevant fields

Do not use required fields as a substitute for prioritization. A 20-field form can collect pristine data while discouraging reporters and delaying critical work. Every field should map to a triage decision: reproduce, classify impact, select owner, or choose next action.

3. Issue versus Discussion versus Pull Request

Question Issue Discussion Pull Request
Primary purpose Track actionable work/problem Open-ended conversation, Q&A, announcements Review a proposed Git change
Needs branch/head/base refs? No No Yes
Expected owner/state Usually yes Not necessarily Author/reviewers + merge state
Good place for incident follow-up task? Yes No, if ownership/escalation is required Only when implementation exists
Can one link to the others? Yes Yes Yes

The cleanest lifecycle is often Discussion → decision → Issue → implementation branch → Pull Request → closure/reference. That sequence is not mandatory, but it prevents the PR from becoming the only record of why work exists and prevents Discussions from becoming an unactionable backlog.

4. Label taxonomy: optimize for filtering decisions, not completeness

Label explosion usually begins with good intentions: every nuance receives a tag. Soon bug, type:bug, kind:defect, and incident-ish all mean roughly the same thing. Query results become arbitrary because humans cannot apply the taxonomy consistently.

Dimension Small-team example Rule
Kind kind:bug, kind:feature, kind:docs Exactly one when known
Priority priority:p1 … priority:p3 Set by triage criteria, not reporter urgency language
Workflow signal status:needs-info, status:blocked Temporary; remove when condition clears
Domain area:api, area:cli Only if it changes routing/ownership

Before adding a label, write the query or routing rule that needs it. If no filter, dashboard, SLA, owner, or automation consumes the distinction, prose may be cheaper.

5. Milestones: bounded goals, not another label axis

A milestone groups issues and pull requests toward a repository-level goal and exposes progress. It is useful for a release, migration, audit remediation wave, or small timebox. It is less useful when used as a permanent “team” or “status” field. Those meanings belong in ownership or taxonomy, not a milestone that never completes.

Deletion behavior: deleting a milestone does not delete the issues or pull requests. The grouping metadata disappears. Treat that as a planning-state change, not data destruction of the work records.

6. Issue types and issue fields: organization-wide structure when it actually exists

Current GitHub supports organization-defined issue types such as Task, Bug, and Feature, and organization issue fields for structured metadata. These are not a reason to make the course dependent on an organization. A personal repository can achieve the chapter goals with labels, milestones, templates/forms, and assignees.

If your organization uses issue types, use them for stable cross-repository semantics and avoid duplicating the same concept as a label unless a compatibility reason demands it. Organization owners manage the type definitions; ordinary triagers should consume rather than redesign the classification system.

7. Chooser policy: make the intended path obvious but keep an operator escape hatch

A good config.yml can route bug reports into a form, questions into Discussions/support, and security reports into an approved private channel. Setting blank_issues_enabled: false reduces accidental free-form intake for Read/Triage contributors while GitHub currently preserves a maintainer-only blank option for Write/Maintain/Admin users. That balance supports both consistency and exceptional operator work.

Do not put a public URL for confidential security reporting unless that destination is actually designed for confidential intake. contact_links changes where reporters go; it does not create confidentiality.

8. Automation-assisted triage: observe first, decide carefully

Automation action Risk Preferred pattern
Add a label from deterministic path/file evidence Low–medium Explain rule; make it reversible
Request missing reproduction data Medium Comment/suggest; preserve human override
Assign owner by CODEOWNERS/domain map Medium Use stable mapping and fallback
Auto-close “stale” issues High Long grace period, exemptions, clear reopen path, auditable comment
Auto-close suspected duplicates High Suggest canonical candidate; human confirms
Auto-prioritize incidents from reporter words High Never trust “urgent/P1” text alone; use impact evidence

Automation should reduce mechanical sorting while humans retain decisions where semantics or impact are uncertain. Later Actions chapters will implement permissions and events; here the design rule is to keep the mutation surface narrow and reversible.

9. Security and privacy shape intake design

Issue forms invite users to paste logs and screenshots. That creates a data-exfiltration path into public repositories. Ask for the minimum evidence, explicitly prohibit secrets/customer data, and route vulnerability reports to the repository’s security policy/private reporting process when applicable. A required “I removed secrets” checkbox is education, not enforcement.

Triage automation must also treat issue titles/bodies as untrusted input. Do not later interpolate issue text directly into shell commands in a workflow. Chapter 13+ will formalize this Actions boundary.

10. Worked decision table

Scenario Recommended design Maintainability Security / governance Reliability Cost / compatibility
Small public CLI project, recurring bug reports YAML bug form + 8–12 labels + one release milestone + Discussions for Q&A Low ongoing taxonomy cost Form warns against secrets; maintainer triage Repro fields reduce back-and-forth GitHub Free-compatible; form preview volatility accepted
Internal service team with trusted engineers Markdown template + blank maintainer issues + direct assignment Flexible Access policy carries more trust; still least privilege Fast operator intake Works without organization issue-type dependency
Large organization with consistent work classes Organization issue types/fields + repository labels only for local routing Central semantics Owner-managed schema; role separation Cross-repo queries improve consistency Requires organization governance; verify product/deployment availability
Open community brainstorm Discussions categories + conversion to issue when committed Keeps backlog clean Moderation policy required Ideas do not masquerade as scheduled work Free-compatible where Discussions enabled

11. Anti-patterns to reject during design review

  • Every issue gets every label: classification stops carrying information.
  • Milestone = status: use lifecycle/labels for state; milestones should complete.
  • Form as interrogation: required fields that do not change a decision increase abandonment.
  • Discussion as incident queue: operational ownership becomes ambiguous.
  • Bot is the triage policy: automation implements policy; it should not silently invent it.
  • Paid feature assumption: design a mandatory path that still works on a personal GitHub Free repository.

12. Design exercise: write your repository intake contract

  1. Name three work kinds and define one sentence for when each applies.
  2. Define priority criteria using impact, not adjectives in the report.
  3. Choose one milestone use case and write its completion condition.
  4. List the minimum fields needed to reproduce one bug class.
  5. Write the boundary for Issue vs Discussion vs external incident channel.
  6. Name one automated action you permit and one decision that must remain human.

13. Lesson summary

Good intake architecture minimizes semantic overlap. Use forms when structured evidence is genuinely required, labels for queryable repository-local distinctions, milestones for bounded goals, organization types/fields only when that governance exists, Discussions for conversation, and automation for reversible mechanics rather than opaque judgment.

Knowledge check

When should you add a new label?

Why is a milestone usually a poor substitute for workflow status?

A bot detects similar issue text with 85% confidence. Should it auto-close the new issue as duplicate?

Why might a Markdown template be better than a YAML issue form?

What is the free-compatible alternative to organization issue types?

Next lesson

Diagnose a broken queue from evidence

Lesson 04 intentionally creates bad classification and routing conditions, preserves the original evidence, and repairs them without erasing the cause.

Authoritative references

 Configuring issue templates
 Syntax for issue forms
 Managing labels
 About milestones
 Managing issue types
 Managing issue fields
 About discussions
 Repository roles
 REST API endpoints for issues

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.