第 5 章 · 03 CI/CD 集成


第 5 章 · 03 CI/CD 集成

本节摘要:在每个 Pull Request 或 Merge Request 上运行 OCR,是它真正价值落地的场景。上游仓库提供两条现成流水线(GitHub Actions、GitLab CI),你复制并配置即可。本节讲清三件事:CI/CD 集成的统一六步模式(触发 → 装 OCR → 配 LLM → 区间模式评审 → 解析 JSON → 回贴评论)、GitHub Actions 与 GitLab CI 两条配方的安装/secret/定制/故障排查、以及用 GitHub App / GitLab 服务账号发布品牌化 bot 评论的方法。读完你能把 OCR 接进团队完整的开发链路。

内容来源:原项目中文文档 pages/src/content/docs/zh/integrations/ci.md,套用体系化模板改写。

学习目标

阅读完本节,你应当能够:

  1. 描述 CI/CD 集成的统一六步模式(触发 → 安装 → 配置 → 评审 → 解析 → 回贴)。
  2. 区分两类凭据(LLM 凭据 vs PR/MR 写 token)的来源。
  3. 把 GitHub Actions 工作流放进仓库并配置 secret、定制 --background/--rule/并发/触发。
  4. 把 GitLab CI 流水线放进仓库并配置变量、避免每次推送复审。
  5. 用 GitHub App / GitLab 服务账号发布品牌化 bot 评论。
  6. 排查 Cannot find merge-base、Failed to parse OCR output 等常见故障。

一、CI/CD 集成如何工作(统一六步)

本页每条配方都遵循同一模式——下面的 GitHub Actions 与 GitLab CI 章节只是它的具体实现:

  1. 在 PR / MR 事件上触发。 新建 pull request、更新的 merge request,或手动 /open-code-review 评论触发作业。

  2. 在 runner 中安装 ocr,通常是 npm install -g @alibaba-group/open-code-review。runner 是临时的,因此每次运行都发生。

  3. 从 CI secret 经 ocr config set 配置 LLM(端点、token、model)。没有持久的 ~/.opencodereview 可回退。

  4. 以区间模式运行评审,输出机器可读,使 stdout 是干净的 JSON 外壳:

    ocr review \ --from "origin/<base-branch>" \ --to "origin/<head-branch>" \ --format json \ --audience agent ​

    --format json 给出可解析载荷;--audience agent 屏蔽进度行。每条配方消费的外壳结构见第 2 章 CLI 参考。

  5. 解析 JSON 并遍历 comments[]。

  6. 通过 provider 的 review API 把评论回贴到 PR / MR。 无有效行信息的条目(文件级发现)合并到摘要备注而非内联张贴;若内联批量 API 拒绝请求,张贴步骤也回退为普通摘要评论。

⚠️ 注意:始终涉及两类凭据——OCR 用来生成发现的 LLM 凭据,以及张贴步骤用来回贴评论的 PR/MR 写 token。GitHub 配方通过 GITHUB_TOKEN 自动提供后者;GitLab 建议显式配置 GITLAB_API_TOKEN,但对 fork MR 会回退使用内置 CI_JOB_TOKEN——为可靠性推荐使用专用 token。

二、GitHub Actions

上游工作流位于 examples/github_actions/ocr-review.yml。

它做什么

  • 在 pull_request_target(opened)和 issue_comment 事件上触发,后者正文以 /open-code-review 或 @open-code-review 开头——后者让评审者通过在 PR 上评论按需重跑 OCR。(用 pull_request_target 而非 pull_request,使即便从 fork 提交的 PR 也能用上 secret;OCR 只读 diff,不执行 PR 中的代码。)
  • 通过 npm install -g @alibaba-group/open-code-review 安装 OCR,用 ocr config set 写配置,再以分支区间模式运行核心命令。
  • 解析 JSON 外壳并通过 GitHub Pull Request Review API 把每条发现作为内联评审评论张贴。无行信息的评论合并到摘要正文。若批量提交失败,回退为逐条张贴,并在摘要评论中呈现统计。

安装

把工作流放进你的仓库:

mkdir -p .github/workflows curl -o .github/workflows/ocr-review.yml \ https://raw.githubusercontent.com/alibaba/open-code-review/main/examples/github_actions/ocr-review.yml ​

必需 secret

在 Settings → Secrets and variables → Actions 下设置:

