feat: add scheduled issue labeler for type/domain triage (#251)

* ci: add issue labeler workflow

Add a manual GitHub Actions workflow and script to poll issues and apply type/domain labels.

* feat(issue-labels): refine heuristics and add docs

Improve domain detection and add safeguards to avoid overriding manual type triage by default. Refresh regression samples from real issues and document usage.

* ci(issue-labels): enable hourly scheduled labeling

Run hourly on schedule with write mode by default while keeping manual dispatch dry-run by default.

* ci(issue-labels): shorten lookback window to 6h

Reduce scheduled scan window while keeping overlap for missed runs.

* ci(issue-labels): opt into Node 24 actions runtime

Set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 and use Node 24 for the script runtime to avoid upcoming Node 20 deprecation warnings.

* ci(issue-labels): restore lookback input for manual runs

Allow workflow_dispatch to override lookback_hours while keeping hourly schedule fixed.

* ci(issue-labels): upgrade checkout/setup-node to v6

Use actions/checkout@v6 and actions/setup-node@v6 to align with Node 24 runtime and avoid Node 20 deprecation warnings.

* fix(ci): label only unlabeled issues via search api

* fix(ci): refine issue labeling heuristics from live issues

* fix(ci): address remaining issue label review comments

* fix(ci): fix issue label arg parsing regression

* docs(issue-labels): clarify one-shot unlabeled triage scope
This commit is contained in:
williamfzc
2026-04-07 10:35:40 +08:00
committed by GitHub
parent b7613d64bd
commit 2efadece34
5 changed files with 1589 additions and 0 deletions

57
.github/workflows/issue-labels.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: Issue Labels
on:
schedule:
- cron: '0 * * * *' # every hour
workflow_dispatch:
inputs:
dry_run:
description: "Do not write labels, only print planned changes"
required: false
default: true
type: boolean
permissions:
contents: read
issues: write
concurrency:
group: issue-labels
cancel-in-progress: true
jobs:
sync-issue-labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
# v6+ uses Node 24 runtime for JavaScript actions.
- uses: actions/setup-node@v6
with:
node-version: '24'
- name: Sync managed issue labels
id: sync_issue_labels
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
EVENT_NAME: ${{ github.event_name }}
INPUT_DRY_RUN: ${{ github.event.inputs.dry_run }}
run: |
args=(
"--max-issues" "300"
)
# Schedule runs should write labels by default.
# Manual runs default to dry-run unless explicitly disabled.
if [ "$EVENT_NAME" = "workflow_dispatch" ] && [ "${INPUT_DRY_RUN:-true}" = "true" ]; then
args+=("--dry-run" "--json")
fi
node scripts/issue-labels/index.js "${args[@]}"
- name: Warn when label sync fails
if: ${{ always() && steps.sync_issue_labels.outcome == 'failure' }}
run: |
echo "::warning::Issue label sync failed; labels may be stale."
echo "⚠️ Issue label sync failed; labels may be stale." >> "$GITHUB_STEP_SUMMARY"