From 4632132a97af79bbb379f22925e6341696139c16 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Mon, 6 Jul 2026 05:22:07 +0000 Subject: [PATCH 1/2] feat: add Automated Code Review workflow Setup a read-only code review pipeline using the google-antigravity SDK and GitHub Actions. The workflow runs on pull_request and triggers on maintainer PR opens or /review comments. It runs the review-pr skill to evaluate code quality, correctness, and architecture, outputting findings as GHA warning annotations. --- .github/workflows/automated_pr_review.yml | 61 +++++++++++++++++++ tools/private/reviewbot/antigravity_review.py | 48 +++++++++++++++ tools/private/reviewbot/prompt.txt | 3 + .../reviewbot/skills/review-pr/SKILL.md | 52 ++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 .github/workflows/automated_pr_review.yml create mode 100644 tools/private/reviewbot/antigravity_review.py create mode 100644 tools/private/reviewbot/prompt.txt create mode 100644 tools/private/reviewbot/skills/review-pr/SKILL.md diff --git a/.github/workflows/automated_pr_review.yml b/.github/workflows/automated_pr_review.yml new file mode 100644 index 0000000000..23d4369b2a --- /dev/null +++ b/.github/workflows/automated_pr_review.yml @@ -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 diff --git a/tools/private/reviewbot/antigravity_review.py b/tools/private/reviewbot/antigravity_review.py new file mode 100644 index 0000000000..1bb23283be --- /dev/null +++ b/tools/private/reviewbot/antigravity_review.py @@ -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()) diff --git a/tools/private/reviewbot/prompt.txt b/tools/private/reviewbot/prompt.txt new file mode 100644 index 0000000000..e406164af1 --- /dev/null +++ b/tools/private/reviewbot/prompt.txt @@ -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. diff --git a/tools/private/reviewbot/skills/review-pr/SKILL.md b/tools/private/reviewbot/skills/review-pr/SKILL.md new file mode 100644 index 0000000000..18c998f9ed --- /dev/null +++ b/tools/private/reviewbot/skills/review-pr/SKILL.md @@ -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. From b989f78ca47603f5e54a143fe3b8184f3eb383a6 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Thu, 9 Jul 2026 02:59:50 +0000 Subject: [PATCH 2/2] style: use .yaml extension for workflow file Rename automated_pr_review.yml to automated_pr_review.yaml. --- .../{automated_pr_review.yml => automated_pr_review.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{automated_pr_review.yml => automated_pr_review.yaml} (100%) diff --git a/.github/workflows/automated_pr_review.yml b/.github/workflows/automated_pr_review.yaml similarity index 100% rename from .github/workflows/automated_pr_review.yml rename to .github/workflows/automated_pr_review.yaml