
一个自托管服务,用 webhook 接收 Gitea pull request 事件,调用你配置的 reviewer,记录结果,并在控制台里查看任务、日志和统计。
Self-hosted pull request review automation for Gitea.
Project site · Quick start · Configuration
gitea-review-agent receives Gitea pull request events through webhooks, prepares
a read-only checkout, runs a configured reviewer, and posts review findings back
to the PR. It can use Codex by default, and can also run Claude Code or a
MiniMax-compatible reviewer as separate review backends. MiniMax-compatible
runs reuse the Claude Code path and can be routed through cc-switch providers or
an Anthropic-compatible relay endpoint.
Reviews are stateful: follow-up pushes and /review comments can continue the
same reviewer session instead of starting from an empty context every time.
/cache, then/admin shows review jobs, logs, runtime configuration,SKILL.md at/skills/<owner>/<repo>/SKILL.md./healthz is a liveness check; /readyz reports DB,Gitea webhook
-> verify HMAC
-> enqueue job in SQLite
-> fetch cached mirror + prepare worktree
-> run configured reviewer
-> map findings to diff lines
-> publish review through Gitea API
Codex is the default reviewer. Claude Code and MiniMax-compatible reviewers are
optional and keep their own reviewer identity, sessions, logs, and PR comments.
MiniMax-compatible review runs through the Claude Code execution path. There are
two supported ways to route it:
MINIMAX_PROVIDER_ID to switch Claude Code to aMINIMAX_API_KEY and MINIMAX_BASE_URL for anExample:
MINIMAX_ENABLED=true
MINIMAX_PROVIDER_ID=minimaxreview
# or:
MINIMAX_API_KEY=...
MINIMAX_BASE_URL=https://relay.example.com
The job is still stored and posted as the minimax reviewer, so it can be
tracked separately from Codex and Claude Code.
docker run --rm \
-p 18080:8080 \
-e ADMIN_PASSWORD=choose-a-strong-password \
-e GITEA_URL=https://gitea.example.com \
-e GITEA_TOKEN=... \
ghcr.io/liutianjie/gitea-review-agent:latest
Then open http://localhost:18080/admin, finish the runtime configuration, and
add a Gitea webhook pointing to http://<host>:8080/webhook.
For local development or persistent data, use Docker Compose:
export ADMIN_PASSWORD=choose-a-strong-password
docker compose up -d
Persist these paths in production:
/data — SQLite database/cache — bare git mirrors/work — temporary worktrees/codex-home — Codex auth and sessions/claude-home — Claude Code state/cc-switch — optional provider/proxy configuration| Mode | Cost | Setup |
|---|---|---|
authfile (default) |
reuses your ChatGPT subscription, no extra API billing | run codex login locally, upload the resulting ~/.codex/auth.json via the /admin console |
apikey |
separately billed OpenAI Platform tokens | set CODEX_API_KEY + CODEX_AUTH_MODE=apikey |
In authfile mode the /codex-home volume must be writable so codex can
refresh its OAuth token in place between runs. Use the console's "check auth
status" button to catch a stale token early.
codex login on your machine → upload ~/.codex/auth.json at /admin.ADMIN_PASSWORD (no password ⇒ /admin returns 503)./admin): Gitea URL, bot token, webhook secret, model,http://<host>:8080/webhook, Content-Type application/json/readyz should return {"ok":true,...} after theconfig_warnings first./review <question> on a PR → answered with the prior review's context./admin → inspect jobs, cancel pending jobs, rerun failed jobs, update/skills/<owner>/<repo>/SKILL.md → download a generated project rule fileThe task tab shows recent jobs, status counters, retryable pending work, canceled
and superseded jobs. Pending jobs can be canceled from the detail panel; worker
finishes are conditional, so an old worker cannot overwrite a canceled or
superseded final state.
Analytics reports are stored snapshots. Reports include:
The Rules tab is project-scoped. It uses existing findings as evidence and can
produce a repository-specific SKILL.md file for future development and review.
Generation is asynchronous:
POST /admin/api/skills/<owner>/<repo>/generate returns a background task_id.GET /admin/api/skills/<owner>/<repo>/generate/<task_id>.Usage instruction format:
请使用这个项目规则文件:https://<host>/skills/<owner>/<repo>/SKILL.md
.github/workflows/pages.yml publishes the static site in docs/ to GitHub
Pages on every push to main. In the repository settings, set Pages source to
GitHub Actions if it is not already enabled.
Default Pages URL:
https://liutianjie.github.io/gitea-review-agent/
Env vars (all optional except ADMIN_PASSWORD; the console can set the rest):
| Var | Default | Notes |
|---|---|---|
ADMIN_PASSWORD |
— | required; protects /admin |
GITEA_URL / GITEA_TOKEN |
— | bot account |
GITEA_TIMEOUT |
90s |
per Gitea API request; also configurable in console |
WEBHOOK_SECRET |
— | HMAC-SHA256 verification |
MODEL |
gpt-5-codex |
codex model |
CODEX_AUTH_MODE |
authfile |
or apikey |
CODEX_API_KEY |
— | apikey mode only (separately billed) |
CODEX_SANDBOX_MODE |
read-only |
set danger-full-access only when the container blocks Codex's read-only sandbox |
CLAUDE_ENABLED |
false |
enable the Claude reviewer |
CLAUDE_MODEL |
sonnet |
Claude model/alias passed to Claude Code |
CLAUDE_API_KEY |
— | optional Anthropic or relay key; configurable in console |
CLAUDE_BASE_URL |
— | optional Anthropic-compatible relay URL; configurable in console |
CLAUDE_MAX_BUDGET_USD |
0.3 |
per Claude Code run budget cap; set 0 to disable |
CC_SWITCH_CONFIG_DIR |
/cc-switch |
cc-switch provider/proxy config directory |
CC_SWITCH_PROVIDER_ID |
— | optional provider id to switch before Claude runs |
MINIMAX_ENABLED |
false |
enable the MiniMax reviewer via Claude Code |
MINIMAX_PROVIDER_ID |
— | optional cc-switch Claude app provider id used before MiniMax review runs |
MINIMAX_API_KEY |
— | optional MiniMax/relay API key passed to Claude Code |
MINIMAX_BASE_URL |
— | optional MiniMax/relay Anthropic-compatible base URL |
MINIMAX_MODEL |
— | optional claude --model override; leave empty to use provider/relay defaults |
MINIMAX_MAX_BUDGET_USD |
0.3 |
per MiniMax/Claude Code run budget cap; set 0 to disable |
CONCURRENCY |
5 |
worker count |
TRIGGER_KEYWORDS |
/review,@review |
comma-separated |
REPO_ALLOWLIST |
— | comma-separated owner/repo; empty = all |
TIMEOUT |
30m |
per codex run |
/admin console can change tokens and upload credentials — do not exposego build ./...
go test ./...
The admin console is a Vite/React app embedded into the Go binary. CI and the
Dockerfile build it automatically before compiling the service, so deploying the
new image is enough. For local go build / go test, rebuild it after changing
console UI code:
cd internal/console/frontend
npm install
npm run build
Module layout: internal/{webhook,queue,review,gitcache,codex,gitea,store,config,console},
wired in cmd/codex-gitea/main.go. Interfaces live in internal/model/types.go.