From 0fae882a687862d6bc1c717a17366eb5fbd46029 Mon Sep 17 00:00:00 2001 From: alexbelgium Date: Thu, 23 Jul 2026 15:37:45 +0200 Subject: [PATCH] feat: allow manual tier-1 triage of a single issue number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a workflow_dispatch trigger with a required `issue` input to on_issues_ai_triage.yaml, so a specific (existing) issue can be triaged on demand instead of only on issues.opened. - Every issue-number reference now reads `github.event.issue.number || inputs.issue`, so it resolves from the event on the auto path and from the input on manual dispatch. - The job's auto-trigger guards (skip the maintainer's own issues, honour no-ai) are bypassed on workflow_dispatch — a manual run is a deliberate override. - The 60s ping_submitter wait is skipped on manual dispatch; there's no race to lose against an issue whose ping already landed. The input flows only through env vars and expression contexts, never inline into a run: block, so there's no shell-injection surface; a bad number just fails `gh issue view` cleanly. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/on_issues_ai_triage.yaml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/on_issues_ai_triage.yaml b/.github/workflows/on_issues_ai_triage.yaml index 0fe03bdf15..8977955a47 100644 --- a/.github/workflows/on_issues_ai_triage.yaml +++ b/.github/workflows/on_issues_ai_triage.yaml @@ -13,6 +13,11 @@ name: AI issue triage on: issues: types: [opened] + workflow_dispatch: + inputs: + issue: + description: "Issue number to (re-)triage manually" + required: true permissions: contents: read @@ -20,7 +25,7 @@ permissions: id-token: write # claude-code-action fetches a GitHub OIDC token to auth the OAuth flow concurrency: - group: ai-triage-${{ github.event.issue.number }} + group: ai-triage-${{ github.event.issue.number || inputs.issue }} cancel-in-progress: false env: @@ -28,9 +33,13 @@ env: jobs: classify: + # Manual dispatch is a deliberate override: skip the auto-trigger guards + # (don't self-triage the maintainer's own issues; honour the no-ai + # opt-out) that only make sense for the fire-on-every-open path. if: >- - github.event.issue.user.login != 'alexbelgium' && - !contains(github.event.issue.labels.*.name, 'no-ai') + github.event_name == 'workflow_dispatch' || + (github.event.issue.user.login != 'alexbelgium' && + !contains(github.event.issue.labels.*.name, 'no-ai')) runs-on: ubuntu-latest timeout-minutes: 15 environment: CR_PAT @@ -41,7 +50,10 @@ jobs: # Both workflows fire on the same issues.opened event and race. The # submitter ping completes in 6-11s of job time across recent runs; 60s # leaves a generous margin for runner-queue skew between the two jobs. + # A manual dispatch runs against an existing issue whose ping (if any) + # landed long ago, so there is nothing to wait for. - name: Wait for ping_submitter + if: github.event_name == 'issues' run: sleep 60 - name: Checkout tooling @@ -57,7 +69,7 @@ jobs: - name: Build context bundle env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ISSUE_NUMBER: ${{ github.event.issue.number }} + ISSUE_NUMBER: ${{ github.event.issue.number || inputs.issue }} REPO: ${{ github.repository }} run: bash .github/scripts/ai_triage_context.sh @@ -83,7 +95,7 @@ jobs: - name: Apply verdict env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ISSUE: ${{ github.event.issue.number }} + ISSUE: ${{ github.event.issue.number || inputs.issue }} REPO: ${{ github.repository }} run: | set -euo pipefail