CI/CD

在每個 Pull Request / Merge Request 上跑 OCR

CI/CD 整合如何運作

每條配方都遵循同一模式:

  1. 在 PR / MR 事件上觸發(新建、更新,或 /open-code-review 評論)。
  2. 在 runner 中安裝 ocr(runner 是臨時的,每次安裝)。
  3. 從 CI secret 配置 LLMocr config set)。
  4. 以區間模式跑評審、輸出機器可讀 JSON。
  5. 解析 JSON、遍歷 comments[]
  6. 透過 provider 的 review API 回貼評論到 PR / MR。

兩類憑證:LLM 憑證(產生發現)與 PR/MR 寫 token(回貼評論)。GitHub 用 GITHUB_TOKEN 自動提供後者;GitLab 建議顯式 GITLAB_API_TOKEN

GitHub Actions

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

pull_request_target(opened)與以 /open-code-review@open-code-review 開頭的 issue_comment 上觸發。透過 GitHub Pull Request Review API 把發現貼成內聯評論;無行資訊的併入摘要。

必需 secret

Secret必需說明
OCR_LLM_URLLLM API 端點
OCR_LLM_AUTH_TOKEN認證 token(傳給 ocr config set llm.auth_token
OCR_LLM_MODEL模型名——無預設,必須顯式設定
OCR_LLM_USE_ANTHROPICAnthropic Claude 模型設 true

客製化:傳背景脈絡

- 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 上被執行。

客製化:自訂規則 / 併發 / 固定版本

ocr review --rule ./my-rules.json \
  --from "origin/$BASE_REF" --to "origin/$HEAD_REF"

ocr review --concurrency 5 \
  --from "origin/$BASE_REF" --to "origin/$HEAD_REF"

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

GitLab CI

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

merge_requests 事件上觸發,在 node:20 映像中跑。內聯 Python 腳本解析 JSON、用 MR 的 versions 端點計算正確 SHA、把發現貼成 GitLab Discussion。

必需 CI/CD 變數

變數必需掩碼說明
OCR_LLM_URLLLM API 端點 URL
OCR_LLM_AUTH_TOKEN認證 token
OCR_LLM_MODEL模型名
GITLAB_API_TOKEN帶 api scope 的 token;缺失時回退 CI_JOB_TOKEN

客製化:避免每次 push 都重審

GitLab 無「僅在建立時」事件,推薦在跑評審前檢查已有 OCR note,有則跳過(省 LLM token)。完整 Python wrapper 見上游 ci.md——核心邏輯是查 MR notes 是否含 OpenCodeReview

疑難排解

症狀原因 / 修復
Cannot find merge-base淺克隆。GitHub 保留 fetch-depth: 0;GitLab 保留 GIT_DEPTH: 0
Failed to parse OCR outputOCR_LLM_URLOCR_LLM_AUTH_TOKEN 錯誤
評論落錯行評審到張貼間 diff 偏移;貼文腳本自動回退為一般 issue 評論
📖 教學解說:CI/CD 實戰

六步 CI 模式的因果邏輯

六步不是任意順序:① 觸發(PR 事件)→ ② 安裝(runner 臨時)→ ③ 配置 LLM(secret)→ ④ 跑評審(區間模式 + JSON)→ ⑤ 解析 JSON(提取 comments)→ ⑥ 回貼評論(PR API)。每步都有原因:為什麼區間模式?因為 PR 只需審 diff。為什麼 JSON?因為腳本需要結構化資料。

兩類憑證的致命混淆

LLM 憑證(產生發現)和 PR/MR 寫 token(回貼評論)是完全獨立的。LLM 憑證是你的 API key,PR 寫 token 是 GitHub/GitLab 的。GitHub 的 GITHUB_TOKEN 自動提供後者;GitLab 用 CI_JOB_TOKEN 但建議用顯式 GITLAB_API_TOKEN(scope 更完整)。混淆這兩者是 CI 故障的 #1 原因。

GitHub 的 ${{ }} 安全陷阱

GitHub 在 shell 解析前就做了 ${{ }} 的文字替換。如果 PR 標題含 $(rm -rf /) 或反引號,它會在你的 runner 上被執行。安全做法:把 PR 可控的值透過 env: 傳入,在 run: 中用 $PR_TITLE(shell 變數)而非 ${{ github.event.pull_request.title }}

🔍 Worked Example:GitHub Actions 完整設定

Step 1 — 下載 workflow 檔

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

Step 2 — 在 GitHub repo Settings → Secrets 新增

OCR_LLM_URL, OCR_LLM_AUTH_TOKEN, OCR_LLM_MODEL

Step 3 — 建立 PR 觸發評審

git checkout -b fix/auth-bug && git commit --allow-empty -m 'test: trigger OCR' && git push origin fix/auth-bug

Step 4 — 在 GitHub 建立 PR,觀察 Actions tab

查看 OCR review job 的輸出

Step 5 — 在 PR 中看到內聯評論

✓ OCR 在 diff 中貼了 2 條評論

預期產出

Run OCR review
  Installing ocr...
  Configuring LLM endpoint...
  Reviewing 3 files...
  Posting 2 inline comments to PR...
  ✓ Done (45s, 12,340 tokens)

常見錯誤與診斷

錯誤訊息診斷修復
Cannot find merge-base淺克隆GitHub: fetch-depth: 0;GitLab: GIT_DEPTH: 0
Failed to parse OCR outputOCR_LLM_URL 或 OCR_LLM_AUTH_TOKEN 錯誤重設 CI secrets
評論落錯行評審到張貼間 diff 偏移貼文腳本自動回退為一般 issue 評論
${{ }} 注入攻擊PR 標題含 shell 元字元用 env: 傳入,不要直接插值進 run:

練習 / 驗收清單

  • 能說出六步 CI 模式的順序與原因
  • 能區分兩類憑證(LLM 憑證 vs PR 寫 token)
  • 能解釋為何不要把 ${{ }} 描述進 run:
  • 能設定 GitHub Actions workflow
  • 能設定 GitLab CI 並避免每次 push 重審
看完這頁你應該能說出:六步 CI 模式、兩類憑證的差別、為何不要把 ${{ }} 插值進 run:、以及 GitLab「避免每次 push 重審」的技法。

延伸閱讀:CLI 參考(JSON 輸出) · 設定 · 評審規則