中文 | English
基于 OpenCode 插件系统的 AI 驱动 Gitea / Forgejo / GitHub PR 自动代码审查工具。同时支持两种运行模式:
suggestion 代码建议块approve、request_changes 或 comment[BUG:HIGH]、[SECURITY:CRITICAL] 等标签分类问题类型与严重度sha256= 前缀格式markdown_v2 格式消息到群机器人*.go,src/**/*.ts).opencode-review/ 目录,不与用户 .opencode/ 冲突linux/amd64 和 linux/arm64,开箱即用┌─────────────────────────────────────────────────────────────────────┐ │ 触发方式 │ │ ┌──────────────────┐ ┌──────────────────────────────────────┐ │ │ │ Gitea Actions │ │ Gitea / GitHub Webhook POST │ │ │ │ (内置) │ │ (pull_request / issue_comment / │ │ │ │ │ │ pull_request_review_comment) │ │ │ └────────┬─────────┘ └──────────────┬───────────────────────┘ │ └───────────┼─────────────────────────────┼──────────────────────────┘ │ │ ▼ ▼ ┌──────────────────┐ ┌────────────────────────┐ │ entrypoint.sh │ │ Go Webhook Server │ │ review 子命令 │ │ ┌──────────────────┐ │ │ │ │ │ 签名验证 + 去重 │ │ │ 1. TLS 配置 │ │ └───────┬──────────┘ │ │ 2. Provider 检测 │ │ ┌───────▼──────────┐ │ │ 3. 构建审查 Prompt│ │ │ Worker Pool │ │ │ 4. opencode run │ │ │ (队列 + 并发控制) │ │ └────────┬─────────┘ │ └───────┬──────────┘ │ │ └──────────┼──────────────┘ │ │ ▼ ▼ ┌─────────────────────────────────────────────────┐ │ OpenCode CLI + 插件系统 │ │ ┌────────────┐ ┌───────────────────────────┐ │ │ │code-review │ │ Tools │ │ │ │Agent │ │ • gitea-pr-diff │ │ │ │ │ │ • gitea-incremental-diff │ │ │ │ (AI 审查 │ │ • gitea-pr-files │ │ │ │ 策略 + │ │ • gitea-review │ │ │ │ 决策逻辑) │ │ • gitea-comment │ │ │ └─────┬──────┘ │ • provider (API 适配层) │ │ │ │ │ • diff-utils │ │ │ ▼ └───────────┬───────────────┘ │ └────────┼─────────────────────┼───────────────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌──────────────────────┐ │ Provider API │ │ 企业微信群机器人 │ │ Gitea / GitHub │ │ (markdown_v2 通知) │ │ 提交 Review │ └──────────────────────┘ │ 行级 Comments │ └─────────────────┘
在你的项目根目录执行:
curl -fsSL https://cnb.cool/zishuo/opencode-review-gitea/-/git/raw/main/install.sh | bash
脚本会引导你选择安装方式(Docker / 源码 / 两者都装),并自动安装 Gitea Actions 的审查 workflow 到 .gitea/workflows/。
# Docker 方式 — 仅添加 1 个 workflow 文件
curl -fsSL https://cnb.cool/zishuo/opencode-review-gitea/-/git/raw/main/install.sh | bash -s -- --docker
# 源码方式 — 添加完整 .opencode-review/ 目录和 workflow
curl -fsSL https://cnb.cool/zishuo/opencode-review-gitea/-/git/raw/main/install.sh | bash -s -- --source
# 两种方式都安装
curl -fsSL https://cnb.cool/zishuo/opencode-review-gitea/-/git/raw/main/install.sh | bash -s -- --both
| 维度 | Docker | 源码 |
|---|---|---|
| 添加的文件 | 1 个 workflow 文件 | .opencode-review/ + workflow |
| CI 速度 | 快(使用预构建缓存镜像) | 较慢(每次运行安装依赖) |
| 自定义能力 | 通过环境变量配置 | 完全控制 Agent、Tools、Skills |
| 更新方式 | 拉取 :latest 镜像自动更新 | 手动同步 .opencode-review/ |
| 适合场景 | 快速上手、标准化使用 | 自定义审查策略、高级用户 |
在仓库 Secrets(Actions 模式)或容器环境变量(Webhook/本地模式)中配置:
| 变量名 | 说明 | 示例 |
|---|---|---|
API_ENDPOINT | OpenAI 兼容的模型网关地址 | https://your-gateway.example.com/v1 |
API_TOKEN | 模型网关 API Token | sk-xxxxx |
GITEA_TOKEN | Gitea / Forgejo API Token(含 repo 权限) | gitea_xxxxx |
GITHUB_TOKEN | GitHub / GHES Personal Access Token | ghp_xxxxx |
OPENCODE_GIT_TOKEN | Gitea Actions 运行时用于 actions/checkout 的 Token | — |
Webhook 模式下还需要
WEBHOOK_SECRET,详见 Webhook 服务配置。
通过 MODEL 环境变量指定模型,格式为 provider/model-id:
env:
MODEL: openai/glm-5.0 # 默认
# MODEL: openai/gpt-5.4
# MODEL: openai/claude-4.5
# MODEL: openai/deepseek-v3.1
# MODEL: openai/gemini-2.5-pro
opencode.json 中预定义了 20+ 个模型(GPT-5.x、Claude 4.5/4.6、Gemini、DeepSeek、GLM、MiniMax、Kimi、混元等),所有模型 cost 设为 0(使用自定义网关计费)。你也可以在 opencode.json 中添加新的模型定义。
| 变量名 | 默认值 | 说明 |
|---|---|---|
REVIEW_LANGUAGE | auto | 审查回复语言:auto(自动检测)/ en / zh-CN |
REVIEW_STYLE | balanced | 审查深度:concise / balanced / thorough / security |
FILE_PATTERNS | (空) | 文件过滤(Glob 模式,逗号分隔),如 *.go,src/**/*.ts |
文件过滤示例:
# 仅审查 TypeScript 文件
FILE_PATTERNS: "*.ts,*.tsx"
# 仅审查 src 目录下的 Go 文件(排除测试)
FILE_PATTERNS: "src/**/*.go"
# 混合模式
FILE_PATTERNS: "*.py,*.js"
注意:当前仅支持正向匹配,不支持
!排除模式。
| 变量名 | 默认值 | 说明 |
|---|---|---|
WEBHOOK_LISTEN_ADDR | :8080 | HTTP 监听地址 |
WEBHOOK_PATH | /webhook | Webhook 接收路径 |
WEBHOOK_QUEUE_SIZE | 64 | 异步队列容量 |
WEBHOOK_MAX_CONCURRENT | 2 | 最大并发审查 Worker 数 |
WEBHOOK_REVIEW_TIMEOUT | 30m | 单次审查超时时间(Go duration 格式) |
WEBHOOK_MAX_BODY_BYTES | 2MB | 请求体最大字节数 |
WEBHOOK_ENTRYPOINT | /entrypoint.sh | 审查执行入口脚本路径 |
WEBHOOK_WORK_ROOT | /tmp/opencode-review/jobs | 临时工作目录(clone 代码) |
WEBHOOK_COMMENT_COMMANDS | /oc,/opencode | 触发审查的评论命令(逗号分隔) |
WEBHOOK_PULL_REQUEST_ACTIONS | opened,reopened,synchronize,ready_for_review | 触发审查的 PR action 白名单 |
WEBHOOK_POST_FAILURE_COMMENT | true | 审查失败时是否在 PR 上留言 |
WEBHOOK_CLEANUP_WORKTREE | true | 审查完成后是否清理临时工作目录 |
WEBHOOK_ALLOW_INSECURE | false | 是否允许无签名的 Webhook 请求 |
Webhook Secret 配置(按优先级):
| 变量名 | 说明 |
|---|---|
GITEA_WEBHOOK_SECRET | Gitea 专用 Secret(覆盖通用) |
GITHUB_WEBHOOK_SECRET | GitHub 专用 Secret(覆盖通用) |
WEBHOOK_SECRET | 通用 Secret(两个 Provider 共享) |
TLS 证书校验默认 跳过,适用于内网自签名证书环境。以下任一环境变量设为 false 可启用严格校验:
SKIP_TLS_VERIFYWEBHOOK_SKIP_TLS_VERIFYREVIEW_SKIP_TLS_VERIFYGIT_SSL_NO_VERIFY| 变量名 | 说明 |
|---|---|
WECOM_BOT_WEBHOOK_URL | 企业微信群机器人 Webhook 地址 |
WECOM_WEBHOOK_URL | 别名(与上面等价,低优先级) |
通知内容包含:仓库名、提交人、PR 链接、审查结论与简短提示、可选 PR 摘要、反馈概览(评论数 / 建议数)、模型、耗时、结果链接。
| 场景 | 推荐模式 | 说明 |
|---|---|---|
| Gitea / Forgejo,想在仓库内最快落地 | Actions 模式 | 内置安装器会自动写入 .gitea/workflows/opencode-review.yaml |
| Gitea / Forgejo,希望统一服务多个仓库 | Webhook 模式 | 更适合集中部署、统一通知与统一运维 |
| GitHub / GHES,想按当前内置方案直接自动审查 | Webhook 模式 | 这是目前针对 GitHub 的默认文档路径,服务端已原生处理 GitHub Webhook 头、API base 与 PR review 回写 |
| GitHub / GHES,坚持使用 Actions Runner 执行 | 需要手工适配 | 仓库内置 workflow 模板偏向 Gitea 运行时变量,不能直接当作 GitHub Actions 成品使用 |
安装完成后,创建或更新 PR 会自动触发审查(如果 workflow 配置了对应事件)。也可以通过评论手动触发:
/oc
或附带自定义指令:
/opencode 请重点关注并发安全问题
评论中的自定义指令会被提取并传递给 AI 审查 Agent。
当前内置安装脚本只会生成 Gitea Actions workflow。若要接入 GitHub / GHES,建议优先使用 Webhook 模式;只有在你准备自行改造模板中的 Gitea 运行时变量时,才建议走 GitHub Actions。
当前对 GitHub / GHES 而言,Webhook 模式是更推荐的自动化接入方式;对 Gitea / Forgejo 来说,如果你想集中部署一套长期运行的审查服务,它同样适用。
启动 Webhook 服务:
docker run --rm -p 8080:8080 \
-e GITEA_TOKEN="your-gitea-token" \
-e GITHUB_TOKEN="your-github-token" \
-e WEBHOOK_SECRET="your-webhook-secret" \
-e API_ENDPOINT="https://your-llm-gateway.example.com/v1" \
-e API_TOKEN="your-api-token" \
-e MODEL="openai/glm-5.0" \
-e WECOM_BOT_WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxx" \
-e WEBHOOK_PATH="/webhook" \
docker.cnb.cool/zishuo/opencode-review-gitea:latest webhook
然后在 Gitea / GitHub 仓库的 Webhook 设置中配置:
http://your-server:8080/webhookapplication/jsonWEBHOOK_SECRET 一致Webhook 服务默认
pull_request事件(opened/reopened/synchronize/ready_for_review)会自动触发审查,也可以通过 PR 评论/oc或/opencode触发。
Docker 单次审查:
docker run --rm \
-v $(pwd):/workspace \
-e GITEA_TOKEN="your-token" \
-e GITEA_SERVER_URL="https://your-gitea.example.com" \
-e API_ENDPOINT="https://your-llm-gateway.example.com/v1" \
-e API_TOKEN="your-api-token" \
-e MODEL="openai/glm-5.0" \
-e PR_NUMBER=123 \
-e REPO_OWNER="your-org" \
-e REPO_NAME="your-repo" \
docker.cnb.cool/zishuo/opencode-review-gitea:latest
REPO_NAME可以传repo或owner/repo,entrypoint 会自动规范化。
Docker Compose 测试:
# 单次审查
docker compose run review
# Webhook 服务
docker compose up webhook
# 交互式 shell
docker compose run dev
源码方式:
export GITEA_TOKEN="your-token"
export GITEA_SERVER_URL="https://your-gitea.example.com"
export API_ENDPOINT="https://your-llm-gateway.example.com/v1"
export API_TOKEN="your-api-token"
export MODEL="openai/glm-5.0"
export OPENCODE_CONFIG_DIR="$(pwd)/.opencode-review"
opencode run --agent code-review \
"Please review PR #123 in owner/repo"
若使用 GitHub / GHES,将 GITEA_TOKEN 替换为 GITHUB_TOKEN,并按需设置 GITHUB_SERVER_URL(默认 https://github.com)。
| 方法 | 路径 | 说明 |
|---|---|---|
GET | / | HTML 引导页(运行时状态 + 配置说明) |
GET | /healthz | 健康检查(返回 {"status":"ok","queue":N}) |
GET | ${WEBHOOK_PATH} | HTML 引导页(同 /) |
POST | ${WEBHOOK_PATH} | Webhook 事件接收端点 |
Webhook 服务仅处理以下事件:
| 事件类型 | 触发条件 |
|---|---|
pull_request | action 在白名单中(默认 opened,reopened,synchronize,ready_for_review) |
issue_comment | 评论内容匹配命令(默认 /oc 或 /opencode) |
pull_request_review_comment | 评论内容匹配命令 |
不匹配的事件返回 202 Accepted + {"status":"ignored"}。
| Provider | 事件头 | 投递头 | 签名头 |
|---|---|---|---|
| Gitea / Forgejo | X-Gitea-Event | X-Gitea-Delivery | X-Gitea-Signature |
| GitHub / GHES | X-GitHub-Event | X-GitHub-Delivery | X-Hub-Signature-256 |
签名验证使用 HMAC-SHA256,兼容 sha256= 前缀。如需跳过验证(仅限开发环境),设置 WEBHOOK_ALLOW_INSECURE=true。
成功入队(202 Accepted):
{
"status": "queued",
"delivery": "uuid-delivery-id",
"provider": "gitea",
"repository": "owner/repo",
"pull": 42,
"trigger": "pull_request/opened"
}
重复投递(202 Accepted):
{
"status": "ignored",
"reason": "duplicate delivery",
"delivery": "uuid-delivery-id"
}
签名错误(401 Unauthorized)。
队列已满(503 Service Unavailable)。
code-review Agent审查 Agent 的工具选择策略:
FILE_PATTERNS 过滤时 → 优先使用 gitea-pr-diff(按过滤条件获取 Diff)gitea-incremental-diff(增量审查,仅审查新变更)gitea-pr-files审查决策矩阵:
CRITICAL 或 HIGH 级别问题 → request_changescommentapprove编辑 .opencode-review/agents/code-review.md,这是主审查 Agent 的定义文件(包含 413 行详细 prompt,涵盖审查纪律、优先级、工具策略、决策矩阵和 6 个 Few-Shot 示例)。
关键配置位于文件头部 frontmatter:
---
description: AI code reviewer for Gitea/Forgejo PRs
tools:
"*": false
"gitea-review": true
"gitea-pr-diff": true
"gitea-incremental-diff": true
"gitea-pr-files": true
"gitea-comment": true
---
你可以修改审查重点、语言风格、严重度判定标准等。
在 .opencode-review/tools/ 目录创建 TypeScript 文件:
import { tool } from "@opencode-ai/plugin";
export default tool({
description: "工具描述",
args: {
param: tool.schema.string().describe("参数说明"),
},
async execute(args, context) {
return "结果";
},
});
创建同名 .txt 文件作为工具描述(供 Agent 理解工具用途),然后在 Agent 的 frontmatter 中启用:
tools:
"your-tool-name": true
工具可以通过 provider.ts 中的 getProviderConfig() 自动检测当前 Provider,并调用统一的 providerFetch() / providerFetchJson() 方法与 Gitea/GitHub API 交互。
. ├── Dockerfile # 两阶段构建:Go 编译 + Bun 运行时 ├── docker-compose.yaml # 本地测试(review / webhook / dev) ├── entrypoint.sh # 容器入口(review / webhook / shell 子命令) ├── install.sh # 交互式安装脚本 ├── .cnb.yml # CNB CI 配置,作为主 `docker.cnb.cool` 镜像发布链 ├── .github/ │ └── workflows/ │ └── docker-publish.yaml # GitHub Actions:使用 CNB 凭据发布同一份 `docker.cnb.cool` 镜像 ├── .gitea/ │ └── workflows/ │ └── opencode-review.yaml # Gitea Actions: 源码方式审查 workflow ├── templates/ │ ├── workflow-docker.yaml # Docker 方式 workflow 模板 │ └── workflow-source.yaml # 源码方式 workflow 模板 ├── backend/ # Go 后端(Webhook Server) │ ├── go.mod # 模块: cnb.cool/zishuo/opencode-review-gitea │ ├── cmd/webhook-server/ │ │ └── main.go # HTTP 服务入口 + Worker Pool + 去重 │ └── internal/ │ ├── config/ │ │ └── config.go # 环境变量加载(所有配置项定义) │ ├── webhook/ │ │ ├── model.go # Provider / ReviewRequest 类型 │ │ ├── verify.go # Provider 检测 + HMAC-SHA256 签名验证 │ │ └── parse.go # 事件解析 + 过滤 + 评论命令匹配 │ ├── review/ │ │ ├── runner.go # 审查执行器(clone + opencode + 通知) │ │ └── notifier.go # 企业微信 markdown_v2 通知 │ └── webui/ │ ├── guide.go # Go embed 引导页渲染 │ └── guide.html # 嵌入式 HTML 引导页面 ├── docs/ # 参考文档 │ ├── webhook-review-service.md # Webhook 部署详解 │ ├── gitea-webhooks-reference.md # Gitea Webhook API 参考 │ ├── github-webhooks-reference.md # GitHub Webhook API 参考 │ ├── wecom-group-bot-webhook.md # 企业微信机器人 API 参考 │ ├── opencode-sdk-reference.md # OpenCode SDK 参考 │ └── gitea-plugin-redoc-2.yaml # Gitea API 1.25.5 OpenAPI 规范 └── .opencode-review/ # OpenCode 插件(隔离配置目录) ├── opencode.json # 模型定义 / Provider / 权限配置 ├── package.json # 依赖: @opencode-ai/plugin ├── agents/ │ ├── code-review.md # 主审查 Agent(prompt + 策略 + Few-Shot) │ └── gitea-assistant.md # 通用助手 Agent ├── tools/ │ ├── provider.ts # Provider 抽象层(API 适配 / 行号映射) │ ├── diff-utils.ts # Diff 解析 / 格式化 / 文件过滤 │ ├── gitea-review.ts # 提交 Review(行级评论 + suggestion) │ ├── gitea-pr-diff.ts # 获取完整 PR Diff │ ├── gitea-incremental-diff.ts # 获取增量 Diff(新变更检测) │ ├── gitea-pr-files.ts # 列出变更文件 │ ├── gitea-comment.ts # 发表 Issue/PR 评论 │ └── *.txt # 各工具描述文件 ├── skills/ │ └── pr-review/SKILL.md # PR Review 可复用技能 └── tests/ # Bun 单元测试 ├── gitea-incremental-diff.test.ts ├── gitea-pr-diff.test.ts ├── gitea-review-stats.test.ts └── gitea-review-tags.test.ts
| 组件 | 技术 |
|---|---|
| 运行时镜像 | oven/bun:1-alpine |
| Go 后端 | Go 1.26, go-git/v5(唯一直接依赖) |
| 插件系统 | OpenCode Plugin SDK (@opencode-ai/plugin) |
| 测试框架 | Bun Test(插件)、Go testing(后端) |
| CI/CD | CNB Build(主多平台发布链,对应 docker.cnb.cool)、GitHub Actions(GitHub 托管自动化下的备用 CNB 发布链) |
本 README 全文默认引用的发布镜像是 docker.cnb.cool/zishuo/opencode-review-gitea。现在无论是 CNB pipeline 还是 GitHub Actions 发布 workflow,都统一推送到同一份 CNB 镜像;GitHub workflow 需要配置 CNB_TOKEN_USER_NAME 与 CNB_TOKEN secrets。
# 启动交互式开发环境
docker compose run dev
# 运行 Go 后端测试
cd backend && go test ./...
# 运行插件测试
cd .opencode-review && bun test
docker build -t opencode-review-gitea:latest .
MIT License - 详见 LICENSE