Skip to content

Commit 08db805

Browse files
balegasclaude
andauthored
ci: auto-approve durable streams PRs from its sole maintainer (#4693)
## Why I'm the only developer working on the durable streams project, so PRs that only touch that package have no natural reviewer. This adds a scoped exception so those PRs can merge without waiting on a teammate, while everything else in the repo keeps requiring a human review. ## What Adds a workflow that auto-approves a PR when **both** hold: - the PR is authored by `@balegas` (and not a draft), and - every changed file is inside `packages/durable-streams-rust/`. The approval comes from `github-actions[bot]`, so it satisfies the existing 1-approval branch protection (an author's own approval never would). Details: - Uses `pull_request_target`, so the workflow definition always runs from `main` — a PR can't modify the logic that's about to approve it. - If a later push brings in files outside the package, the workflow dismisses its own approval (the repo has `dismiss_stale_reviews` off, so a stale approval would otherwise survive the push). - The scoped paths live in a `scopes` array, easy to extend if the project grows to more packages. - No repo settings changes needed: "Allow GitHub Actions to create and approve pull requests" is already enabled. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent c259e7b commit 08db805

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Auto-approve durable streams PRs
2+
3+
# The durable streams package has a single maintainer, so PRs that only
4+
# touch it are auto-approved to satisfy the 1-review branch protection.
5+
# Uses pull_request_target so the workflow definition always comes from
6+
# main and cannot be modified by the PR under review.
7+
on:
8+
pull_request_target:
9+
types: [opened, synchronize, reopened, ready_for_review]
10+
11+
permissions:
12+
pull-requests: write
13+
14+
jobs:
15+
auto-approve:
16+
if: github.event.pull_request.user.login == 'balegas' && !github.event.pull_request.draft
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Approve if all changes are within the durable streams package
20+
env:
21+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22+
REPO: ${{ github.repository }}
23+
PR: ${{ github.event.pull_request.number }}
24+
run: |
25+
scopes=(
26+
"packages/durable-streams-rust/"
27+
)
28+
29+
in_scope=true
30+
while IFS= read -r file; do
31+
matched=false
32+
for scope in "${scopes[@]}"; do
33+
[[ "$file" == "$scope"* ]] && matched=true && break
34+
done
35+
if ! $matched; then
36+
echo "Out of scope: $file"
37+
in_scope=false
38+
fi
39+
done < <(gh api --paginate "repos/$REPO/pulls/$PR/files" --jq '.[].filename')
40+
41+
bot_approval=$(gh api --paginate "repos/$REPO/pulls/$PR/reviews" \
42+
--jq '[.[] | select(.user.login == "github-actions[bot]" and .state == "APPROVED")] | last | .id // empty')
43+
44+
if $in_scope; then
45+
if [[ -z "$bot_approval" ]]; then
46+
gh pr review "$PR" --repo "$REPO" --approve \
47+
--body "Auto-approved: all changes are within the durable streams package."
48+
else
49+
echo "Already approved."
50+
fi
51+
elif [[ -n "$bot_approval" ]]; then
52+
# A later push brought out-of-scope files in; retract the approval
53+
# since stale reviews are not dismissed automatically.
54+
gh api -X PUT "repos/$REPO/pulls/$PR/reviews/$bot_approval/dismissals" \
55+
-f message="Dismissed: PR now touches files outside the durable streams package." \
56+
-f event="DISMISS"
57+
else
58+
echo "PR touches files outside the durable streams package; no auto-approval."
59+
fi

0 commit comments

Comments
 (0)