Skip to content

Commit 65d35a1

Browse files
committed
feat: add scheduled issue checkup workflow
Add org-issue-checkup.yml for periodic issue hygiene: - Scans open issues for missing labels or incomplete descriptions - Adds needs-info label to issues requiring human input - Claude comments with specific asks to move issues forward - Runs on schedule (weekly) or manual trigger - Non-destructive: never implements, only triages Also adds: - Workflow template for other repos - Documentation in README - needs-info status label
1 parent e5d7753 commit 65d35a1

3 files changed

Lines changed: 275 additions & 0 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Issue Checkup
2+
3+
on:
4+
# Run weekly on Mondays at 9am UTC
5+
schedule:
6+
- cron: '0 9 * * 1'
7+
8+
# Allow manual trigger
9+
workflow_dispatch:
10+
inputs:
11+
max_issues:
12+
description: 'Maximum number of issues to process'
13+
required: false
14+
default: '20'
15+
type: string
16+
17+
permissions:
18+
contents: read
19+
issues: write
20+
actions: read
21+
id-token: write
22+
23+
jobs:
24+
checkup:
25+
uses: happyvertical/.github/.github/workflows/org-issue-checkup.yml@main
26+
with:
27+
max_issues: ${{ github.event.inputs.max_issues && fromJSON(github.event.inputs.max_issues) || 20 }}
28+
stale_days: 7
29+
# Uncomment and set your project board ID if using GitHub Projects
30+
# project_id: 'PVT_your_project_id'
31+
secrets:
32+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
33+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
name: Org Issue Checkup
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
max_issues:
7+
description: 'Maximum number of issues to process'
8+
required: false
9+
type: number
10+
default: 20
11+
stale_days:
12+
description: 'Days before an untriaged issue is considered stale'
13+
required: false
14+
type: number
15+
default: 7
16+
project_id:
17+
description: 'GitHub Projects board ID'
18+
required: false
19+
type: string
20+
default: ''
21+
secrets:
22+
CLAUDE_CODE_OAUTH_TOKEN:
23+
description: 'Claude Code OAuth token'
24+
required: true
25+
GH_TOKEN:
26+
description: 'GitHub token for API access'
27+
required: true
28+
29+
permissions:
30+
contents: read
31+
issues: write
32+
actions: read
33+
id-token: write
34+
35+
jobs:
36+
find-issues:
37+
runs-on: arc-happyvertical
38+
timeout-minutes: 5
39+
outputs:
40+
issues: ${{ steps.scan.outputs.issues }}
41+
count: ${{ steps.scan.outputs.count }}
42+
steps:
43+
- name: Scan for Issues Needing Attention
44+
id: scan
45+
env:
46+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
47+
run: |
48+
echo "Scanning for issues needing attention..."
49+
50+
# Get all open issues
51+
ISSUES=$(gh issue list --state open --limit 100 --json number,title,labels,createdAt,body)
52+
53+
# Find issues missing required labels or with short descriptions
54+
NEEDS_ATTENTION=$(echo "$ISSUES" | jq -c '[.[] | select(
55+
# Missing type label
56+
([.labels[].name | select(startswith("type:"))] | length) == 0 or
57+
# Missing priority label
58+
([.labels[].name | select(startswith("priority:"))] | length) == 0 or
59+
# Missing size label
60+
([.labels[].name | select(startswith("size:"))] | length) == 0 or
61+
# Short description (less than 50 chars)
62+
((.body // "") | length) < 50
63+
)] | .[0:${{ inputs.max_issues }}]')
64+
65+
COUNT=$(echo "$NEEDS_ATTENTION" | jq 'length')
66+
67+
echo "Found $COUNT issues needing attention"
68+
echo "issues=$(echo $NEEDS_ATTENTION | jq -c '.')" >> $GITHUB_OUTPUT
69+
echo "count=$COUNT" >> $GITHUB_OUTPUT
70+
71+
checkup:
72+
needs: find-issues
73+
if: needs.find-issues.outputs.count != '0'
74+
runs-on: arc-happyvertical
75+
timeout-minutes: 30
76+
steps:
77+
- name: Checkout repository
78+
uses: actions/checkout@v4
79+
with:
80+
fetch-depth: 1
81+
82+
- name: Post Checkup Summary
83+
env:
84+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
85+
run: |
86+
echo "## Issue Checkup Report" >> $GITHUB_STEP_SUMMARY
87+
echo "" >> $GITHUB_STEP_SUMMARY
88+
echo "Found **${{ needs.find-issues.outputs.count }}** issues needing attention." >> $GITHUB_STEP_SUMMARY
89+
echo "" >> $GITHUB_STEP_SUMMARY
90+
echo "Processing with Claude..." >> $GITHUB_STEP_SUMMARY
91+
92+
- name: Run Claude Issue Checkup
93+
uses: anthropics/claude-code-action@v1
94+
with:
95+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
96+
timeout_minutes: 25
97+
prompt: |
98+
REPO: ${{ github.repository }}
99+
STALE_DAYS: ${{ inputs.stale_days }}
100+
101+
You are performing a scheduled issue checkup/hygiene scan.
102+
103+
## Issues Needing Attention
104+
105+
The following issues need review:
106+
```json
107+
${{ needs.find-issues.outputs.issues }}
108+
```
109+
110+
## Your Tasks
111+
112+
For EACH issue above:
113+
114+
### 1. Read the Issue
115+
```bash
116+
gh issue view <number>
117+
```
118+
119+
### 2. Analyze What's Missing
120+
121+
Check for:
122+
- **Type label**: bug, feature, docs, maintenance, research, question
123+
- **Priority label**: critical, high, medium, low, icebox
124+
- **Size label**: xs, s, m, l, xl
125+
- **Description quality**: Is it clear what needs to be done?
126+
127+
### 3. Add Missing Labels
128+
129+
If you can determine the appropriate labels from the issue content, add them:
130+
```bash
131+
gh issue edit <number> --add-label "type: X,priority: Y,size: Z"
132+
```
133+
134+
### 4. Add "needs-info" Label If Unclear
135+
136+
If the issue lacks enough information to determine labels or next steps:
137+
```bash
138+
gh issue edit <number> --add-label "needs-info"
139+
```
140+
141+
### 5. Post a Helpful Comment
142+
143+
For issues that need human input, post a comment like:
144+
```
145+
## Issue Checkup
146+
147+
This issue was flagged during our scheduled review.
148+
149+
**Status**: [what's missing or unclear]
150+
151+
**To move forward**, please:
152+
- [specific ask 1]
153+
- [specific ask 2]
154+
155+
Once updated, remove the `needs-info` label and the issue will be ready for work.
156+
157+
---
158+
*Automated checkup by Claude*
159+
```
160+
161+
## Important Rules
162+
163+
- DO NOT implement anything - this is checkup only
164+
- DO NOT add `agent: claude` label
165+
- DO NOT create branches or PRs
166+
- Be helpful and specific in comments
167+
- Skip issues that already have all required labels AND adequate description
168+
- If an issue is fine, don't comment on it
169+
170+
## Summary
171+
172+
After processing all issues, output a summary:
173+
- How many issues were updated
174+
- How many need human attention (needs-info)
175+
- How many were already fine
176+
177+
allowed_tools: |
178+
Bash(gh issue:*),Bash(gh search:*),Read,Grep,Glob
179+
180+
report:
181+
needs: [find-issues, checkup]
182+
if: always() && needs.find-issues.outputs.count != '0'
183+
runs-on: arc-happyvertical
184+
timeout-minutes: 5
185+
steps:
186+
- name: Generate Report
187+
env:
188+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
189+
run: |
190+
echo "## Issue Checkup Complete" >> $GITHUB_STEP_SUMMARY
191+
echo "" >> $GITHUB_STEP_SUMMARY
192+
echo "Processed ${{ needs.find-issues.outputs.count }} issues." >> $GITHUB_STEP_SUMMARY
193+
echo "" >> $GITHUB_STEP_SUMMARY
194+
echo "View the checkup job logs for details." >> $GITHUB_STEP_SUMMARY
195+
196+
no-issues:
197+
needs: find-issues
198+
if: needs.find-issues.outputs.count == '0'
199+
runs-on: arc-happyvertical
200+
timeout-minutes: 1
201+
steps:
202+
- name: Report Clean State
203+
run: |
204+
echo "## Issue Checkup Complete" >> $GITHUB_STEP_SUMMARY
205+
echo "" >> $GITHUB_STEP_SUMMARY
206+
echo "All issues are properly triaged. No action needed." >> $GITHUB_STEP_SUMMARY

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This repository contains organization-wide GitHub configuration, reusable workfl
66

77
The HappyVertical organization uses Claude Code Action for automated:
88
- **Issue triage** - Categorize, prioritize, and size new issues
9+
- **Issue checkup** - Scheduled hygiene scan to catch issues needing attention
910
- **@claude mentions** - AI assistance in issues and PRs
1011
- **CI failure auto-fix** - Automatically fix failing CI builds
1112
- **Test failure analysis** - Analyze and detect flaky tests
@@ -111,6 +112,38 @@ Full implementation automation triggered by `agent: claude` label:
111112
5. Creates pull request
112113
6. Updates issue status
113114

115+
### Issue Checkup (`org-issue-checkup.yml`)
116+
117+
Scheduled hygiene workflow to catch issues that slipped through triage:
118+
- Runs weekly (configurable) or on-demand via manual trigger
119+
- Scans all open issues for missing labels or incomplete descriptions
120+
- Adds `needs-info` label to issues requiring human input
121+
- Claude comments with specific asks to move issues forward
122+
- Non-destructive: never implements, only triages and flags
123+
124+
**Caller example:**
125+
```yaml
126+
name: Issue Checkup
127+
on:
128+
schedule:
129+
- cron: '0 9 * * 1' # Weekly on Mondays
130+
workflow_dispatch:
131+
inputs:
132+
max_issues:
133+
description: 'Maximum issues to process'
134+
default: '20'
135+
136+
jobs:
137+
checkup:
138+
uses: happyvertical/.github/.github/workflows/org-issue-checkup.yml@main
139+
with:
140+
max_issues: ${{ github.event.inputs.max_issues && fromJSON(github.event.inputs.max_issues) || 20 }}
141+
stale_days: 7
142+
secrets:
143+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
144+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
145+
```
146+
114147
## Claude Commands
115148

116149
The `.claude/commands/` directory contains prompts for Claude:
@@ -154,6 +187,9 @@ The `.claude/commands/` directory contains prompts for Claude:
154187
- `agent: testing` - AI testing in progress
155188
- `agent: review` - AI code review in progress
156189

190+
### Status Labels
191+
- `needs-info` - Issue needs more information before it can be worked on
192+
157193
## Kanban Board Integration
158194

159195
The workflows integrate with GitHub Projects:

0 commit comments

Comments
 (0)