logo
0
0
WeChat Login
ci: 更新 Docker 发布工作流至 CNB 仓库

OpenCode PR Review

OpenCode Docker Image License Go Multi-arch

中文 | English

基于 OpenCode 插件系统的 AI 驱动 Gitea / Forgejo / GitHub PR 自动代码审查工具。同时支持两种运行模式:

  • Actions 模式 — 通过仓库内置的 Gitea Actions workflow 触发单次审查;GitHub Actions 需手工适配 workflow
  • Webhook 模式 — 长驻 Go HTTP 服务,接收 Provider 事件并异步执行审查,完成后推送企业微信通知

目录

功能特性

  • AI 代码审查 — 支持 GPT、Claude、DeepSeek、GLM 等模型,通过 OpenAI 兼容网关接入
  • 行级精确评论 — 在具体代码行上提供反馈,支持 suggestion 代码建议块
  • 审查决策 — 根据问题严重度自动输出 approverequest_changescomment
  • 结构化标签 — 使用 [BUG:HIGH][SECURITY:CRITICAL] 等标签分类问题类型与严重度
  • 增量审查 — PR 更新时仅审查自上次审查以来的新变更,避免重复审查
  • 多 Provider 支持 — 统一适配 Gitea / Forgejo / GitHub / GHES 的 API、Diff 和 Review 语义差异
  • Webhook 异步处理 — Go Worker Pool 模式,可配置队列大小和并发数,内置 delivery 去重
  • 签名验证 — HMAC-SHA256 签名校验,兼容 sha256= 前缀格式
  • 企业微信通知 — 审查完成后推送 markdown_v2 格式消息到群机器人
  • 文件过滤 — 支持 Glob 模式指定审查范围(如 *.go,src/**/*.ts
  • 隔离配置 — 使用独立 .opencode-review/ 目录,不与用户 .opencode/ 冲突
  • 预构建 Docker 镜像 — 支持 linux/amd64linux/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_ENDPOINTOpenAI 兼容的模型网关地址https://your-gateway.example.com/v1
API_TOKEN模型网关 API Tokensk-xxxxx
GITEA_TOKENGitea / Forgejo API Token(含 repo 权限)gitea_xxxxx
GITHUB_TOKENGitHub / GHES Personal Access Tokenghp_xxxxx
OPENCODE_GIT_TOKENGitea 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_LANGUAGEauto审查回复语言:auto(自动检测)/ en / zh-CN
REVIEW_STYLEbalanced审查深度: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 服务配置

变量名默认值说明
WEBHOOK_LISTEN_ADDR:8080HTTP 监听地址
WEBHOOK_PATH/webhookWebhook 接收路径
WEBHOOK_QUEUE_SIZE64异步队列容量
WEBHOOK_MAX_CONCURRENT2最大并发审查 Worker 数
WEBHOOK_REVIEW_TIMEOUT30m单次审查超时时间(Go duration 格式)
WEBHOOK_MAX_BODY_BYTES2MB请求体最大字节数
WEBHOOK_ENTRYPOINT/entrypoint.sh审查执行入口脚本路径
WEBHOOK_WORK_ROOT/tmp/opencode-review/jobs临时工作目录(clone 代码)
WEBHOOK_COMMENT_COMMANDS/oc,/opencode触发审查的评论命令(逗号分隔)
WEBHOOK_PULL_REQUEST_ACTIONSopened,reopened,synchronize,ready_for_review触发审查的 PR action 白名单
WEBHOOK_POST_FAILURE_COMMENTtrue审查失败时是否在 PR 上留言
WEBHOOK_CLEANUP_WORKTREEtrue审查完成后是否清理临时工作目录
WEBHOOK_ALLOW_INSECUREfalse是否允许无签名的 Webhook 请求

Webhook Secret 配置(按优先级):

变量名说明
GITEA_WEBHOOK_SECRETGitea 专用 Secret(覆盖通用)
GITHUB_WEBHOOK_SECRETGitHub 专用 Secret(覆盖通用)
WEBHOOK_SECRET通用 Secret(两个 Provider 共享)

TLS 与安全

TLS 证书校验默认 跳过,适用于内网自签名证书环境。以下任一环境变量设为 false 可启用严格校验:

  • SKIP_TLS_VERIFY
  • WEBHOOK_SKIP_TLS_VERIFY
  • REVIEW_SKIP_TLS_VERIFY
  • GIT_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 成品使用

Actions 模式

安装完成后,创建或更新 PR 会自动触发审查(如果 workflow 配置了对应事件)。也可以通过评论手动触发:

/oc

或附带自定义指令:

/opencode 请重点关注并发安全问题

评论中的自定义指令会被提取并传递给 AI 审查 Agent。

当前内置安装脚本只会生成 Gitea Actions workflow。若要接入 GitHub / GHES,建议优先使用 Webhook 模式;只有在你准备自行改造模板中的 Gitea 运行时变量时,才建议走 GitHub Actions。

Webhook 模式

当前对 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 设置中配置:

  • URL: http://your-server:8080/webhook
  • Content Type: application/json
  • Secret: 与 WEBHOOK_SECRET 一致
  • Events: Pull Request events, Issue Comment events, Pull Request Review Comment events

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 可以传 repoowner/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)。

