Issue Garbage Collector #18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 'Issue Garbage Collector' | |
| on: | |
| # Weekly schedule: Every Monday at 09:00 UTC | |
| schedule: | |
| - cron: '0 9 * * 1' | |
| # Manual trigger with options | |
| workflow_dispatch: | |
| inputs: | |
| mode: | |
| description: 'Execution mode' | |
| required: true | |
| default: 'full' | |
| type: choice | |
| options: | |
| - full # Phase 1 + Phase 2 (AI analysis) | |
| - phase1-only # Python scanner only (no AI) | |
| - dry-run # Scan and report, no changes | |
| jobs: | |
| garbage-collect: | |
| name: 'Run Issue Garbage Collection' | |
| runs-on: ubuntu-latest | |
| # Only run if ANTHROPIC_API_KEY is configured (for Phase 2) | |
| # Phase 1 will still run without it | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| ANTHROPIC_MODEL: ${{ vars.ANTHROPIC_MODEL || 'claude-sonnet-4-20250514' }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| # Need full history for git operations | |
| fetch-depth: 0 | |
| # Use a token that can push changes | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: lts/* | |
| cache: 'npm' | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Configure Git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Run Phase 1 (Python Scanner) | |
| id: phase1 | |
| run: | | |
| echo "## 📋 Issue Scanner Report" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| python3 .github/scripts/issue-scanner.py | tee -a $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| # Get JSON output for Phase 2 | |
| python3 .github/scripts/issue-scanner.py --json > /tmp/scan-result.json | |
| SUSPECTS=$(jq '.summary.suspects' /tmp/scan-result.json) | |
| echo "suspects=$SUSPECTS" >> $GITHUB_OUTPUT | |
| - name: Run Phase 2 (AI Analysis) | |
| if: | | |
| env.ANTHROPIC_API_KEY != '' && | |
| steps.phase1.outputs.suspects != '0' && | |
| (github.event.inputs.mode == 'full' || github.event.inputs.mode == '' || github.event_name == 'schedule') | |
| env: | |
| INPUT_MODE: ${{ github.event.inputs.mode }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| run: | | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 🤖 AI Analysis" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "$INPUT_MODE" == "full" ] && [ "$EVENT_NAME" == "workflow_dispatch" ]; then | |
| echo "Manual full mode: applying issue maintenance changes." >> $GITHUB_STEP_SUMMARY | |
| npx tsx .github/scripts/issue-gc.ts 2>&1 | tee -a $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Report-only mode: scheduled and non-full runs do not mutate docs/issues/." >> $GITHUB_STEP_SUMMARY | |
| npx tsx .github/scripts/issue-gc.ts --dry-run 2>&1 | tee -a $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Skip Phase 2 (No API Key) | |
| if: env.ANTHROPIC_API_KEY == '' | |
| run: | | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## ⚠️ Phase 2 Skipped" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "No ANTHROPIC_API_KEY secret configured. Set it in repository secrets to enable AI analysis." >> $GITHUB_STEP_SUMMARY | |
| - name: Skip Phase 2 (No Suspects) | |
| if: steps.phase1.outputs.suspects == '0' | |
| run: | | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## ✅ No Suspects Found" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "All issues are in good shape. No AI analysis needed." >> $GITHUB_STEP_SUMMARY | |
| - name: Check for changes | |
| id: changes | |
| run: | | |
| if git diff --quiet docs/issues/; then | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 📝 Changes Made" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo '```diff' >> $GITHUB_STEP_SUMMARY | |
| git diff docs/issues/ >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Commit and push changes | |
| if: | | |
| steps.changes.outputs.has_changes == 'true' && | |
| github.event_name == 'workflow_dispatch' && | |
| github.event.inputs.mode == 'full' | |
| run: | | |
| git add docs/issues/ | |
| git commit -m "chore: automated issue garbage collection | |
| - Updated issue statuses based on AI analysis | |
| - Merged duplicate issues where applicable | |
| - Closed stale issues that are no longer relevant | |
| Triggered by: ${{ github.event_name }} | |
| Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>" | |
| git push |