Using a GitHub Discussions-First Approach Intake for Maintainers
I still spend time re-routing #1234: a question filed as a bug, a feature pitch that should've been an Ideas thread, an install problem with no version in the body. Discussion category forms fix what shows up in the forum once someone lands there. This post is about policy and wiring: where contributors go first, and what happens when they open New issue anyway.
Some maintainers want questions, ideas, and suspected bugs in GitHub Discussions, triaged in public, with Issues opened only after the work is real. That takes five pieces: chooser routing, a reserved issue template, discussion forms (see How to Write Effective GitHub Discussion Templates for YAML and the Ideas and Community Help examples), CONTRIBUTING.md, and a pinned rules thread.
A Simple Policy¶
Discussions are the front door. Issues are for confirmed, actionable work.
Write that in CONTRIBUTING.md, repeat it in a pinned discussion, and back it with templates so the UI matches the docs.
flowchart TD
contributor[Contributor] --> chooser[Issue chooser]
chooser -->|contact_link| discussions[Discussions forms]
chooser -->|reserved.yml| reserved[Reserved issue]
discussions --> triage[Triage thread]
triage -->|confirmed| issue[Tracked issue]
reserved -->|pending-close| closed[Closed without review] Route the Issue Chooser to Discussions¶
.github/ISSUE_TEMPLATE/config.yml is the first file I touch. Disable blank issues and put Discussions first as a contact_link. See Configuring the GitHub Issue Template Chooser for the full config.yml schema.
For a discussions-first repo, the file can look like this:
---
blank_issues_enabled: false
contact_links:
- name: Discussions
url: https://github.com/tenthirtyam/example/discussions/new/choose
about: The starting point for questions, assistance, and discussions about this project.
blank_issues_enabled: false removes the escape hatch. The Discussions link should land on discussions/new/choose so contributors pick a category immediately, not on a blank forum page.
Place that link above any issue templates in practice by listing it first and writing the about text as the primary path: questions, help, and early reports start here.
Use a Reserved Issue Template¶
Some contributors will still open New issue. Give them one template, for example reserved.yml.
It's not a bug form. The body sends them to Discussions. The only checkbox makes them acknowledge they read that. Auto-apply a label such as pending-close so automation or triage can close the issue without a review cycle.
---
name: Reserved
description: Use GitHub Discussions for questions, assistance, and discussions about this project.
labels: ["pending-close"]
body:
- type: markdown
attributes:
value: |
> [!IMPORTANT]
> Don't open an issue.
>
> Use [GitHub Discussions](https://github.com/tenthirtyam/example/discussions/new/choose) for questions, assistance, and discussions about this project.
- type: checkboxes
attributes:
label: Acknowledgement
options:
- label: By submitting this issue, I affirm that I neglected to read the message above and can expect this item to be closed without review.
required: true
Warning
A reserved template only works as deterrence if it's the only actionable issue template in the chooser. If bug.yml and enhancement.yml remain alongside it, contributors will keep filing real issues. For a strict discussions-first policy, remove public bug and enhancement templates from .github/ISSUE_TEMPLATE/ and open tracked issues yourself after triage confirms the work.
Every mis-filed issue still costs a label, a notification, and a context switch.
Automate pending-close¶
Manual closing is fine for the first few. After the third reserved issue, you'll want automation. A small workflow closes any issue labeled pending-close on open, posts a redirect comment with your Discussions link, and exits without a review debate:
---
name: Close Reserved Issues
on:
issues:
types: [opened, labeled]
permissions:
issues: write
jobs:
close-reserved:
if: contains(join(github.event.issue.labels.*.name, ','), 'pending-close')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const issue_number = context.payload.issue.number;
const discussions = `https://github.com/${context.repo.owner}/${context.repo.repo}/discussions/new/choose`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number,
body: [
'Thanks for opening an issue. This repository uses GitHub Discussions for questions, help, and early reports.',
'',
`Please start here: ${discussions}`,
'',
'Issues are reserved for confirmed, actionable work after triage.'
].join('\n')
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number,
state: 'closed',
state_reason: 'not_planned'
});
Create the pending-close label in the repository before you ship reserved.yml. The workflow needs issues: write permission only. Adjust the comment body to match your categories and triage policy.
Triage Bugs in Discussions First¶
Questions and ideas fit the Ideas and Community Help forms from the discussion templates post. Suspected bugs need a heavier form in Discussions first: version, environment, reproduction, expected versus actual behavior.
Add a Triage category (or reuse Community Help with a dedicated template if you prefer fewer categories). Create .github/DISCUSSION_TEMPLATE/triage.yml when the category slug is triage:
---
title: "[Triage]: "
labels: ["needs-triage"]
body:
- type: markdown
attributes:
value: |
Use this category when something looks like a bug but you're not sure yet. Maintainers will triage the thread and may ask you to open a tracked issue if it's confirmed.
Before posting, [search existing discussions](https://github.com/tenthirtyam/example/discussions) and [search existing issues](https://github.com/tenthirtyam/example/issues). Use reactions to up-vote existing reports instead of duplicating them.
When posting, include the following information.
- type: input
id: version
attributes:
label: Version
description: |
The version you're using.
Test with [the latest release](https://github.com/tenthirtyam/example/releases/latest) when you can.
placeholder: e.g. 1.0.0
validations:
required: true
- type: dropdown
id: environment
attributes:
label: Environment
description: Where the problem occurs.
options:
- Linux
- macOS
- Windows
- Other
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: What happened? Be specific enough that someone can investigate.
validations:
required: true
- type: textarea
id: configuration
attributes:
label: Configuration or Code Sample
description: |
Minimal example, workflow snippet, or link to a [GitHub Gist](https://gist.github.com/).
Remove secrets and identifiable information.
render: yaml
validations:
required: true
- type: textarea
id: debug
attributes:
label: Debug Output
description: Link to a Gist for long output. Paste only the relevant excerpt here.
render: text
validations:
required: false
- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: Actual Behavior
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to Reproduce
validations:
required: true
- type: textarea
id: references
attributes:
label: References
placeholder: |
#GH-0000
validations:
required: false
labels: ["needs-triage"] makes the queue visible. Maintainers and community helpers can ask follow-ups, mark an answer, or confirm a defect. Only then do you open an issue with your normal bug.yml workflow, often filed by a maintainer with the discussion link in the body.
That flow keeps the issue tracker thin: verified bugs and accepted enhancements, not every confused install report on day one.
| Stage | Where It Lives | Outcome |
|---|---|---|
| Question or How-to | Community Help Discussion | Answered in thread; no issue |
| Feature Idea | Ideas Discussion | Discussed; issue opened if accepted |
| Suspected Bug | Triage Discussion | Confirmed → issue; not reproduced → closed thread |
| Ignored Routing | Reserved Issue | pending-close, closed without review |
Say It in Contributing Gudelines¶
GitHub surfaces CONTRIBUTING.md when someone opens an issue or pull request. Chooser links help, but the file is where you say Issues aren't for general help.
## Questions and Help
Don't open an issue for questions, installation problems, or "how do I" requests.
Use [GitHub Discussions](https://github.com/tenthirtyam/example/discussions/new/choose) instead.
Pick the category that matches your post (Community Help, Ideas, or Triage for suspected bugs).
## Bugs and Feature Requests
Confirmed bugs and accepted enhancements are tracked as issues. Maintainers may open an issue for
you after a discussion is triaged. If you open an issue without that triage step, expect it to be
closed and redirected to Discussions.
Align that language with Writing Practical Contribution Guidelines for GitHub Repositories. The CONTRIBUTING file states the rule; the templates enforce it.
Pin the Rules Thread¶
Form preambles are easy to skip. Long rules belong in a discussion post you pin: the contract people see when they browse the forum, not only in YAML.
Create a thread in General (rules meta) or Community Help (help-specific norms). Paste expectations, pin it, and link it from the chooser about text and from CONTRIBUTING.md. A strong pinned post usually covers:
- Search First: links to docs, existing discussions, and common duplicates.
- Category Choice: Community Help for questions, Ideas for proposals, Triage for suspected bugs.
- Reactions over Duplicates: up-vote or react instead of opening parallel threads.
- Signal over Noise: no "+1" comments; add new information or reproduction detail only.
- Issues are Downstream: the tracker is for confirmed work after triage, not first contact.
Example body (adjust links and categories for your repo):
# Discussion Rules
Welcome. This board is for questions, ideas, and troubleshooting before anything becomes a tracked issue.
Please read and follow these rules before you post:
1. **Search irst.** Check [the docs](https://github.com/tenthirtyam/example/tree/main/docs), existing discussions, and open issues. Your question may already be answered.
2. **Use the Right Category.** Community Help for questions, Ideas for feature proposals, and Triage when you suspect a bug but need confirmation.
3. **Up-vote Instead of Duplicating.** If a thread already covers your topic, react or up-vote it. Do not open a parallel thread with the same question.
4. **Add Detail.** Version, environment, what you tried, and a minimal reproduction help maintainers respond once instead of five times.
5. **Don't Use Issues for General Help.** The issue tracker is for confirmed, actionable work. Questions and early reports belong here.
Maintainers may ask you to refine a post, move a conversation, or open an issue after triage confirms a defect.
Thank you for keeping the forum useful for everyone.
Lock the pinned thread if you don't want meta-discussion on the rules themselves. Update it when categories or policy change so the pinned post and CONTRIBUTING.md stay aligned.
Build Order¶
- Enable Discussions and categories (Ideas, Community Help, Triage).
- Add discussion category forms (templates post).
- Set
config.ymlcontact_linksandblank_issues_enabled: false. - Add
reserved.ymlas the only public issue template if you want a strict policy. - Publish
CONTRIBUTING.mdand pin the rules discussion.
Routing alone still sends vague threads to Discussions. Forms alone still leave New issue one click away. Wire both, automate pending-close for the holdouts, and triage suspected bugs in the forum before you open a tracked issue.