Webhook 服务 API

路由表

方法路径说明
GET/HTML 引导页(运行时状态 + 配置说明)
GET/healthz健康检查(返回 {"status":"ok","queue":N}
GET${WEBHOOK_PATH}HTML 引导页(同 /
POST${WEBHOOK_PATH}Webhook 事件接收端点

触发规则

Webhook 服务仅处理以下事件:

事件类型触发条件
pull_requestaction 在白名单中(默认 opened,reopened,synchronize,ready_for_review
issue_comment评论内容匹配命令(默认 /oc/opencode
pull_request_review_comment评论内容匹配命令

不匹配的事件返回 202 Accepted + {"status":"ignored"}

Provider 头部验证

Provider事件头投递头签名头
Gitea / ForgejoX-Gitea-EventX-Gitea-DeliveryX-Gitea-Signature
GitHub / GHESX-GitHub-EventX-GitHub-DeliveryX-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)。

审查工作流详解

  1. 签名验证 — HMAC-SHA256 校验 Webhook 签名
  2. 去重 — 基于 delivery ID 的 24 小时 TTL 去重
  3. 入队 — 通过带缓冲 channel 的 Worker Pool 异步处理
  4. go-git clone — 纯 Go 实现克隆仓库到临时目录(无需系统 git)
  5. Checkout head SHA — 精确切换到 PR 的最新提交
  6. 构建 Prompt — 根据环境变量(语言、风格、文件过滤等)组装审查指令
  7. opencode run — 启动 OpenCode CLI 执行 code-review Agent
  8. 提交 Review — 调用 Provider API 提交审查决策和行级评论
  9. 企业微信通知 — 推送审查结果摘要到群机器人

审查 Agent 的工具选择策略:

  • FILE_PATTERNS 过滤时 → 优先使用 gitea-pr-diff(按过滤条件获取 Diff)
  • 无过滤时 → 优先使用 gitea-incremental-diff(增量审查,仅审查新变更)
  • 需要文件列表时 → 使用 gitea-pr-files

审查决策矩阵:

  • 存在 CRITICALHIGH 级别问题 → request_changes
  • 只有非阻断但值得跟进的问题、疑问或后续项 → comment
  • 没有 actionable 问题,或只有极轻微的可选建议 → approve

自定义

修改审查 Agent

编辑 .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/CDCNB 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_NAMECNB_TOKEN secrets。

本地开发

# 启动交互式开发环境 docker compose run dev # 运行 Go 后端测试 cd backend && go test ./... # 运行插件测试 cd .opencode-review && bun test

构建 Docker 镜像

docker build -t opencode-review-gitea:latest .

相关链接

许可证

MIT License - 详见 LICENSE