diff --git a/.github/workflows/automated_pr_review.yaml b/.github/workflows/automated_pr_review.yaml deleted file mode 100644 index ec243aee93..0000000000 --- a/.github/workflows/automated_pr_review.yaml +++ /dev/null @@ -1,104 +0,0 @@ -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: - issue_comment: - types: [created] - -permissions: - contents: read - pull-requests: read - -jobs: - # Always runs so the workflow run exits cleanly without a "No jobs ran" error - # when the review job's if-condition evaluates to false. - noop: - runs-on: ubuntu-latest - steps: - - name: Workflow trigger check - run: echo "Workflow triggered successfully." - - # Job 1: Runs without secrets to extract the git diff from untrusted PR code. - # Keeps GEMINI_API_KEY away from any environment that checks out untrusted PR files. - prepare_diff: - runs-on: ubuntu-latest - if: > - github.event_name == 'issue_comment' && github.event.issue.pull_request != null && - (startsWith(github.event.comment.body, '/review') || - contains(github.event.comment.body, '\n/review') || - contains(github.event.comment.body, '\r\n/review')) && - contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) - steps: - - name: Checkout PR Branch (Data Only) - uses: actions/checkout@v7 - with: - ref: refs/pull/${{ github.event.pull_request.number || github.event.issue.number }}/head - path: untrusted_pr_head - persist-credentials: false - - - name: Fetch Base Branch and Negotiate Minimal Diff History - env: - PR_COMMITS: ${{ github.event.pull_request.commits }} - run: | - cd untrusted_pr_head - # 1. Fetch the tip of main - git fetch origin main:refs/remotes/origin/main --depth=1 - - # 2. Check if we already have the merge base (common ancestor) - if ! git merge-base origin/main HEAD >/dev/null 2>&1; then - # If we know the exact number of commits in the PR, deepen by (PR_COMMITS + 10) - if [ -n "$PR_COMMITS" ] && [ "$PR_COMMITS" != "null" ]; then - git fetch --deepen="$((PR_COMMITS + 10))" - fi - # 3. If it's an issue_comment event (where PR_COMMITS is null) or still shallow, unshallow/deepen - if ! git merge-base origin/main HEAD >/dev/null 2>&1; then - git fetch --unshallow || git fetch --deepen=50 - fi - fi - git diff origin/main...HEAD > ../pr_diff.txt - - # Upload extracted diff as artifact to pass to Job 2 safely as text data. - - name: Upload Diff Artifact - uses: actions/upload-artifact@v7 - with: - name: pr_diff - path: pr_diff.txt - - # Job 2: Runs with secrets in base branch context. - review: - needs: prepare_diff - runs-on: ubuntu-latest - steps: - - name: Download Diff Artifact - uses: actions/download-artifact@v8 - with: - name: pr_diff - - # Check out reviewbot into a separate directory to isolate base branch tool code. - - name: Checkout Reviewbot (Base Branch Only) - uses: actions/checkout@v7 - with: - sparse-checkout: | - tools/private/reviewbot - path: reviewbot - - - name: Install uv - uses: astral-sh/setup-uv@v10.0.1 - - - name: Run Antigravity Review - # Run inside reviewbot directory so execution context is the trusted base branch. - # This also helps prevent uv from looking for config files in locations it shouldn't, - # i.e. by default, uv will look in $PWD for a pyproject file to build. - working-directory: reviewbot - env: - GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Use --no-project to prevent uv from discovering or building pyproject.toml/setup.py - # in the workspace, ensuring only standalone script dependencies are resolved. - uv run --no-project --directory . tools/private/reviewbot/antigravity_review.py \ - --prompt tools/private/reviewbot/prompt.txt \ - --diff-file ../pr_diff.txt diff --git a/tools/private/README.md b/tools/private/README.md index 19b174e35c..ab2847d26b 100644 --- a/tools/private/README.md +++ b/tools/private/README.md @@ -2,7 +2,7 @@ This directory contains development-only tools used for maintaining and developing `rules_python` itself (such as release management, dependency -updating, review bots, and repository maintenance scripts). +updating, and repository maintenance scripts). Supporting tools for rules (e.g. `launcher`, `precompiler`, `zipapp`, `publish`, `wheelmaker`) belong as their own top-level directories under diff --git a/tools/private/reviewbot/antigravity_review.py b/tools/private/reviewbot/antigravity_review.py deleted file mode 100644 index 4ae0ef1690..0000000000 --- a/tools/private/reviewbot/antigravity_review.py +++ /dev/null @@ -1,88 +0,0 @@ -# /// script -# requires-python = ">=3.11" -# dependencies = [ -# "google-antigravity", -# ] -# /// -import argparse -import asyncio -import subprocess -from pathlib import Path - -from google.antigravity import Agent, CapabilitiesConfig, LocalAgentConfig -from google.antigravity.models import GeminiAPIEndpoint, ModelTarget -from google.antigravity.types import BuiltinTools - - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--prompt", required=True, help="Path to prompt file") - parser.add_argument("--diff-file", help="Path to pre-computed diff file") - return parser.parse_args() - - -def get_pr_diff(diff_file: str | None = None) -> str: - """Fetches the git diff for the current pull request against origin/main.""" - if diff_file and Path(diff_file).exists(): - return Path(diff_file).read_text() - try: - return subprocess.check_output( - ["git", "diff", "origin/main...HEAD"], text=True, stderr=subprocess.DEVNULL - ) - except Exception: - return "No diff could be automatically extracted via git commands." - - -async def main(): - args = parse_args() - - # Read prompt file and pre-hydrate with the exact PR code diff - base_prompt = Path(args.prompt).read_text() - diff_text = get_pr_diff(args.diff_file) - prompt = ( - f"{base_prompt}\n\n## Pull Request Git Diff\n" - f"Here is the exact code diff for this pull request:\n```diff\n{diff_text}\n```" - ) - - # 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." - ) - - # Create the default endpoint picking up GEMINI_API_KEY from the environment. - endpoint = GeminiAPIEndpoint() - - # Initialize the Antigravity Agent in read-only mode for security. - # Register the review-pr skill from the local reviewbot folder. - # Provide a comprehensive prioritized cascade across Gemini 3 models - # to automatically fall back if any model hits free-tier quota limits (429) - # or temporary unavailability. - config = LocalAgentConfig( - models=[ - ModelTarget(name="gemini-3.5-flash", endpoint=endpoint), - ModelTarget(name="gemini-3.1-pro-preview", endpoint=endpoint), - ModelTarget(name="gemini-3.1-flash-lite", endpoint=endpoint), - ModelTarget(name="gemini-3-pro-preview", endpoint=endpoint), - ModelTarget(name="gemini-flash-latest", endpoint=endpoint), - ModelTarget(name="gemini-pro-latest", endpoint=endpoint), - ], - system_instructions=system_instructions, - skills_paths=[str(Path(__file__).parent / "skills" / "review-pr" / "SKILL.md")], - capabilities=CapabilitiesConfig( - enabled_tools=BuiltinTools.read_only(), - ), - ) - - async with Agent(config) 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 deleted file mode 100644 index e406164af1..0000000000 --- a/tools/private/reviewbot/prompt.txt +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index 3182b14a77..0000000000 --- a/tools/private/reviewbot/skills/review-pr/SKILL.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: review-pr -description: Perform a read-only code review on a pull request. ---- - -# review-pr - -IMPORTANT: The exact git diff for the pull request is pre-provided right in your -prompt. Analyze this provided diff directly in a single pass without calling -exploratory directory listing or file reading tools unless you specifically need -surrounding lines of context from a modified file. - -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. -* **Workflow & Script Execution**: Verify workflow step scripts have - executable permissions (`chmod +x` / filemode `100755`) and shebangs. - -### 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.