chore(#148): auto-triage user-submitted issues (flag + P2/Backlog)
New workflow .github/workflows/triage-user-issues.yml. On issues:opened, if the author is external (author_association not OWNER/MEMBER/COLLABORATOR), apply user-submitted + priority:P2 + board:backlog using PROJECT_PAT so the existing sync-labels-to-board.yml fires and sets Status=Backlog / Priority=Medium on board #2. Maintainer-opened issues are untouched. type: is left for manual triage. workflow_dispatch entrypoint added for manual re-triage and the post-merge live test: both triggers require the workflow to be on the default branch first (issues:-triggered workflows only run from default; a new workflow_dispatch is only dispatchable once on default), so validation happens after the merge to dev. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>pull/198/head v1.1.2-rc.1-b55-topology
parent
546002c2e8
commit
f6ebeef4f7
@ -0,0 +1,75 @@
|
||||
name: Triage User-Submitted Issues
|
||||
|
||||
# When an EXTERNAL (non-maintainer) user opens an issue, flag + default-triage it:
|
||||
# user-submitted + priority:P2 + board:backlog.
|
||||
# Labels are applied with PROJECT_PAT so the existing sync-labels-to-board.yml
|
||||
# (label -> board) fires and sets Status=Backlog / Priority=Medium on board #2.
|
||||
# `type:` is intentionally left for manual triage (type is the judgment call).
|
||||
#
|
||||
# Maintainer-opened issues (author_association OWNER/MEMBER/COLLABORATOR) are untouched.
|
||||
#
|
||||
# Requires repo secret PROJECT_PAT (classic PAT, project+repo scope) — the same
|
||||
# secret sync-labels-to-board.yml uses. The PAT is also what lets the added labels
|
||||
# re-trigger that downstream workflow (labels added by the default GITHUB_TOKEN do
|
||||
# NOT trigger further workflow runs).
|
||||
#
|
||||
# Testing: `issues:`-triggered workflows only run from the default branch, and an
|
||||
# owner-opened issue reports author_association=OWNER (won't self-trigger). Use the
|
||||
# workflow_dispatch entrypoint against a throwaway issue to validate before merge.
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: "Issue number to triage (test path — bypasses the author-association gate)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Triage user-submitted issue
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.PROJECT_PAT }}
|
||||
script: |
|
||||
const INTERNAL = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);
|
||||
const isDispatch = context.eventName === 'workflow_dispatch';
|
||||
|
||||
let issueNumber, association;
|
||||
|
||||
if (isDispatch) {
|
||||
issueNumber = parseInt(context.payload.inputs.issue_number, 10);
|
||||
if (!Number.isInteger(issueNumber)) {
|
||||
core.setFailed(`Invalid issue_number input: "${context.payload.inputs.issue_number}"`);
|
||||
return;
|
||||
}
|
||||
const { data: issue } = await github.rest.issues.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issueNumber,
|
||||
});
|
||||
association = issue.author_association;
|
||||
core.info(`Manual dispatch for #${issueNumber} (author_association=${association}) — bypassing author gate for test`);
|
||||
} else {
|
||||
issueNumber = context.payload.issue.number;
|
||||
association = context.payload.issue.author_association;
|
||||
if (INTERNAL.has(association)) {
|
||||
core.info(`#${issueNumber} opened by ${association} (maintainer) — skipping triage`);
|
||||
return;
|
||||
}
|
||||
core.info(`#${issueNumber} opened by external author (${association}) — triaging`);
|
||||
}
|
||||
|
||||
const labels = ['user-submitted', 'priority:P2', 'board:backlog'];
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issueNumber,
|
||||
labels,
|
||||
});
|
||||
core.info(`Applied [${labels.join(', ')}] to #${issueNumber}.`);
|
||||
core.info('sync-labels-to-board.yml will set Status=Backlog / Priority=Medium on board #2.');
|
||||
Loading…
Reference in new issue