Secret 必需 说明
OCR_LLM_URL 是 LLM API 端点(如 https://api.openai.com/v1/chat/completions)。
OCR_LLM_AUTH_TOKEN 是 LLM API 的认证 token。此 CI secret 传给 ocr config set llm.auth_token。(OCR 的直接环境变量是 OCR_LLM_TOKEN,不是 OCR_LLM_AUTH_TOKEN。)
OCR_LLM_MODEL 否 模型名。无默认——必须显式设置。
OCR_LLM_USE_ANTHROPIC 否 Anthropic Claude 模型设为 true。

GITHUB_TOKEN 自动提供;工作流声明 pull-requests: write 以便张贴评审评论。

⚠️ 注意:工作流启动时还会运行 ocr config set llm.extra_body '{"thinking": {"type": "disabled"}}',为不支持该字段的 LLM provider 关闭 thinking-mode 请求(原理见第 2 章配置)。若你的 provider 需保留 thinking-mode,删除该行。

定制

以下都是对你刚复制的工作流文件(.github/workflows/ocr-review.yml)的编辑。

背景上下文

--background 是效果最显著的单一参数。传入 PR 标题(当标题遵循 feat(auth): add OAuth2 support 这样的语义约定时,效果更好):

- name: Run OCR review env: PR_TITLE: ${{ github.event.pull_request.title }} BASE_REF: ${{ github.base_ref }} HEAD_REF: ${{ github.head_ref }} run: | ocr review \ --background "$PR_TITLE" \ --from "origin/$BASE_REF" \ --to "origin/$HEAD_REF" \ --format json --audience agent ​

⚠️ 注意(安全):把 PR 可控的值通过 env: 传入,不要把 ${{ }} 直接插值进 run:。GitHub 在 shell 解析该行之前就已把 ${{ }} 做了文本替换,因此包含 shell 元字符的 PR 标题或分支名会在你的 runner 上被执行。

自定义规则

用 --rule 传入项目专属规则文件(schema 见第 3 章评审规则):

- name: Run OCR review env: BASE_REF: ${{ github.base_ref }} HEAD_REF: ${{ github.head_ref }} run: | ocr review --rule ./my-rules.json \ --from "origin/$BASE_REF" \ --to "origin/$HEAD_REF" ​

并发

默认 8 个并行 per-file 子 agent。大 PR 上调低,以免触发 LLM provider 速率限制:

- name: Run OCR review env: BASE_REF: ${{ github.base_ref }} HEAD_REF: ${{ github.head_ref }} run: | ocr review --concurrency 5 \ --from "origin/$BASE_REF" \ --to "origin/$HEAD_REF" ​

触发模式

默认工作流在 PR opened 时以及以 /open-code-review 或 @open-code-review 开头的 PR 评论时触发。两种常见调整:

在更多 PR 生命周期事件上运行(如推送新 commit 时复审):

on: pull_request: types: [opened, synchronize, reopened, ready_for_review] ​

使用不同评论关键字:

if: | github.event_name == 'pull_request' || (github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/review')) ​

github.event.issue.pull_request 检查确保评论在 PR 上而非普通 issue 上。

固定 OCR 版本

默认工作流安装最新发布版本。固定:

- name: Install OpenCodeReview run: npm install -g @alibaba-group/open-code-review@1.0.0 ​

以 GitHub App 身份发布

默认评审评论来自 github-actions[bot]。要以 OpenCodeReview Bot 这类自定义品牌的 bot 发布,把 GITHUB_TOKEN 换成 GitHub App installation token。

  1. 在 Settings → Developer settings → GitHub Apps → New GitHub App 创建 app。禁用 webhook(此用例不需要)。在 Repository permissions 授予:

    • Pull requests:Read and write
    • Contents:Read-only(用于取 diff)
    • Metadata:Read-only(必需)
  2. 从 app 设置页生成私钥并下载 .pem 文件。记下同页的 App ID。

  3. 把 app 安装到你想 OCR 评审的仓库。Installation ID 出现在安装后 URL 中,如 https://github.com/settings/installations/12345 → ID 为 12345。

  4. 在 Settings → Secrets and variables → Actions 下添加三个 secret:

    Secret 值
    GITHUB_APP_ID App ID。
    GITHUB_APP_PRIVATE_KEY .pem 文件全部内容,含 -----BEGIN RSA PRIVATE KEY----- 与 -----END RSA PRIVATE KEY----- 行。
    GITHUB_APP_INSTALLATION_ID Installation ID。
  5. 在评论张贴步骤中生成并使用 token:

    - name: Get GitHub App Token id: app-token uses: actions/create-github-app-token@v1 with: app-id: ${{ secrets.GITHUB_APP_ID }} private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }} - name: Post review comments to PR uses: actions/github-script@v7 with: github-token: ${{ steps.app-token.outputs.token }} script: | # ...existing post script... ​

