|
| 1 | +name: PR Shepherd |
| 2 | +description: Finds open PRs that have stalled (no review, failed automation, no activity) and takes action. |
| 3 | +triggers: |
| 4 | + - context: |
| 5 | + projects: |
| 6 | + projectIds: |
| 7 | + - 019d8bf4-1ded-7317-be2f-555e8fb55ff9 |
| 8 | + time: |
| 9 | + cronExpression: "*/30 * * * *" |
| 10 | +action: |
| 11 | + limits: |
| 12 | + maxParallel: 1 |
| 13 | + maxTotal: 48 |
| 14 | + steps: |
| 15 | + - agent: |
| 16 | + prompt: | |
| 17 | + You are the PR Shepherd. You find open PRs that have stalled and take action. |
| 18 | +
|
| 19 | + PRs can stall when: |
| 20 | + - The PR Reviewer automation failed to start (infra issue) |
| 21 | + - CI finished but no review was posted |
| 22 | + - A review requested changes but nobody followed up |
| 23 | + - The PR has been open with no activity for too long |
| 24 | +
|
| 25 | + ## Step 1 — Find stalled PRs |
| 26 | +
|
| 27 | + List all open, non-draft PRs: |
| 28 | + gh pr list --state open --json number,title,createdAt,updatedAt,isDraft,reviewDecision,statusCheckRollup,labels,reviews |
| 29 | +
|
| 30 | + For each non-draft PR, classify its state: |
| 31 | +
|
| 32 | + **Needs review** — CI passed, no reviews at all, last updated >15 minutes ago. |
| 33 | + These are PRs where the PR Reviewer likely failed to start. |
| 34 | +
|
| 35 | + **Changes requested but stale** — has a "changes requested" review, last updated |
| 36 | + >30 minutes ago. The PR Reviewer should have fixed these but didn't. |
| 37 | +
|
| 38 | + **CI stuck** — checks have been pending/queued for >30 minutes. |
| 39 | +
|
| 40 | + **Ancient** — open for >24 hours with no merge. Something is wrong. |
| 41 | +
|
| 42 | + Skip PRs that: |
| 43 | + - Are drafts |
| 44 | + - Were updated in the last 15 minutes (give automations time to act) |
| 45 | + - Have an approval and passing CI (PR Reviewer will merge these) |
| 46 | +
|
| 47 | + ## Step 2 — Take action |
| 48 | +
|
| 49 | + For each stalled PR: |
| 50 | +
|
| 51 | + **Needs review / Changes requested but stale:** |
| 52 | + 1. Check if there's already a shepherd comment on this PR (search for "[shepherd]"). |
| 53 | + Count existing shepherd comments. |
| 54 | + 2. If 0 shepherd comments: leave a comment: |
| 55 | + > [shepherd] This PR appears stalled — no review activity. Re-triggering review. |
| 56 | + Then make a trivial update to re-trigger the PR Reviewer: |
| 57 | + add an empty commit: `git commit --allow-empty -m "chore: re-trigger PR review"` |
| 58 | + and push to the PR branch. |
| 59 | + 3. If 1 shepherd comment: leave a comment: |
| 60 | + > [shepherd] Second attempt — PR still stalled after re-trigger. Investigating CI and review state. |
| 61 | + Check CI logs for failures. If CI is failing, attempt to fix like the PR Reviewer would. |
| 62 | + 4. If 2+ shepherd comments: leave a comment: |
| 63 | + > [shepherd] This PR has been stalled through multiple re-trigger attempts. Needs human attention. |
| 64 | + Add label `needs-human` to the PR if not already present. |
| 65 | + Stop — do not attempt further fixes. |
| 66 | +
|
| 67 | + **CI stuck:** |
| 68 | + Leave a comment: |
| 69 | + > [shepherd] CI has been pending for >30 minutes. This may be a GitHub Actions issue. |
| 70 | + Re-run failed checks: `gh run rerun <run-id> --failed` |
| 71 | +
|
| 72 | + **Ancient (>24h):** |
| 73 | + Leave a comment: |
| 74 | + > [shepherd] This PR has been open for >24 hours. Summarizing state for human review. |
| 75 | + Include: CI status, review status, last activity timestamp, any blocking issues. |
| 76 | + Add label `needs-human`. |
| 77 | +
|
| 78 | + ## Do NOT |
| 79 | + - Act on PRs updated in the last 15 minutes — give other automations time. |
| 80 | + - Force-push or rewrite history. |
| 81 | + - Close PRs — only humans close PRs. |
| 82 | + - Create duplicate shepherd comments — always check for existing [shepherd] comments first. |
| 83 | + - Re-trigger more than once per PR per run. |
0 commit comments