最近隨著團隊的人數變多
看MR的次數也跟著增加
改動的內容一多
MR就無法看得很仔細
剛好公司有提供AI 的API
所以就來實作AI Code Review
目標是在每次發MR時
AI針對diff的內容給出建議
並且自動留言到MR
步驟如下
1. 建立Job
在原本的.gitlab-ci.yml
加入review的Job
並且只有在Merge Request的時後才發動
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| stages: - build
ai-code-review: stage: build image: python:3.11
rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: on_success - when: never
before_script: - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
script: - pip install requests - python House-Demo/Scripts/ai_code_review.py
|
2. 在專案內新建ai_code_review.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| import os import re import subprocess import requests import sys
# ===================== # Environment Variables # ===================== AI_API_KEY = os.getenv("AI_API_KEY") API_URL = os.getenv("API_URL")
TARGET_BRANCH = os.getenv("CI_MERGE_REQUEST_TARGET_BRANCH_NAME") GITLAB_API = os.getenv("CI_API_V4_URL") PROJECT_ID = os.getenv("CI_PROJECT_ID") MR_IID = os.getenv("CI_MERGE_REQUEST_IID") GITLAB_TOKEN = os.getenv("AI_REVIEW_COMMENT_TOKEN")
# ===================== # Git Diff # ===================== diff = subprocess.check_output( ["git", "diff", f"origin/{TARGET_BRANCH}..HEAD"] ).decode("utf-8", errors="ignore")
filtered = [] current = [] keep = False
for line in diff.splitlines(): if line.startswith("diff --git"): if current and keep: filtered.extend(current)
current = [line] keep = bool(re.search(r'\.(cs|csproj|sln)$', line)) else: current.append(line)
if current and keep: filtered.extend(current)
filtered_diff = "\n".join(filtered)
# ===================== # Prompt (.NET only) # ===================== prompt = f""" 你是一位資深 .NET / ASP.NET Core 架構師,請針對以下 Git diff 做 Code Review。
請只針對「實質問題」給建議,不要評論排版或命名風格。
請特別注意: 1. 潛在 Bug(null reference、async/await 誤用、thread safety) 2. ASP.NET Core 常見陷阱(DI lifetime、middleware、filter) 3. 安全性(SQL Injection、XSS、反序列化風險、過度信任輸入) 4. 效能(不必要的 allocation、LINQ 誤用、同步 IO) 5. 可維護性(過度耦合、責任不清)
請用條列方式輸出,最多 10 點,越嚴重的排越前面。
Git diff: {filtered_diff} """
# ===================== # Call LLM # ===================== resp = requests.post( API_URL+AI_API_KEY, headers={ "Content-Type": "application/json", }, json={ "contents": [ { "parts": [ { "text": prompt } ] } ] } ) print(resp.json())
review = resp.json()["candidates"][0]["content"]["parts"][0]["text"]
print("===== AI Code Review (.NET) =====") print(review)
# ===================== # Post to Merge Request # ===================== note_url = ( f"{GITLAB_API}/projects/{PROJECT_ID}" f"/merge_requests/{MR_IID}/notes" )
r = requests.post( note_url, headers={ "PRIVATE-TOKEN": GITLAB_TOKEN }, json={ "body": review } )
r.raise_for_status()
print("✅ AI review posted to Merge Request")
|
demo的專案是用Google AI Studio提供的API
實際上API的參數、回傳、Key值
都需要依實際狀況調整
3. 設定gitlab的CI/CD變數
因為要讓pipeline可以自動留note到MR
所以需要申請一個token
可以到Settings的Access tokens新增
scopes勾選api
Role至少要是developer以上


再來就可以到Settings的CI/CD
新增剛剛.py裡面所需要的環境變數
Flags記得不要勾選Protect variable
並且選 Expand variable reference
否則會讀取不到

4. 建立PR
接著就是建立分支,並且發起MR
當pipeline跑完後
就可以看到AI的 review建議已經新增到MR上面

這個review的建議
很大程度受到AI模型、專案規模、Prompt的精準度影響
所以絕對不是照單全收
實測上會給出很多over design的建議
還是得由工程師來把關
不過多了AI協助review
多少還是有幫助的