评审现在会以你 app 的名字而非 github-actions[bot] 发布。

故障排查

症状 原因 / 修复
Cannot find merge-base checkout 步骤用了浅克隆,但区间模式评审需要完整历史。上游工作流在 actions/checkout 上设 fetch-depth: 0——编辑文件时保留该设置。
Failed to parse OCR output OCR_LLM_URL 或 OCR_LLM_AUTH_TOKEN 缺失或错误。在 Settings → Secrets and variables → Actions 下复查值。
评审评论落到错误行 通常意味着评审开始到评论张贴之间 diff 发生了偏移。张贴脚本此时回退为普通 issue 评论——无需处理。

⚠️ 注意:OCR_DEBUG 环境变量目前在 OCR 中未实现——设置 OCR_DEBUG: "1" 无效。当前若需详细输出,可检查工作流写到 /tmp/ocr-result.json 和 /tmp/ocr-stderr.log 的原始评审 JSON 和 stderr,或本地运行 ocr review。

三、GitLab CI

上游流水线位于 examples/gitlab_ci/.gitlab-ci.yml。

它做什么

  • 在 merge_requests 事件上触发(所有 MR 事件——创建、更新、重开)。
  • 在 node:20 镜像中运行,安装 OCR,通过 ocr config set 配置,再以 MR diff 模式运行核心命令。
  • 用内联 Python 脚本解析 JSON 外壳,把每条发现作为 GitLab Discussion(在 diff 上内联)张贴,用 MR 的 versions 端点计算正确的 base_sha / start_sha / head_sha 以精确定位。对无法内联张贴的评论回退为普通 MR note,并以摘要 note 收尾。

安装

把流水线放进仓库根:

curl -o .gitlab-ci.yml \ https://raw.githubusercontent.com/alibaba/open-code-review/main/examples/gitlab_ci/.gitlab-ci.yml ​

若已有 .gitlab-ci.yml 并想保留,把配方放到其他路径并用 include: 引入:

include: - local: 'ci/ocr-review.gitlab-ci.yml' ​

必需 CI/CD 变量

在 Settings → CI/CD → Variables 下设置:

变量 必需 掩码 说明
OCR_LLM_URL 是 否 LLM API 端点 URL。
OCR_LLM_AUTH_TOKEN 是 是 API 认证 token。此 CI 变量传给 ocr config set llm.auth_token。(OCR 的直接环境变量是 OCR_LLM_TOKEN,不是 OCR_LLM_AUTH_TOKEN。)
OCR_LLM_MODEL 否 否 模型名。无默认——必须显式设置。
GITLAB_API_TOKEN 否 是 带 api scope 的 project / personal / group access token。可选——缺失时回退使用内置 CI_JOB_TOKEN(如对 fork MR)。为可靠性推荐专用 GITLAB_API_TOKEN。

⚠️ 注意:GitLab 拒绝短于 8 字符的变量,因此流水线中 llm.use_anthropic 硬编码为 false。要用 Anthropic Claude 模型,直接编辑脚本。流水线启动时同样会关 thinking-mode(同 GitHub)。

💡 技巧·bot 命名:对 Project Access Token 和 Group Access Token,token 的名字会出现在 MR 讨论旁。把 token 命名为 OpenCodeReview Bot,即可让评审讨论带上品牌名,无需额外设置。

定制

以下都是对你刚复制的 .gitlab-ci.yml 的编辑。

背景上下文

把 MR 标题传给 --background:

script: - | ocr review \ --background "$CI_MERGE_REQUEST_TITLE" \ --from "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" \ --to "${CI_COMMIT_SHA}" \ --format json --audience agent ​

自定义规则与并发

与 GitHub Actions 配方相同的参数——--rule 传项目专属规则文件,--concurrency 限制并行子 agent(默认 8):

script: - | ocr review --rule ./my-rules.json --concurrency 5 \ --from "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" \ --to "${CI_COMMIT_SHA}" ​

固定 OCR 版本

script: - npm install -g @alibaba-group/open-code-review@1.0.0 ​

避免每次推送都复审

only: [merge_requests] 在每次 MR 更新时触发,对长生命周期 MR 会消耗大量 LLM token。GitLab 无原生「仅在创建时」事件,因此推荐模式是运行评审前检测已有 OCR note,若有则跳过。把 ocr review 调用替换为 Python wrapper:

