Enforce GitHub issue template compliance

Issues that don't follow the issue template are automatically labeled with
`needs-template` and receive a bot comment explaining what sections are
missing. The label is removed when the issue is edited to become compliant.
Includes the workflow, decision logic, compliance checker, and comprehensive
tests verifying sync with the actual template definitions.
This commit is contained in:
Jinjing
2026-09-07 09:27:44 -07:00
parent b8311d509a
commit b62e2ca158
3 changed files with 528 additions and 0 deletions
@@ -0,0 +1,63 @@
name: Enforce issue templates
on:
issues:
types:
- opened
- edited
permissions:
contents: read
issues: write
concurrency:
group: issue-template-compliance-${{ github.event.issue.number }}
cancel-in-progress: true
jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
# Why: `issues` events check out the default branch, so only reviewed code runs
# under the write-scoped token. No dependency install: the script is node-only.
- name: Checkout compliance script
uses: actions/checkout@v6
with:
persist-credentials: false
sparse-checkout: .github/scripts/issue-template-compliance.mjs
sparse-checkout-cone-mode: false
- name: Decide whether the issue follows a template
id: decision
run: node .github/scripts/issue-template-compliance.mjs
- name: Label and comment on a non-compliant issue
if: steps.decision.outputs.kind == 'flag'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
LABEL: ${{ steps.decision.outputs.label }}
MARKER: ${{ steps.decision.outputs.marker }}
COMMENT: ${{ steps.decision.outputs.comment }}
run: |
set -euo pipefail
# Why no --force: a maintainer's recolor or reworded description must survive re-runs.
gh label create "$LABEL" --color d93f0b \
--description "Issue does not follow an issue template; awaiting author edit" \
|| echo "Label $LABEL already exists."
gh issue edit "$ISSUE_URL" --add-label "$LABEL"
# Why: an author may edit several times; keep a single bot comment per issue.
if gh issue view "$ISSUE_URL" --json comments --jq '.comments[].body' | grep -qF "$MARKER"; then
echo "Compliance comment already present; skipping."
else
gh issue comment "$ISSUE_URL" --body "$COMMENT"
fi
- name: Clear the label once the issue is compliant
if: steps.decision.outputs.kind == 'clear'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
LABEL: ${{ steps.decision.outputs.label }}
run: gh issue edit "$ISSUE_URL" --remove-label "$LABEL"