GC-301h · Module 2
PR Review Bots
3 min read
A PR review bot runs Gemini CLI on every pull request, posts inline comments on problematic lines, and provides an overall summary. The architecture: a GitHub Actions workflow triggers on pull_request events, runs gemini -p with the PR diff as input, parses the structured JSON output into GitHub review comments, and posts them via the GitHub API. The bot appears as a reviewer on the PR — providing instant feedback while human reviewers handle the nuanced review.
Effective PR review bots require prompt engineering tuned for precision over recall. A bot that flags every line with a minor style suggestion becomes noise that developers ignore. The prompt should focus on high-signal issues: bugs, security vulnerabilities, logic errors, missing error handling, and breaking API changes. Style and formatting issues belong in linters, not AI review. The prompt should also include project-specific context — pull from GEMINI.md so the bot understands your architecture and conventions.
#!/bin/bash
# PR review bot — posts inline comments via GitHub API
set -euo pipefail
PR_NUMBER="$1"
DIFF=$(git diff origin/main...HEAD)
# Get structured review from Gemini
REVIEW=$(gemini -p "Review this PR diff. Focus only on bugs, security issues, and logic errors. Ignore style. Output JSON: {summary: string, comments: [{file: string, line: number, body: string, severity: \"critical\"|\"warning\"}]}\n\n$DIFF" \
--output-format json)
# Extract inner response
RESPONSE=$(echo "$REVIEW" | jq -r '.response')
# Post each comment via GitHub API
echo "$RESPONSE" | jq -c '.comments[]?' | while read -r comment; do
FILE=$(echo "$comment" | jq -r '.file')
LINE=$(echo "$comment" | jq -r '.line')
BODY=$(echo "$comment" | jq -r '.body')
SEVERITY=$(echo "$comment" | jq -r '.severity')
gh api "repos/{owner}/{repo}/pulls/$PR_NUMBER/comments" \
-f body="**[$SEVERITY]** $BODY" \
-f path="$FILE" \
-F line="$LINE" \
-f commit_id="$(git rev-parse HEAD)" \
-f subject_type="line"
done
# Post summary
SUMMARY=$(echo "$RESPONSE" | jq -r '.summary // "No issues found."')
gh pr comment "$PR_NUMBER" --body "## Gemini Review\n\n$SUMMARY"