Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/automated_pr_review.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Automated Code Review

# TODO: Eventually, use pull_request_target instead of pull_request.
# pull_request_target runs in the base branch context and has access
# to secrets (like GEMINI_API_KEY) even for fork PRs.
# Using pull_request for now during setup/testing.
on:
pull_request:
types: [opened]
pull_request_review_comment:
types: [created]

permissions:
contents: read
pull-requests: read

jobs:
review:
runs-on: ubuntu-latest
# Trigger only if:
# 1. It is a pull_request event, it is NOT a draft, and the author is a maintainer
# (OWNER, MEMBER, or COLLABORATOR).
# 2. OR it is a pull_request_review_comment event, the comment body has a line starting with "/review",
# and the commenter is a maintainer.
if: >
(github.event_name == 'pull_request' && !github.event.pull_request.draft &&
contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)) ||
(github.event_name == 'pull_request_review_comment' &&
(startsWith(github.event.comment.body, '/review') || contains(github.event.comment.body, '\n/review')) &&
contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association))
steps:
- name: Checkout PR Branch
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false

- name: Checkout Reviewbot (Base Branch)
uses: actions/checkout@v7
with:
sparse-checkout: |
tools/private/reviewbot
path: reviewbot

- name: Install uv
uses: astral-sh/setup-uv@v8.3.0

- name: Set up Python
run: uv python install 3.13

- name: Install Dependencies
run: |
uv pip install google-antigravity requests

- name: Run Antigravity Review
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
uv run reviewbot/tools/private/reviewbot/antigravity_review.py \
--prompt reviewbot/tools/private/reviewbot/prompt.txt
48 changes: 48 additions & 0 deletions tools/private/reviewbot/antigravity_review.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import argparse
import asyncio
from pathlib import Path

from google.antigravity import Agent, CapabilitiesConfig, LocalAgentConfig


def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("--prompt", required=True, help="Path to prompt file")
return parser.parse_args()


async def main():
args = parse_args()

# Read prompt file
prompt = Path(args.prompt).read_text()

# Initialize the Antigravity Agent in read-only mode for security.
# Register the review-pr skill from the local reviewbot folder.
config = LocalAgentConfig(
skills_paths=["tools/private/reviewbot/skills/review-pr"],
capabilities=CapabilitiesConfig(
allow_filesystem_read=True,
allow_filesystem_write=False,
allow_network=False,
),
)

# General coordinator instructions for the reviewer agent.
system_instructions = (
"You are a code review assistant. Use your available skills to perform "
"reviews on pull requests."
)

async with Agent(config, system_instructions=system_instructions) as agent:
response = await agent.chat(prompt)
report = await response.text()

print("--- REVIEW REPORT GENERATED ---")
print(report)

# TODO: Use GITHUB_TOKEN to post the report back to the PR comments.


if __name__ == "__main__":
asyncio.run(main())
3 changes: 3 additions & 0 deletions tools/private/reviewbot/prompt.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Use the review-pr skill to review the files modified in this pull request.
Summarize your findings and suggest specific, actionable improvements.
Group your findings into clear, descriptive nits or suggestions.
52 changes: 52 additions & 0 deletions tools/private/reviewbot/skills/review-pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: review-pr
description: Perform a read-only code review on a pull request.
---

# review-pr

You are an expert Starlark, Python, and Bazel code reviewer. Analyze the changed files for
correctness, edge cases, and performance. Focus strictly on logical
correctness, concurrency safety, system architecture, performance bottlenecks,
and resource management. Do not comment on style nits or formatting issues
that an automated formatter can handle. Be constructive and concise.

For every issue or improvement you identify, you MUST output the finding in the
GitHub Actions workflow command warning format. Specify the exact file path
and line numbers that the comment applies to.

Format each finding exactly as a single line to stdout matching this template:
`::warning file={file_path},line={line_number},endLine={end_line},title={category}::{comment_body}`

Where:
* `file_path` is the relative file path from the repository root.
* `line_number` is the starting line number in the file where the comment applies.
* `end_line` is the ending line number in the file where the comment applies (equal to line_number if the issue is on a single line).
* `category` is a short tag for the type of issue (e.g., "Error Handling", "Correctness", "Performance").
* `comment_body` is your constructive and concise feedback.

Do not write any markdown commentary outside of these GHA command formatted lines.

Follow these checklists during your review:

### General Quality & Architecture Checklist
* **PR Description Audit**: Verify the description contains the Why
(business/technical reason), a brief high level overview of changes,
Issue/Bug Link, and explicit Testing Evidence.
* **Separation of Concerns**: Suggest extracting large hardcoded data structures
(e.g., massive templates, complex regexes) to resource files.
* **Logic Correctness**: Verify calculations, negative values, division-by-zero,
and null safety before member access.
* **Error Handling**: Flag silent failures (e.g., empty except blocks) and
unconditional defaults that override configs.
* **Deterministic Operations**: Sort collections/keys to guarantee
reproducible/deterministic execution.

### Skeptical Critic (Adversarial Specialist Review)
* **Dynamic Filtering**: Filter the PR diff and run only the specialist checks
that have relevant files changed (e.g. skip the C++ checks if only Python
files are modified).
* **Specialist Review Pillars**: Run parallel audits focusing on:
1. Crash Regression: Null safety and resource lifecycle.
2. Performance & Latency: Thread bottlenecks, locks, and network calls.
3. Test Integrity: Coverage validity, change detectors defense.