Spaces:
Sleeping
Sleeping
| # PR Review Bot | |
| Automated PR review system using Claude Code. Runs as a cron job to review open PRs. | |
| ## Architecture | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β Cron (every 6 hours) β | |
| β pr-review-cron-wrapper.sh β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β Claude Code β | |
| β 1. Calls pr_tracker.py --list --since 6h β | |
| β 2. Spawns alignment-reviewer subagent for each PR β | |
| β 3. Posts reviews via pr_tracker.post_review() β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ``` | |
| **Key insight**: Claude handles orchestration. The only code needed is `pr_tracker.py` for GitHub API access. | |
| ## Files | |
| | File | Purpose | | |
| |------|---------| | |
| | `pr_tracker.py` | GitHub API wrapper (PyGithub) - fetches PRs, posts reviews | | |
| | `pr-review-cron-wrapper.sh` | Cron entry point - invokes Claude | | |
| ## Quick Start | |
| ### 1. Install PyGithub | |
| ```bash | |
| pip install PyGithub | |
| ``` | |
| ### 2. Test the Tracker | |
| ```bash | |
| # List PRs updated in last 6 hours | |
| python3 scripts/pr_tracker.py --list --since 6h | |
| # List PRs updated in last day | |
| python3 scripts/pr_tracker.py --list --since 1d | |
| # Get details for a specific PR | |
| python3 scripts/pr_tracker.py --details 123 | |
| ``` | |
| ### 3. Test a Review (manually) | |
| ```bash | |
| claude "Review PR #123 using the alignment-reviewer agent. | |
| Use scripts/pr_tracker.py to get PR details and post the review." | |
| ``` | |
| ### 4. Set Up Cron | |
| ```bash | |
| crontab -e | |
| # Add this line | |
| 0 */6 * * * /home/davidet/OpenEnv/scripts/pr-review-cron-wrapper.sh >> ~/.openenv-review-cron.log 2>&1 | |
| ``` | |
| ## pr_tracker.py API | |
| ```python | |
| from scripts.pr_tracker import ( | |
| get_prs_needing_review, | |
| get_pr_details, | |
| post_review, | |
| parse_since, | |
| ) | |
| # Get PRs updated in last 6 hours | |
| since = parse_since("6h") | |
| prs = get_prs_needing_review(since=since) | |
| # Returns: [{"number": 123, "title": "...", "updated_at": "...", ...}] | |
| # Get detailed info about a PR | |
| details = get_pr_details(123) | |
| # Returns: {"number": 123, "files": [...], "body": "...", ...} | |
| # Post a review | |
| post_review(pr_number=123, verdict="approve", body="LGTM!") | |
| ``` | |
| ## Filtering | |
| PRs are filtered by update time using `--since`: | |
| - `6h` - last 6 hours | |
| - `1d` - last day | |
| - `2w` - last 2 weeks | |
| - `2024-01-13T00:00:00Z` - since specific timestamp | |
| The cron job runs every 6 hours with `--since 6h`, so it reviews any PR that was updated since the last run. | |
| ## Review Model | |
| | Issues Found | Verdict | | |
| |--------------|---------| | |
| | Tier 1 issues (bugs, lint, security) | `request_changes` | | |
| | Only Tier 2 flags (alignment concerns) | `comment` | | |
| | No issues | `approve` | | |
| ## Logs | |
| ```bash | |
| tail -50 ~/.openenv-review-cron.log | |
| ``` | |