ci: enforce issue/PR description completeness for template-bypassing submissions (#1959)

* ci: add issue/PR description completeness checks (#1958)

Two github-script workflows that validate description structure on
issue/PR open/edit/reopen, for submissions that bypass the browser
template (API, gh CLI, agent bulk PRs).

- PR check: Summary, Linked Issue, Type of Change, duplicate-search
  box, How to Test.
- Issue check: body length + per-label bug/enhancement fields, plus a
  bug+enhancement conflict guard.
- Pass deletes any prior bot comment and applies `ready for review`;
  fail posts an in-place comment, fails the check, and applies
  `needs work` (PRs) / `needs more info` (issues).
- References existing labels only — never creates or recolours repo
  labels (checks existence first, warns and skips if absent).
- Safe pull_request_target: checkout pinned to the base ref, sparse
  `.github/scripts` only; PR head never checked out.

Closes #1958
Co-authored-by: Povilas Kirna <povilas.kirna@pebble.net>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Povilas Kirna
2026-06-03 16:58:10 +02:00
committed by GitHub
parent b5590fd008
commit 7c7ac1021a
4 changed files with 337 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
name: ci / issue description check
on:
issues:
types: [opened, edited, reopened]
permissions:
issues: write
jobs:
check:
name: Check issue description
runs-on: ubuntu-latest
# Skip bots (Dependabot, release-drafter, etc.)
if: ${{ github.event.issue.user.type != 'Bot' }}
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github/scripts
- uses: actions/github-script@v7
with:
script: return require('./.github/scripts/check-issue-description.js')({github, context, core})

View File

@@ -0,0 +1,28 @@
name: ci / PR description check
on:
pull_request_target:
types: [opened, edited, synchronize, reopened]
# pull_request_target runs in the base-repo context (has secrets).
# The checkout below pins to the base branch so no fork code is executed.
# The script only reads context.payload and calls the GitHub API.
permissions:
issues: write
pull-requests: write
jobs:
check-description:
name: Check PR description
runs-on: ubuntu-latest
# Skip bots — they open PRs programmatically and have their own process.
if: github.event.pull_request.user.type != 'Bot'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
sparse-checkout: .github/scripts
- uses: actions/github-script@v7
with:
script: return require('./.github/scripts/check-pr-description.js')({github, context, core})