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.
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.
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.
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.
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
- Name three work kinds and define one sentence for when each applies.
- Define priority criteria using impact, not adjectives in the report.
- Choose one milestone use case and write its completion condition.
- List the minimum fields needed to reproduce one bug class.
- Write the boundary for Issue vs Discussion vs external incident channel.
- 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?
When a stable query, routing rule, reporting need, owner, or policy decision needs that distinction—not merely because the nuance can be named.
Why is a milestone usually a poor substitute for workflow status?
Milestones represent bounded grouped goals and progress. Workflow status changes frequently and belongs in lifecycle/labels or structured fields.
A bot detects similar issue text with 85% confidence. Should it auto-close the new issue as duplicate?
Prefer suggesting the canonical candidate and letting a human confirm; false-positive closure can hide distinct defects and destroy trust.
Why might a Markdown template be better than a YAML issue form?
When the work is varied and flexible narrative is valuable, or when preview/schema stability and strict validation are not worth the extra structure.
What is the free-compatible alternative to organization issue types?
Use a small repository label taxonomy, milestones, assignees, and templates/forms while keeping types as an optional organization extension.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.