
Smart PR Review Management_ A GitHub Action for Monorepos
#GitHub #GitHubActions #Monorepo #PullRequests
By Rotem Kalman
When a PR in a monorepo touches multiple areas, GitHub gives you a binary choice: keep all approvals or dismiss them all. That breaks review integrity, slows teams down, and lets the wrong approvals stay in place. In this guide I’ll show a GitHub Action that automatically dismisses only the stale approvals from owners of files that actually changed, while keeping valid approvals intact—so your reviews stay fast, fair, and compliant.
Why GitHub’s PR Approvals Break in Monorepos
As a DevOps engineer working with large monorepos, I’ve often encountered a frustrating limitation in GitHub’s PR review system. When new commits are pushed to a PR, GitHub only offers two options:
- keep all approvals
- dismiss all approvals. This binary choice becomes particularly problematic in monorepos where multiple teams own different parts of the codebase
https://github.com/RotemK1/auto-unapprove
The Monorepo Scenario: Multiple Teams, One PR

Let me illustrate this with a real scenario from our monorepo:
Repository Structure:
/repo
/team-a/ # Owned by Team A
/frontend/
/api/
/team-b/ # Owned by Team B
/backend/
/database/
/team-c/ # Owned by Team C
/infrastructure/
/deployment/
When a PR touches multiple areas, we need approvals from different teams. For example:
- A developer changes files in both frontend and backend
- Team A approves the frontend changes
- Team B approves the backend changes
- The developer pushes new commits that only affect frontend files
At this point, GitHub gives us two options:
- Keep all approvals (including Team A’s – even though their files changed and their previous approval became stale.
- Dismiss all approvals (including Team B’s, even though their area wasn’t affected)
Neither option is ideal. The first option might allow code owners to approve their own changes, while the second option forces us to re-request approvals from teams whose code wasn’t even touched.
Round Robin ≠ Ownership: Where Assignments Fall Short
GitHub’s Round Robin feature automatically assigns reviewers to pull requests, rotating through team members to ensure fair distribution of review work. However, it doesn’t consider code ownership or handle stale reviews when new commits are pushed.
Our action complements Round Robin by:
- Ensuring code owners can’t approve their own changes
- Handling stale reviews when new commits are pushed
- Maintaining review integrity while Round Robin handles fair distribution
Together, Round Robin and our action create a robust review process:
- Round Robin: Fair distribution of review work
- Our Action: Code quality through proper review separation
The Solution: Auto-Unapprove Reviews by Actual Ownership
To solve this, I developed a GitHub Action called “Auto Unapprove Reviews” that provides granular control over review dismissals. Here’s how it works:
The action follows a simple but effective flow:
- Get PR information
- Check changed files
- Check team ownership
- Analyze review status
- Take appropriate action

Key Features
- Smart Dismissal
- Only dismisses approvals from code owners of changed files
- Preserves valid approvals from other teams
- Handles team-based ownership via CODEOWNERS
- Team Support
- Works with GitHub teams
- Supports hierarchical CODEOWNERS rules
- Validates team memberships
- Performance Optimized
- Parallel API calls
- Efficient team checking
- Smart caching
Real-World Impact
Since implementing this action, we’ve seen:
- Reduced review cycles (from 3-4 to 1-2 per PR)
- Better code quality through enforced review separation
- Improved team productivity
- Clearer ownership boundaries
How to Add the Action to Your Pipeline
name: Auto Unapprove
on:
pull_request:
types: [synchronize]
jobs:
auto-unapprove:
runs-on: ubuntu-latest
env:
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
# Need to create github app and allow him access to -
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.REVIEWS_APP_ID }}
private-key: ${{ secrets.REVIEWS_APP_PRIVATE_KEY }}
- name: Dismiss Stale Reviews
uses: RotemK1/auto-unapprove@main
with:
github-token: ${{ steps.app-token.outputs.token }}
pr-number: ${{ github.event.number }}
dry-run: 'false'
target-branch: ${{ github.event.pull_request.base.ref }}
team-start-with: '@your-org/'
https://github.com/RotemK1/auto-unapprove
What the Action Prints (Example)
Here’s a real-world example of how the action works:
🚀 Smart Review Dismissal
Repository: myorg/myrepo
PR: #123
Mode: 🧪 DRY RUN
📁 All changed files in PR (3):
📝 src/gui/components/Button.tsx
📝 src/gui/styles/theme.css
📝 src/gui/utils/helpers.ts
🎯 Target branch: main
👑 Parsed 15 CODEOWNERS rules
🎯 DISMISSAL ANALYSIS:
🕐 Checking commits after jane-smith's approval (2025-06-04T12:49:59.000Z)...
📅 Commit 55a4fc5 at 2025-06-04T12:53:44Z
🎯 Modified owned files: src/gui/components/Button.tsx
🚫 DISMISS @jane-smith
📁 Files: src/gui/components/Button.tsx, src/gui/styles/theme.css, src/gui/utils/helpers.ts
👑 Owner Via: @myorg/frontend-team
💡 Reason: Approval became stale - commits modified owned files
✅ KEEP @bob-jones
📄 Not owner of changed files
📊 EXECUTION PLAN:
• Changed files: 3
• Total approvals: 2
• Dismissals needed: 1
• Approvals preserved: 1
This example shows:
- Clear identification of changed files
- Detailed analysis of review status
- Smart dismissal of stale approvals
- Preservation of valid approvals
- Comprehensive execution plan
Best Practices for CODEOWNERS and Teams
- CODEOWNERS Setup
- Keep CODEOWNERS file up to date
- Use team-based ownership
- Document ownership boundaries
- Team Organization
- Use GitHub teams for code ownership
- Keep team membership current
- Clear team responsibilities
- Round Robin Configuration
- Set up Round Robin for each team
- Ensure team size is appropriate for review load
- Monitor review distribution
- Adjust team membership based on review capacity
- Workflow Integration
- Run on PR synchronization
- Add status checks
- Monitor action logs
Conclusion
This GitHub Action solves a real pain point in GitHub’s review system by providing granular control over review dismissals. It ensures:
- Code owners can’t approve their own changes
- Teams only need to re-review changes in their area
- The review process remains efficient and effective
The action works seamlessly with GitHub’s Round Robin review assignment, creating a robust review process where:
- Round Robin ensures fair distribution of review work
- Our action maintains code quality through proper review separation
- Together they provide a complete solution for monorepo review management
The action is open-source and available on GitHub. Feel free to try it out and contribute to its development. Whether you’re working in a small team or a large monorepo, this action can help streamline your review process while maintaining high code quality standards.