Add unit tests, integration test, CI workflow, and conventions
- gitea/client_test.go: mock HTTP tests for all API methods + error cases - llm/client_test.go: mock tests for completion, errors, timeouts - review/parser_test.go: JSON parsing, markdown fences, validation - review/formatter_test.go: markdown output, empty/multiple findings - review/prompt_test.go: system/user prompt construction - integration_test.go: full end-to-end flow (build tag: integration) - .gitea/workflows/ci.yml: test + vet + build on push, dual LLM review on PRs - CONVENTIONS.md: coding standards for self-review dogfooding - README.md: usage docs, env vars, architecture
This commit is contained in:
@@ -1,58 +1,91 @@
|
||||
# review-bot
|
||||
|
||||
AI-powered code review bot for Gitea pull requests.
|
||||
Automated code review bot for Gitea. Fetches a pull request diff, sends it to an LLM for analysis, and posts a structured review back to the PR.
|
||||
|
||||
## Overview
|
||||
## Features
|
||||
|
||||
`review-bot` fetches a PR's diff, title, description, and CI status from Gitea, sends it to an LLM via an OpenAI-compatible API, and posts a structured code review back to Gitea.
|
||||
- Fetches PR metadata, diff, and CI status from Gitea API
|
||||
- Sends context-rich prompts to any OpenAI-compatible LLM
|
||||
- Parses structured JSON review responses
|
||||
- Posts formatted reviews (APPROVE / REQUEST_CHANGES) back to Gitea
|
||||
- Supports custom coding conventions via repo files
|
||||
- Zero external dependencies — Go stdlib only
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
review-bot \
|
||||
--gitea-url https://gitea.weiker.me \
|
||||
--gitea-url https://gitea.example.com \
|
||||
--repo owner/name \
|
||||
--pr 123 \
|
||||
--reviewer-name "sonnet-review-bot" \
|
||||
--reviewer-token "$(cat /path/to/token)" \
|
||||
--llm-base-url "https://proxy.example.com/v1" \
|
||||
--llm-api-key "key" \
|
||||
--llm-model "anthropic--claude-4.6-sonnet" \
|
||||
--conventions-file "CLAUDE.md"
|
||||
--pr 42 \
|
||||
--reviewer-token "$GITEA_TOKEN" \
|
||||
--llm-base-url https://api.openai.com/v1 \
|
||||
--llm-api-key "$OPENAI_API_KEY" \
|
||||
--llm-model gpt-4 \
|
||||
--reviewer-name "Sonnet" \
|
||||
--conventions-file CONVENTIONS.md \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
All flags can also be set via environment variables:
|
||||
## Environment Variables
|
||||
|
||||
| Flag | Env Var |
|
||||
|------|---------|
|
||||
| `--gitea-url` | `GITEA_URL` |
|
||||
| `--repo` | `GITEA_REPO` |
|
||||
| `--pr` | `PR_NUMBER` |
|
||||
| `--reviewer-name` | `REVIEWER_NAME` |
|
||||
| `--reviewer-token` | `REVIEWER_TOKEN` |
|
||||
| `--llm-base-url` | `LLM_BASE_URL` |
|
||||
| `--llm-api-key` | `LLM_API_KEY` |
|
||||
| `--llm-model` | `LLM_MODEL` |
|
||||
| `--conventions-file` | `CONVENTIONS_FILE` |
|
||||
All flags can be set via environment variables:
|
||||
|
||||
Use `--dry-run` to print the review to stdout without posting.
|
||||
| Flag | Env Var | Required | Description |
|
||||
|------|---------|----------|-------------|
|
||||
| `--gitea-url` | `GITEA_URL` | Yes | Gitea instance base URL |
|
||||
| `--repo` | `GITEA_REPO` | Yes | Repository in `owner/name` format |
|
||||
| `--pr` | `PR_NUMBER` | Yes | Pull request number |
|
||||
| `--reviewer-token` | `REVIEWER_TOKEN` | Yes | Gitea API token for posting reviews |
|
||||
| `--llm-base-url` | `LLM_BASE_URL` | Yes | OpenAI-compatible API base URL |
|
||||
| `--llm-api-key` | `LLM_API_KEY` | Yes | LLM API key |
|
||||
| `--llm-model` | `LLM_MODEL` | Yes | Model identifier |
|
||||
| `--reviewer-name` | `REVIEWER_NAME` | No | Display name in review footer |
|
||||
| `--conventions-file` | `CONVENTIONS_FILE` | No | Path to conventions file in repo |
|
||||
| `--dry-run` | — | No | Print review to stdout instead of posting |
|
||||
|
||||
## Build
|
||||
## Adding to a Gitea Repository
|
||||
|
||||
1. Build the binary or use the CI workflow approach (build in CI).
|
||||
|
||||
2. Add secrets to your Gitea repo (Settings → Actions → Secrets):
|
||||
- `SONNET_REVIEW_TOKEN` — Gitea token for the Sonnet reviewer account
|
||||
- `GPT_REVIEW_TOKEN` — Gitea token for the GPT reviewer account
|
||||
- `LLM_BASE_URL` — Your LLM API endpoint
|
||||
- `LLM_API_KEY` — Your LLM API key
|
||||
|
||||
3. Copy `.gitea/workflows/ci.yml` to your repo (or adapt it).
|
||||
|
||||
4. On every PR, the bot will:
|
||||
- Run tests and vet
|
||||
- Build review-bot
|
||||
- Post reviews from each configured LLM reviewer
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
go test ./...
|
||||
|
||||
# Run vet
|
||||
go vet ./...
|
||||
|
||||
# Build
|
||||
go build -o review-bot ./cmd/review-bot
|
||||
|
||||
# Integration tests (requires env vars)
|
||||
go test -tags=integration ./...
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
- `cmd/review-bot/main.go` — CLI entry point
|
||||
- `gitea/client.go` — Gitea API interactions (fetch PR, diff, CI status, post review)
|
||||
- `llm/client.go` — OpenAI-compatible chat completion client
|
||||
- `review/prompt.go` — System/user prompt construction
|
||||
- `review/parser.go` — Parse LLM JSON response
|
||||
- `review/formatter.go` — Format markdown review body
|
||||
```
|
||||
cmd/review-bot/ CLI entrypoint
|
||||
gitea/ Gitea API client
|
||||
llm/ OpenAI-compatible LLM client
|
||||
review/ Prompt building, response parsing, formatting
|
||||
```
|
||||
|
||||
## Constraints
|
||||
## License
|
||||
|
||||
- Pure Go stdlib, no external dependencies
|
||||
- No CGO
|
||||
MIT
|
||||
|
||||
Reference in New Issue
Block a user