mirror of
https://github.com/hwchase17/langchain.git
synced 2026-04-03 10:55:08 +00:00
ci: auto-close issues that bypass template checkboxes (#36377)
GitHub issue forms enforce `required: true` checkboxes in the web UI, but the API bypasses form validation — bots and scripts can open issues with every box unchecked or skip the template entirely. This adds a workflow that auto-closes those issues, with an org-membership carve-out so maintainers can still open free-form issues.
This commit is contained in:
106
.github/workflows/close_unchecked_issues.yml
vendored
Normal file
106
.github/workflows/close_unchecked_issues.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
# Auto-close issues that bypass or ignore the issue template checkboxes.
|
||||
#
|
||||
# GitHub issue forms enforce `required: true` checkboxes in the web UI,
|
||||
# but the API bypasses form validation entirely — bots/scripts can open
|
||||
# issues with every box unchecked or skip the template altogether.
|
||||
#
|
||||
# Rules:
|
||||
# 1. Checkboxes present, none checked → close
|
||||
# 2. No checkboxes at all → close unless author is an org member or bot
|
||||
#
|
||||
# Org membership check reuses the shared helper from pr-labeler.js and
|
||||
# the same GitHub App used by tag-external-issues.yml.
|
||||
|
||||
name: Close Unchecked Issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.issue.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check-boxes:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Generate GitHub App token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@v3
|
||||
with:
|
||||
app-id: ${{ secrets.ORG_MEMBERSHIP_APP_ID }}
|
||||
private-key: ${{ secrets.ORG_MEMBERSHIP_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Validate issue checkboxes
|
||||
if: steps.app-token.outcome == 'success'
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
github-token: ${{ steps.app-token.outputs.token }}
|
||||
script: |
|
||||
const body = context.payload.issue.body ?? '';
|
||||
const checked = (body.match(/- \[x\]/gi) || []).length;
|
||||
|
||||
if (checked > 0) {
|
||||
console.log(`Found ${checked} checked checkbox(es) — OK`);
|
||||
return;
|
||||
}
|
||||
|
||||
const unchecked = (body.match(/- \[ \]/g) || []).length;
|
||||
|
||||
// No checkboxes at all — allow org members and bots, close everyone else
|
||||
if (unchecked === 0) {
|
||||
const { owner, repo } = context.repo;
|
||||
const { h } = require('./.github/scripts/pr-labeler.js').loadAndInit(github, owner, repo, core);
|
||||
|
||||
const author = context.payload.sender.login;
|
||||
const { isExternal } = await h.checkMembership(
|
||||
author, context.payload.sender.type,
|
||||
);
|
||||
|
||||
if (!isExternal) {
|
||||
console.log(`No checkboxes, but ${author} is internal — OK`);
|
||||
return;
|
||||
}
|
||||
console.log(`No checkboxes and ${author} is external — closing`);
|
||||
} else {
|
||||
console.log(`Found 0 checked and ${unchecked} unchecked checkbox(es) — closing`);
|
||||
}
|
||||
|
||||
const { owner, repo } = context.repo;
|
||||
const issue_number = context.payload.issue.number;
|
||||
|
||||
const reason = unchecked > 0
|
||||
? 'none of the required checkboxes were checked'
|
||||
: 'no issue template was used';
|
||||
|
||||
// Close before commenting — a closed issue without a comment is
|
||||
// less confusing than an open issue with a false "auto-closed" message
|
||||
// if the second API call fails.
|
||||
await github.rest.issues.update({
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
state: 'closed',
|
||||
state_reason: 'not_planned',
|
||||
});
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
body: [
|
||||
`This issue was automatically closed because ${reason}.`,
|
||||
'',
|
||||
`Please use one of the [issue templates](https://github.com/${owner}/${repo}/issues/new/choose) and complete the checklist.`,
|
||||
].join('\n'),
|
||||
});
|
||||
Reference in New Issue
Block a user