feat(diff 過濾): 改讀 .reviewignore 外部化 diff 排除清單
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
# AI Code Review 忽略清單
|
||||||
|
# 符合下列前綴/路徑的檔案不會納入送給 LLM 的 git diff。
|
||||||
|
# 規則:每行一個路徑前綴(相對 repo 根),# 開頭為註解,空行略過。
|
||||||
|
# 註:任何深度的 node_modules/ 一律排除(程式內建保險),此處列出僅為明示。
|
||||||
|
|
||||||
|
.gitea/
|
||||||
|
.github/
|
||||||
|
README.md
|
||||||
|
TODO.md
|
||||||
|
package-lock.json
|
||||||
|
src/package-lock.json
|
||||||
|
dist/
|
||||||
|
node_modules/
|
||||||
+43
-11
@@ -41,23 +41,55 @@ export function getBotReviewOutcome(message) {
|
|||||||
return match?.[1]?.toLowerCase() || 'unknown';
|
return match?.[1]?.toLowerCase() || 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 找不到 .reviewignore 時(例如其他 repo 未提供)採用的內建預設排除清單。
|
||||||
|
// 任何深度的 node_modules/ 另由 filterDiff 內建強制排除,不倚賴此清單。
|
||||||
|
export const DEFAULT_REVIEW_IGNORE = [
|
||||||
|
'.gitea/',
|
||||||
|
'.github/',
|
||||||
|
'README.md',
|
||||||
|
'TODO.md',
|
||||||
|
'package-lock.json',
|
||||||
|
'src/package-lock.json',
|
||||||
|
'dist/',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取得目前 PR 的完整 Git diff,並排除 CI/文件等不需審查的路徑(.gitea/、.github/、README.md、TODO.md)。
|
* 解析 .reviewignore 文字為排除前綴陣列(gitignore 風格)。
|
||||||
|
* 規則:每行一個路徑前綴,trim 後略過空行與 `#` 開頭的註解行。
|
||||||
|
* @param {string} text - .reviewignore 檔案內容。
|
||||||
|
* @returns {string[]} 排除前綴清單。
|
||||||
|
*/
|
||||||
|
export function parseReviewIgnore(text) {
|
||||||
|
return String(text || '')
|
||||||
|
.split('\n')
|
||||||
|
.map(l => l.trim())
|
||||||
|
.filter(l => l && !l.startsWith('#'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 從被審 PR 的 head ref 取得 `.reviewignore` 並解析為排除清單。
|
||||||
|
* 檔案不存在或為空時退回 {@link DEFAULT_REVIEW_IGNORE}。
|
||||||
|
* @returns {Promise<string[]>} 套用於 diff 過濾的排除前綴清單。
|
||||||
|
*/
|
||||||
|
export async function getReviewIgnore() {
|
||||||
|
const patterns = parseReviewIgnore(await getFileContentAtRef('.reviewignore'));
|
||||||
|
if (patterns.length > 0) {
|
||||||
|
line(`已套用 .reviewignore:${patterns.length} 條排除規則`);
|
||||||
|
return patterns;
|
||||||
|
}
|
||||||
|
return DEFAULT_REVIEW_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取得目前 PR 的完整 Git diff,並依 `.reviewignore`(讀不到時用內建預設)排除不需審查的路徑。
|
||||||
* 透過 Gitea `GET /repos/{repo}/pulls/{index}.diff`(純文字 diff),授權使用 GITEA_TOKEN。
|
* 透過 Gitea `GET /repos/{repo}/pulls/{index}.diff`(純文字 diff),授權使用 GITEA_TOKEN。
|
||||||
* @returns {Promise<string>} 過濾後的 diff 文字。
|
* @returns {Promise<string>} 過濾後的 diff 文字。
|
||||||
* @throws {Error} 當 Gitea API 請求失敗(網路錯誤、逾時或非 2xx 狀態)時拋出 axios 例外。
|
* @throws {Error} 當 Gitea 取 diff 的 API 請求失敗(網路錯誤、逾時或非 2xx 狀態)時拋出 axios 例外。
|
||||||
*/
|
*/
|
||||||
export async function getPRDiff() {
|
export async function getPRDiff() {
|
||||||
|
const patterns = await getReviewIgnore();
|
||||||
const resp = await axios.get(api(`/repos/${GITEA_REPOSITORY}/pulls/${PR_NUMBER}.diff`), { headers: headers(), timeout: 60000, httpsAgent });
|
const resp = await axios.get(api(`/repos/${GITEA_REPOSITORY}/pulls/${PR_NUMBER}.diff`), { headers: headers(), timeout: 60000, httpsAgent });
|
||||||
return filterDiff(resp.data, [
|
return filterDiff(resp.data, patterns);
|
||||||
'.gitea/',
|
|
||||||
'.github/',
|
|
||||||
'README.md',
|
|
||||||
'TODO.md',
|
|
||||||
'package-lock.json',
|
|
||||||
'src/package-lock.json',
|
|
||||||
'dist/',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user