GitLab CI 自動 Claude Code Review

§1

背景與目標

GitLab 後端 repo 缺少自動化 code review 機制。希望 MR 建立或 push 新 commit 時,自動觸發 Claude AI 審查並將結果以 comment 形式貼到 MR,作為 human reviewer 的輔助。

目標:

  • MR pipeline 自動觸發,不需人工操作
  • Review 結果聚焦本專案規範(DDD / RLS / jedi-* / 權限模型)
  • 不阻擋 MR 合併(allow_failure: true),僅為建議
  • 無需額外依賴(原生 Node.js,不引入 npm 套件管線)
§2

需求範圍

觸發條件

  • GitLab CI pipeline rules:只在 $CI_PIPELINE_SOURCE == "merge_request_event" 觸發
  • 新 MR 建立、MR 有新 commit push、MR rebase 皆會觸發

Diff 篩選規則

  • 副檔名白名單:.py, .sql, .yml, .yaml, .json
  • 路徑排除:migrations/, tests/, __pycache__/
  • Diff 長度上限 80,000 chars,超過截斷並於 prompt 標註

審查面向(Claude prompt 覆蓋)

面向 重點
架構合規性 DDD / hexagonal 分層(route 不存取 DB、app service 不 import ORM model、domain 不依賴 infra)
多租戶安全 tenant / org filter、RLS 是否可能被繞過、跨租戶洩漏風險
資料庫 SQLAlchemy N+1、lazy/selectin/joined load 使用、缺失 index
API 設計 response envelope 一致性、HTTP status code、錯誤處理(jedi_common exception + ErrorCode)
安全性 SQL injection、敏感資料(password/token/PII)洩漏、角色權限檢查(manager / reviewer / auditor / viewer)

輸出格式(繁體中文 Markdown)

  1. 整體評分 1-10,附一句話評語
  2. 摘要 ≤3 句
  3. 問題清單:每項含檔案路徑、行號、嚴重程度(🔴 高 / 🟡 中 / 🟢 低)、說明、建議修法
  4. 優點:具體指出做得好的檔案 / 設計決策

行為細節

情境 行為
MR pipeline 產出 claude-review.md artifact + POST comment 至 MR
非 MR pipeline 只產檔、不呼叫 API、不發 comment
無相關檔案變更 只產檔(內容為「無符合審查條件的檔案變更」),不呼叫 API
diff 為空 只產檔、不呼叫 API
Anthropic / GitLab API 呼叫失敗 job 失敗,但 allow_failure: true 不擋 MR
§3

架構

┌─────────────────────────────────────────────────────────────┐
│ GitLab CI Pipeline (merge_request_event 觸發)               │
│                                                             │
│  .gitlab-ci.yml                                             │
│   └─ review stage                                           │
│       └─ claude-review job (node:20-alpine)                 │
│           1. apk add git curl jq                            │
│           2. node scripts/claude-review.js                  │
│           3. artifact: claude-review.md (2 weeks)           │
└─────────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────┐
│ scripts/claude-review.js (原生 Node.js)                     │
│                                                             │
│  1. git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME   │
│  2. git diff origin/<target>...HEAD                         │
│     → 過濾副檔名 + 排除路徑                                 │
│     → 80k 截斷                                              │
│  3. Anthropic Messages API (claude-sonnet-4-5)              │
│  4. 寫入 claude-review.md                                   │
│  5. POST GitLab Notes API                                   │
└─────────────────────────────────────────────────────────────┘
§4

技術選型

項目 選擇 原因
Runtime Node.js 20 (alpine) 原生 https / child_process 夠用,不用 python 生態
HTTP client 內建 https 模組 不引入第三方依賴(無 package.json 維護成本)
子行程 execFileSync + 參數陣列 避免 shell injection
Model claude-sonnet-4-5 平衡速度與審查品質
max_tokens 4096 足以容納結構化 review 輸出
§5

環境變數需求

變數 來源 用途
ANTHROPIC_API_KEY GitLab Settings → CI/CD → Variables(Masked) Anthropic API 認證
GITLAB_TOKEN GitLab Settings → CI/CD → Variables(Masked,Project Access Token api scope) POST comment 至 MR
CI_SERVER_URL GitLab CI 預設 GitLab API base URL
CI_PROJECT_ID GitLab CI 預設 專案 ID
CI_MERGE_REQUEST_IID GitLab CI 預設(MR pipeline) MR 編號
CI_MERGE_REQUEST_TARGET_BRANCH_NAME GitLab CI 預設(MR pipeline) 目標 branch
CI_COMMIT_SHA GitLab CI 預設 Comment 標頭顯示 short SHA
§6

安全性考量

  • 子行程透過參數陣列傳入(execFileSync('git', [...])),避免 shell injection
  • ANTHROPIC_API_KEY / GITLAB_TOKEN 僅透過環境變數讀取,不寫入 log 或 artifact
  • claude-review.md artifact 內容僅為 review 結果,不包含原始 diff
  • GIT_DEPTH: 0 完整抓取 commit 歷史以確保能 git fetch origin <target> 成功
§7

未來延伸(非本次範圍)

§8

相關檔案

檔案 用途
.gitlab-ci.yml GitLab CI 設定
scripts/claude-review.js Review 腳本
docs/changelog/2026-04-24-gitlab-ci-claude-auto-code-review.md 本次變更紀錄