From d04a256a3b11d19ebd9dc5092d93fbec9fd572e9 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 22 Jun 2026 23:02:13 +0800 Subject: [PATCH 1/2] =?UTF-8?q?docs(README):=20=E5=90=8C=E6=AD=A5=20Step6?= =?UTF-8?q?=20=E8=A1=8C=E7=82=BA=E8=AA=AA=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43d0eb9..6e9649f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ 3. 檢查是否為 AI 助理自動提交;若不是,選定 LLM provider/model、載入角色、取得 PR diff,將服務名稱、模型名稱與角色資訊 Comment 到 Pull Request,並讓每個角色個別分析 Git Diff 產生新問題表格(問題等級、角色名稱、問題位置或行數、修改建議) 4. 讀取來源分支中的所有未解決舊問題(問題檔案 `.gitea/ai-review/findings.json`)加上新問題後,去除重複產生本次 PR 的問題表格(PR問題表格)覆蓋問題檔案 5. 讀取來源分支中的排除問題檔案(`.gitea/ai-review/exclusions.json`),用來過濾 PR 問題表格中不需要處理的問題 -6. 將 PR 問題表格寫入 `.gitea/ai-review/findings.json`,並發布一個 Gitea Review:Review 本文用「嚴重/警告/建議」三欄統計各等級數量;之後將可找出檔案與行數的問題依照嚴重等級排序後加入 Review Comments 內,每個 Comment 包含嚴重等級/審查員/問題/建議,其中「問題」是審查員判斷該處有問題的原因,不是檔案路徑或行號 +6. 將 PR 問題表格寫入 `.gitea/ai-review/findings.json`,並發布一個 Gitea Review:Review 本文只統計本次新發現的問題,使用「嚴重/警告/建議」三欄呈現各等級數量;之後將可找出檔案與行數的問題依照嚴重等級排序後加入 Review Comments 內,每個 Comment 包含嚴重等級/審查員/問題/建議,其中「問題」是審查員判斷該處有問題的原因,不是檔案路徑或行號 7. 驗證來源分支中的 `findings.json` 與 `exclusions.json` 是否為合法 JSON array;格式錯誤時先嘗試透過 AI 修正內容,再重新驗證;修正後仍不合法才 exit 1;檔案不存在則建立並寫入 `[]` 8. Commit 問題檔案,只將 workspace 中實際存在的 `.gitea/ai-review/findings.json` 與 `.gitea/ai-review/exclusions.json` 覆蓋到記憶區;workspace 沒有的問題檔就略過。自動提交的 commit message 會帶上 `[ai-review-bot]`,供 workflow 判斷是否要跳過重跑 9. 如果 PR 問題表格中有嚴重問題,先嘗試透過 Gitea API 對 PR head commit 建立 failure status 來阻擋 PR 合併;若 API 阻擋失敗,才改用原本的 workflow failure 處理(`exit 1`) -- 2.53.0 From 279bcc2101618c595901b57b4aa374cb46c8b335 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 22 Jun 2026 23:02:21 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix(=E8=A9=95=E8=AB=96=E7=99=BC=E5=B8=83):?= =?UTF-8?q?=20=E5=8F=AA=E7=B5=B1=E8=A8=88=E6=96=B0=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E4=B8=A6=E6=8E=92=E5=BA=8F=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/comments.js | 19 ++++++++++++------- app/comments.test.js | 4 +++- app/main.js | 6 +++++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/comments.js b/app/comments.js index 587dc54..c597c6d 100644 --- a/app/comments.js +++ b/app/comments.js @@ -84,16 +84,21 @@ function toReviewComment(f) { } /** - * 發布單一 Gitea review:本文統計可找出檔案與行數的問題, - * comments 只包含可定位到檔案與行數的 findings,並依嚴重等級排序。 + * 發布單一 Gitea review: + * - summaryFindings 只用來統計本文數字 + * - commentFindings 用來產生 review comments,並依嚴重等級排序 */ export async function postFindingsReview(findings, deps = {}) { - const { postReview = postPullReview } = deps; - const sorted = [...findings].sort(bySeverity); - const comments = sorted.map(toReviewComment).filter(Boolean); - const body = buildReviewSummary(sorted); + const { + postReview = postPullReview, + summaryFindings = findings, + commentFindings = findings, + } = deps; + const sortedComments = [...commentFindings].sort(bySeverity); + const comments = sortedComments.map(toReviewComment).filter(Boolean); + const body = buildReviewSummary(summaryFindings); await postReview({ body, comments }); - ok(`review 發布: total=${sorted.length} commentable=${comments.length}`); + ok(`review 發布: summary=${summaryFindings.length} total=${sortedComments.length} commentable=${comments.length}`); } /** diff --git a/app/comments.test.js b/app/comments.test.js index a6de0d8..c0ffab4 100644 --- a/app/comments.test.js +++ b/app/comments.test.js @@ -196,12 +196,14 @@ describe('postFindingsReview', () => { ]; await postFindingsReview(findings, { + summaryFindings: findings.filter(f => f.is_new !== false), + commentFindings: findings, postReview: async (args) => { reviewCalls.push(args); }, }); assert.equal(reviewCalls.length, 1); assert.match(reviewCalls[0].body, /\| 🔴 嚴重 \| 🟡 警告 \| 🔵 建議 \|/); - assert.match(reviewCalls[0].body, /\| 1 筆 \| 1 筆 \| 1 筆 \|/); + assert.match(reviewCalls[0].body, /\| 0 筆 \| 1 筆 \| 1 筆 \|/); assert.deepEqual( reviewCalls[0].comments.map(c => c.path), ['app/a.js', 'app/b.js', 'app/c.js'], diff --git a/app/main.js b/app/main.js index a1d7082..e519818 100644 --- a/app/main.js +++ b/app/main.js @@ -111,7 +111,11 @@ async function main() { const reviewDir = repoDir || WORKSPACE; saveFindings(WORKSPACE, filtered, reviewDir); try { - await postFindingsReview(filtered); + const newFindings = filtered.filter(f => f.is_new !== false); + await postFindingsReview(filtered, { + summaryFindings: newFindings, + commentFindings: filtered, + }); ok('Step6 完成'); } catch (e) { warn(`review 發布失敗(繼續執行): ${e.message}`); -- 2.53.0