import json, os, sys, urllib.request GITLAB_URL = os.environ.get("CI_SERVER_URL", "https://gitlab.com") PROJECT_ID = os.environ["CI_PROJECT_ID"] MR_IID = os.environ["CI_MERGE_REQUEST_IID"] API_TOKEN = os.environ["GITLAB_API_TOKEN"] url = ( f"{GITLAB_URL}/api/v4/projects/{PROJECT_ID}" f"/merge_requests/{MR_IID}/notes?per_page=100" ) req = urllib.request.Request(url, headers={"PRIVATE-TOKEN": API_TOKEN}) with urllib.request.urlopen(req) as resp: notes = json.loads(resp.read().decode()) if any("OpenCodeReview" in n.get("body", "") for n in notes): print("OCR already reviewed this MR. Skipping to save tokens.") sys.exit(0) # ...otherwise call `ocr review ...` as usual and write the JSON to # the file the posting step expects. ​

要在此之后强制复审,从 MR 删除之前的 OCR note——下次流水线运行会看不到 OCR note,便会继续。

自托管 GitLab

无需改代码。张贴脚本读 CI_SERVER_URL(GitLab 在每个 runner 上自动设置),因此开箱即可与你自己的实例通信。只需确保 GITLAB_API_TOKEN 由你的自托管实例签发,而非 gitlab.com。

以服务账号身份发布

默认评审讨论出现在 GITLAB_API_TOKEN 所属用户名下。改用项目级服务账号,即可获得 OpenCodeReview Bot 这类自定义品牌的 bot 身份。

  1. 在 Project → Settings → Service Accounts → New service account 创建服务账号。你选的名字(如 OpenCodeReview Bot)会出现在 MR 讨论旁。
  2. 在 Settings → Members → Invite member 邀请它到项目。搜索服务账号名并分配 Developer 或 Maintainer——两者都有张贴讨论所需权限。
  3. 在 Settings → Service Accounts →(该账号)→ Add new token 签发 access token。所需 scope:api。立即复制 token——GitLab 只显示一次。
  4. 在 Settings → CI/CD → Variables 替换 token 值——用服务账号的 token 替换现有 GITLAB_API_TOKEN 值(变量名保持不变)。

讨论现在以服务账号名而非最初创建 token 的用户名发布。

故障排查

症状 原因 / 修复
Cannot find merge-base runner 用了浅克隆。上游流水线设 GIT_DEPTH: 0 强制完整克隆——编辑文件时保留该设置。
张贴时 API error 403 GITLAB_API_TOKEN 缺 api scope、不是项目成员,或——自托管时——由不同实例签发。以 api scope 重签并在 Settings → CI/CD → Variables 下重新添加。
Failed to parse OCR output OCR_LLM_URL 或 OCR_LLM_AUTH_TOKEN 错误。在 Settings → CI/CD → Variables 下复查值。
内联评论落到错误行 GitLab 内联讨论要求精确 SHA 匹配;张贴脚本取 versions 元数据以得到正确的 base_sha / start_sha / head_sha。若某条发现仍无法锚定,回退为普通 MR note。

💡 技巧:流水线把原始评审 JSON 写到 /tmp/ocr-result.json,stderr 写到 /tmp/ocr-stderr.log。可在 debug 步骤中 cat 它们,检查 OCR 返回了什么。

本节要点回顾

  1. 统一六步:触发 → 装 OCR → 配 LLM → 区间模式评审(--format json --audience agent)→ 解析 comments[] → 回贴(无行号→摘要)。
  2. 两类凭据:LLM 凭据(OCR_LLM_*)生成发现 + PR/MR 写 token(GITHUB_TOKEN/GITLAB_API_TOKEN)回贴评论。
  3. GitHub Actions:pull_request_target + issue_comment 双触发,fork PR 也能用 secret;fetch-depth: 0 防浅克隆。
  4. GitLab CI:merge_requests 事件触发,内联 Python 解析 JSON 张贴 Discussion;自托管读 CI_SERVER_URL 即可。
  5. --background 最有效:传 PR/MR 标题(语义化约定时更佳);PR 可控值走 env: 不走 ${{ }} 插值。
  6. 并发:大 PR 调低 --concurrency(如 5)防速率限制。
  7. 品牌化 bot:GitHub 用 App installation token,GitLab 用服务账号 token。
  8. 避免重复复审(GitLab):检测已有 OCR note 跳过,删 note 即可强制复审。
  9. 故障两常见:浅克隆→Cannot find merge-base;LLM 凭据错→Failed to parse OCR output。

CI/CD 讲完了。下一节看委托模式——让宿主 agent(如 Claude Code)提供模型,OCR 只负责审查逻辑,无需在 OCR 端配置 LLM。


作者与出处
原作者: 灏天文库
来源:alibaba
许可证:Apache-2.0
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: 灏天文库 转发
评论区 (0)
U