Files
review-bot/README.md
T
Rodin 6ccbf17286
CI / test (pull_request) Successful in 14s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m12s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m20s
docs: comprehensive README with action usage, cleanup behavior, custom prompts
- Quick start example with composite action + matrix strategy
- Full action inputs table with descriptions
- How sentinel-based cleanup works (explains the reviewer-name concept)
- Custom prompt file usage with security review example
- CLI usage with all flags
- Environment variables table
- Token scopes documentation
- Setup guide for new repos
2026-05-01 20:58:30 -07:00

6.6 KiB

review-bot

AI-powered code review bot for Gitea pull requests. Fetches diff + context, sends to an LLM, and posts a structured review (APPROVE / REQUEST_CHANGES) back to the PR.

Features

  • Multi-provider: OpenAI-compatible and Anthropic Messages API
  • Context-aware: Fetches full file content, conventions, language patterns, CI status
  • Smart budget: Automatically trims context to fit model token limits
  • Idempotent reviews: Deletes previous review before posting new one (one review per bot)
  • Custom prompts: Load additional instructions from a file (e.g. security-focused review)
  • Zero dependencies: Go stdlib only

Quick Start: Composite Action

The easiest way to use review-bot in your Gitea CI:

# .gitea/workflows/review.yml
name: Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        include:
          - name: code-review
            model: gpt-4.1
            token_secret: REVIEW_TOKEN
          - name: security
            model: gpt-4.1
            token_secret: REVIEW_TOKEN
            system_prompt_file: SECURITY_REVIEW.md
    steps:
      - uses: actions/checkout@v4
      - uses: https://gitea.weiker.me/rodin/review-bot/.gitea/actions/review@v0.1.0
        with:
          reviewer-token: ${{ secrets[matrix.token_secret] }}
          reviewer-name: ${{ matrix.name }}
          llm-base-url: ${{ secrets.LLM_BASE_URL }}
          llm-api-key: ${{ secrets.LLM_API_KEY }}
          llm-model: ${{ matrix.model }}
          conventions-file: CONVENTIONS.md
          system-prompt-file: ${{ matrix.system_prompt_file }}

Action Inputs

Input Required Default Description
reviewer-token Yes Gitea token for posting reviews (needs write:issue, write:repository)
reviewer-name No "" Logical identity for this reviewer. Used as sentinel for idempotent cleanup. Set this when running multiple review bots on the same PR.
llm-base-url Yes LLM API base URL
llm-api-key Yes LLM API key
llm-model Yes Model name
llm-provider No openai API provider: openai or anthropic
conventions-file No "" Path to coding conventions file in the repo
patterns-repo No "" Comma-separated repos with language patterns (e.g. rodin/go-patterns)
patterns-files No README.md Files/directories to fetch from pattern repos
system-prompt-file No "" Local file with additional system prompt instructions
temperature No 0 LLM temperature (0 = server default)
timeout No 300 LLM request timeout in seconds
dry-run No false Print review to stdout instead of posting
update-existing No true Delete previous review from same bot before posting. Accepts: true/1/yes or false/0/no
version No latest review-bot version to install

How Review Cleanup Works

When reviewer-name is set, the bot embeds a hidden sentinel in each review:

<!-- review-bot:code-review -->

On the next run, it finds and deletes any review containing its own sentinel (except the one it just posted). This means:

  • One review per bot per PR — no clutter from repeated pushes
  • Multiple bots coexist — each only cleans up its own reviews
  • Same token, different roles — a single bot account can post "code-review" and "security" reviews without conflict
  • No extra permissions — identity comes from the sentinel, not the API

If reviewer-name is empty, cleanup is skipped (reviews stack like before).

Custom Review Prompts

Use --system-prompt-file to specialize the review focus. The file contents are appended to the base system prompt as "Additional Review Instructions."

Example SECURITY_REVIEW.md:

You are performing a security-focused code review.
Focus on: injection, auth bypass, secrets exposure, input validation, race conditions.
Only report findings with security implications. Ignore style and general quality.

This enables running multiple specialized reviews in parallel (code quality, security, performance) from a single workflow.

CLI Usage

review-bot \
  --gitea-url https://gitea.example.com \
  --repo owner/name \
  --pr 42 \
  --reviewer-token "$GITEA_TOKEN" \
  --reviewer-name "code-review" \
  --llm-base-url https://api.openai.com/v1 \
  --llm-api-key "$OPENAI_API_KEY" \
  --llm-model gpt-4.1 \
  --llm-provider openai \
  --conventions-file CONVENTIONS.md \
  --patterns-repo rodin/go-patterns \
  --patterns-files "README.md,patterns/" \
  --system-prompt-file SECURITY_REVIEW.md \
  --update-existing true \
  --llm-timeout 600

Environment Variables

All flags have environment variable equivalents:

Flag Env Var
--gitea-url GITEA_URL
--repo GITEA_REPO
--pr PR_NUMBER
--reviewer-token REVIEWER_TOKEN
--reviewer-name REVIEWER_NAME
--llm-base-url LLM_BASE_URL
--llm-api-key LLM_API_KEY
--llm-model LLM_MODEL
--llm-provider LLM_PROVIDER
--conventions-file CONVENTIONS_FILE
--patterns-repo PATTERNS_REPO
--patterns-files PATTERNS_FILES
--system-prompt-file SYSTEM_PROMPT_FILE
--llm-temperature LLM_TEMPERATURE
--llm-timeout LLM_TIMEOUT
--update-existing UPDATE_EXISTING

Setup

  1. Create a Gitea bot account (e.g. review-bot)
  2. Generate a token with scopes: write:issue, write:repository
  3. Add secrets to your Gitea repo (Settings → Actions → Secrets):
    • REVIEW_TOKEN — the bot's Gitea token
    • LLM_BASE_URL — your LLM endpoint
    • LLM_API_KEY — your LLM key
  4. Add the workflow (see Quick Start above)

Token Scopes Required

Scope Purpose
write:issue Post and delete reviews
write:repository Read PR diffs, file content, commit statuses

No read:user scope needed — the bot identifies itself from the review response.

Development

go test ./...        # Unit tests
go vet ./...         # Static analysis
go build -o review-bot ./cmd/review-bot

# Integration tests (requires env vars set)
go test -tags=integration ./...

Architecture

cmd/review-bot/     CLI entrypoint + orchestration
gitea/              Gitea API client (reviews, PRs, files)
llm/                Multi-provider LLM client (OpenAI + Anthropic)
review/             Prompt building, response parsing, formatting
budget/             Token estimation + context trimming

License

MIT