feat(ai-code-review): 建問題模式導向 issue,並整併流程調整、文件與 CI #11

Closed
opened 2026-07-20 08:03:44 +00:00 by gitea-actions · 12 comments

變更摘要

本 PR 將 ai-code-review action 分支的完整成果併入 develop,主要含四塊:

  1. 建問題模式重構(feat)create-issue: 'true' 時,審查留言(工具/diff/角色/嚴重問題/警告+建議)全部改發到追蹤 issue、不再張貼到 PR;不執行「舊留言標過時/resolve」;issue 延後到「確定有保留問題」才建立;無保留問題或無可審查變更則不建 issue、PR 也完全不留言(靜默通過);有問題時最後在 PR 回貼一則 issue 連結並補掛標籤,形成雙向關聯。
  2. 審查流程步驟調整(refactor):將「標記舊留言過時/resolve」提前到偵測 AI 工具之前,並依新順序重編所有步驟編號與說明。
  3. 修正(gitrepo):補抓淺層 checkout 的 base 歷史,避免 merge-base 計算失敗。
  4. 文件與 CI:補齊 action.ymlsrc 各模組文件、重建 readme.md,新增 .gitea/workflows/ci.yaml(多工具 code review 驗證)並啟用建問題模式。

影響範圍

範圍 說明
action 執行流程 src/index.js main() 依模式分流:留言去向、跳過 resolveOldComments、issue 延後建立、severe/others 導向 issue、有問題才在 PR 回貼連結
Gitea API src/lib/gitea.js 新增 addLabelsToIssue
留言模板 src/lib/templates.js 新增 issueLinkComment
審查核心 src/lib/review.js 新增 postSevereToIssue,移除 createIssueWithFindingssortFindingsForIssue
git base 解析 src/lib/gitrepo.js 補抓淺層 checkout 的 base 歷史
文件與 CI readme.mdaction.yml.gitea/workflows/ci.yaml.gitea/workflows/readme.md

風險與注意事項

  • 建問題模式行為明顯改變:啟用後 PR 上不再有審查留言(有問題時改為 issue + 一則連結留言;無問題時完全不留言),請確認團隊流程可接受。
  • 端對端行為需靠 CI 實測:本地僅完成語法與模組載入驗證,實際 issue/PR 互動需一次 CI 觸發確認。
  • readme.md 尚未反映「建問題模式導向 issue」的最新行為與新/移除的函式,建議後續以 doc-funcs 重建文件。
  • 各檔頭部「更新時間」時間戳仍為 2026/07/17 18:49:58,未刷新。

本問題由 AI Code Review 依 PR #6 的審查結果自動建立,問題明細見下方留言。

<!-- ai-code-review --> ## 變更摘要 本 PR 將 ai-code-review action 分支的完整成果併入 `develop`,主要含四塊: 1. **建問題模式重構(feat)**:`create-issue: 'true'` 時,審查留言(工具/diff/角色/嚴重問題/警告+建議)全部改發到追蹤 issue、不再張貼到 PR;不執行「舊留言標過時/resolve」;issue 延後到「確定有保留問題」才建立;**無保留問題或無可審查變更則不建 issue、PR 也完全不留言(靜默通過)**;有問題時最後在 PR 回貼一則 issue 連結並補掛標籤,形成雙向關聯。 2. **審查流程步驟調整(refactor)**:將「標記舊留言過時/resolve」提前到偵測 AI 工具之前,並依新順序重編所有步驟編號與說明。 3. **修正(gitrepo)**:補抓淺層 checkout 的 base 歷史,避免 merge-base 計算失敗。 4. **文件與 CI**:補齊 `action.yml`/`src` 各模組文件、重建 `readme.md`,新增 `.gitea/workflows/ci.yaml`(多工具 code review 驗證)並啟用建問題模式。 ## 影響範圍 | 範圍 | 說明 | | --- | --- | | action 執行流程 | `src/index.js` `main()` 依模式分流:留言去向、跳過 resolveOldComments、issue 延後建立、severe/others 導向 issue、有問題才在 PR 回貼連結 | | Gitea API | `src/lib/gitea.js` 新增 `addLabelsToIssue` | | 留言模板 | `src/lib/templates.js` 新增 `issueLinkComment` | | 審查核心 | `src/lib/review.js` 新增 `postSevereToIssue`,移除 `createIssueWithFindings`、`sortFindingsForIssue` | | git base 解析 | `src/lib/gitrepo.js` 補抓淺層 checkout 的 base 歷史 | | 文件與 CI | `readme.md`、`action.yml`、`.gitea/workflows/ci.yaml`、`.gitea/workflows/readme.md` | ## 風險與注意事項 - **建問題模式行為明顯改變**:啟用後 PR 上不再有審查留言(有問題時改為 issue + 一則連結留言;無問題時完全不留言),請確認團隊流程可接受。 - **端對端行為需靠 CI 實測**:本地僅完成語法與模組載入驗證,實際 issue/PR 互動需一次 CI 觸發確認。 - `readme.md` 尚未反映「建問題模式導向 issue」的最新行為與新/移除的函式,建議後續以 doc-funcs 重建文件。 - 各檔頭部「更新時間」時間戳仍為 `2026/07/17 18:49:58`,未刷新。 --- > 本問題由 AI Code Review 依 PR #6 的審查結果自動建立,問題明細見下方留言。

🤖 AI Code Review|審查工具

項目 內容
工具 codex
版本 codex-cli 0.144.6
模型 (工具預設)
審查 commit 4c2b6d426569441d6c3d8ad892117b9fcdee9e11
Run Job #25
flowchart LR
    A[整理 git diff] --> B[⚔️ 攻擊方找問題]
    B --> C[🛡️ 防守方裁決]
    C --> D[保存 findings]
    D --> E[留言到 PR]
<!-- ai-code-review --> ## 🤖 AI Code Review|審查工具 | 項目 | 內容 | | --- | --- | | 工具 | `codex` | | 版本 | `codex-cli 0.144.6` | | 模型 | (工具預設) | | 審查 commit | `4c2b6d426569441d6c3d8ad892117b9fcdee9e11` | | Run Job | [#25](https://gitea.jsc.idv.tw/node-actions/ai-code-review/actions/runs/1593) | ```mermaid flowchart LR A[整理 git diff] --> B[⚔️ 攻擊方找問題] B --> C[🛡️ 防守方裁決] C --> D[保存 findings] D --> E[留言到 PR] ```

📋 變更摘要(送審 git diff)

檔案 用途 git diff 長度 最後更新時間
action.yml 定義 Action 中繼資料與輸入參數 95 行/4205 字元 2026/07/20 15:00:23
readme.md 說明專案功能、流程與使用方式 276 行/23829 字元(過長截斷送審) 2026/07/20 16:01:05
src/index.js 編排並執行多角色程式碼審查 320 行/14204 字元 2026/07/20 15:00:15
src/lib/agents.js 偵測並執行 AI 審查工具 14 行/503 字元 2026/07/20 09:46:12
src/lib/context.js 載入 Action 輸入與執行環境 31 行/1398 字元 2026/07/20 15:00:23
src/lib/gitea.js 封裝 Gitea API 操作 121 行/5278 字元 2026/07/20 16:01:05
src/lib/gitrepo.js 處理 Git 差異、歷史與提交 222 行/9110 字元 2026/07/20 16:01:05
src/lib/review.js 執行審查、裁決與結果處理 582 行/24967 字元(過長截斷送審) 2026/07/20 16:01:05
src/lib/roles.js 載入並分類審查角色設定 14 行/586 字元 2026/07/20 09:46:12
src/lib/templates.js 產生審查留言的固定模板 165 行/5949 字元 2026/07/20 15:00:32

共 10 個檔案納入審查;另有 7 個檔案依 .reviewignore 排除。

<!-- ai-code-review --> ## 📋 變更摘要(送審 git diff) | 檔案 | 用途 | git diff 長度 | 最後更新時間 | | --- | --- | --- | --- | | `action.yml` | 定義 Action 中繼資料與輸入參數 | 95 行/4205 字元 | 2026/07/20 15:00:23 | | `readme.md` | 說明專案功能、流程與使用方式 | 276 行/23829 字元(過長截斷送審) | 2026/07/20 16:01:05 | | `src/index.js` | 編排並執行多角色程式碼審查 | 320 行/14204 字元 | 2026/07/20 15:00:15 | | `src/lib/agents.js` | 偵測並執行 AI 審查工具 | 14 行/503 字元 | 2026/07/20 09:46:12 | | `src/lib/context.js` | 載入 Action 輸入與執行環境 | 31 行/1398 字元 | 2026/07/20 15:00:23 | | `src/lib/gitea.js` | 封裝 Gitea API 操作 | 121 行/5278 字元 | 2026/07/20 16:01:05 | | `src/lib/gitrepo.js` | 處理 Git 差異、歷史與提交 | 222 行/9110 字元 | 2026/07/20 16:01:05 | | `src/lib/review.js` | 執行審查、裁決與結果處理 | 582 行/24967 字元(過長截斷送審) | 2026/07/20 16:01:05 | | `src/lib/roles.js` | 載入並分類審查角色設定 | 14 行/586 字元 | 2026/07/20 09:46:12 | | `src/lib/templates.js` | 產生審查留言的固定模板 | 165 行/5949 字元 | 2026/07/20 15:00:32 | > 共 10 個檔案納入審查;另有 7 個檔案依 `.reviewignore` 排除。

⚔️ 攻擊方登場

角色 面向 個性
🗡️ Assassin 安全性(security) 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard 風格(style) 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo 可維護性(maintainability) 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage 邏輯(logic) 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya 測試(testing) 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
Rogue 效率(efficiency) 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」
<!-- ai-code-review --> ## ⚔️ 攻擊方登場 | 角色 | 面向 | 個性 | | --- | --- | --- | | 🗡️ **Assassin** | 安全性(security) | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | 🎼 **Bard** | 風格(style) | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | 🧰 **Leo** | 可維護性(maintainability) | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | 🔮 **Mage** | 邏輯(logic) | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | 🧪 **Maya** | 測試(testing) | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | ⚡ **Rogue** | 效率(efficiency) | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 |

🛡️ 防守方登場

角色 面向 個性
🛡️ Paladin 裁決(verdict) 沉穩公正、就事論事,不護短也不冤枉,只依排除事項與原始碼脈絡裁定問題成立與否
<!-- ai-code-review --> ## 🛡️ 防守方登場 | 角色 | 面向 | 個性 | | --- | --- | --- | | 🛡️ **Paladin** | 裁決(verdict) | 沉穩公正、就事論事,不護短也不冤枉,只依排除事項與原始碼脈絡裁定問題成立與否 |

🔴 嚴重|🗡️ Assassin

位置action.yml 第 49–59 行

問題描述

新增的長效 PAT 會以 INPUT_PUSH-TOKEN 環境變數存在於整個 Node Action 執行期間,而審查流程會啟動可受 PR diff 提示注入影響的 AI CLI 子程序。若子程序繼承目前環境,攻擊者可在惡意 diff 中誘導工具讀取並外傳此 PAT,取得推送儲存庫甚至更廣的權限;pushWithCredential 最後才安全注入認證,無法消除 PAT 在前面 AI 階段已暴露的風險。

修改建議

不要把長效 PAT 作為執行 AI 審查之 Action 的輸入。將推送結果拆到獨立 job/受信任 workflow,使用短效、限單一儲存庫與限目標分支的憑證;同時讓所有 AI CLI 子程序使用明確 allowlist 建立環境,排除 INPUT_PUSH-TOKEN、各類 token 與 secrets。若無法拆分,讀取後立即從 process.env 移除,並確保 PAT 只傳給單次 git push 子程序。

建議寫法

// 載入後立即移除,且 runAgent 必須使用 allowlist env
const pushToken = (process.env['INPUT_PUSH-TOKEN'] || '').trim();
delete process.env['INPUT_PUSH-TOKEN'];

// 更安全:將 PAT 推送移到獨立、受信任且不執行 PR 內容的 job。
<!-- ai-code-review --> ### 🔴 嚴重|🗡️ Assassin **位置**:`action.yml` 第 49–59 行 **問題描述** 新增的長效 PAT 會以 `INPUT_PUSH-TOKEN` 環境變數存在於整個 Node Action 執行期間,而審查流程會啟動可受 PR diff 提示注入影響的 AI CLI 子程序。若子程序繼承目前環境,攻擊者可在惡意 diff 中誘導工具讀取並外傳此 PAT,取得推送儲存庫甚至更廣的權限;`pushWithCredential` 最後才安全注入認證,無法消除 PAT 在前面 AI 階段已暴露的風險。 **修改建議** 不要把長效 PAT 作為執行 AI 審查之 Action 的輸入。將推送結果拆到獨立 job/受信任 workflow,使用短效、限單一儲存庫與限目標分支的憑證;同時讓所有 AI CLI 子程序使用明確 allowlist 建立環境,排除 `INPUT_PUSH-TOKEN`、各類 token 與 secrets。若無法拆分,讀取後立即從 `process.env` 移除,並確保 PAT 只傳給單次 `git push` 子程序。 **建議寫法** ``` // 載入後立即移除,且 runAgent 必須使用 allowlist env const pushToken = (process.env['INPUT_PUSH-TOKEN'] || '').trim(); delete process.env['INPUT_PUSH-TOKEN']; // 更安全:將 PAT 推送移到獨立、受信任且不執行 PR 內容的 job。 ```

🟠 警告|🧰 Leo

位置src/index.js 第 119–139 行

問題描述

流程步驟編號被當成跨模組識別值,散落在 index.js、各 library 的日誌與 JSDoc、README 流程圖及功能表。這次僅因插入並延後一步,就必須同步修改大量 步驟2步驟8 字串,而且實際執行順序已變成 1、3~8、2、9~10;未來再調整流程時非常容易讓文件、日誌與程式碼脫節。

修改建議

以穩定的語意階段名稱取代硬編碼序號,例如 TOOL_DETECTIONCOLLECT_DIFFRESOLVE_OLD_COMMENTS,由單一常數表集中決定顯示名稱;README 的流程順序則從同一份定義產生,或至少不要在各函式文件重複紀錄易變的數字。

建議寫法

const PHASE = Object.freeze({
  FAST_RESULT: '快速回報',
  DETECT_TOOL: '偵測 AI 工具',
  COLLECT_DIFF: '整理變更',
  RESOLVE_OLD: '處理舊留言',
  PUBLISH_FINDINGS: '發布審查結果',
});

log(PHASE.DETECT_TOOL, 'INF', `選用工具:${tool.name}。`);
<!-- ai-code-review --> ### 🟠 警告|🧰 Leo **位置**:`src/index.js` 第 119–139 行 **問題描述** 流程步驟編號被當成跨模組識別值,散落在 `index.js`、各 library 的日誌與 JSDoc、README 流程圖及功能表。這次僅因插入並延後一步,就必須同步修改大量 `步驟2`~`步驟8` 字串,而且實際執行順序已變成 1、3~8、2、9~10;未來再調整流程時非常容易讓文件、日誌與程式碼脫節。 **修改建議** 以穩定的語意階段名稱取代硬編碼序號,例如 `TOOL_DETECTION`、`COLLECT_DIFF`、`RESOLVE_OLD_COMMENTS`,由單一常數表集中決定顯示名稱;README 的流程順序則從同一份定義產生,或至少不要在各函式文件重複紀錄易變的數字。 **建議寫法** ``` const PHASE = Object.freeze({ FAST_RESULT: '快速回報', DETECT_TOOL: '偵測 AI 工具', COLLECT_DIFF: '整理變更', RESOLVE_OLD: '處理舊留言', PUBLISH_FINDINGS: '發布審查結果', }); log(PHASE.DETECT_TOOL, 'INF', `選用工具:${tool.name}。`); ```

🟠 警告|🧪 Maya

位置src/index.js 第 260–276 行

問題描述

「無可審查變更」新增了兩種不同結果,且一般模式把清理舊留言延後到新留言發布後,但沒有測試驗證這個關鍵時序。若留言建立或保存 findings 失敗,可能留下半套新結果,或錯誤地清除仍應保留的舊審查;建問題模式也需要確認先前暫存的工具留言確實不會送到 PR 或建立 issue。

修改建議

補上一般模式與建問題模式的空檔案案例。一般模式應斷言先建立本回合「無可審查變更」留言,再呼叫 resolveOldComments,且傳入的集合包含新留言 ID;讓新留言建立失敗時,斷言不會清理舊留言。建問題模式則斷言不呼叫任何 PR/issue 留言 API、不建立 issue、不清理舊留言,並以成功結束。

<!-- ai-code-review --> ### 🟠 警告|🧪 Maya **位置**:`src/index.js` 第 260–276 行 **問題描述** 「無可審查變更」新增了兩種不同結果,且一般模式把清理舊留言延後到新留言發布後,但沒有測試驗證這個關鍵時序。若留言建立或保存 findings 失敗,可能留下半套新結果,或錯誤地清除仍應保留的舊審查;建問題模式也需要確認先前暫存的工具留言確實不會送到 PR 或建立 issue。 **修改建議** 補上一般模式與建問題模式的空檔案案例。一般模式應斷言先建立本回合「無可審查變更」留言,再呼叫 `resolveOldComments`,且傳入的集合包含新留言 ID;讓新留言建立失敗時,斷言不會清理舊留言。建問題模式則斷言不呼叫任何 PR/issue 留言 API、不建立 issue、不清理舊留言,並以成功結束。

🟠 警告| Rogue

位置src/lib/gitrepo.js 第 134–135 行

問題描述

淺層 checkout 一旦首次 merge-base 失敗,就優先執行 --unshallow,會下載整個存取庫歷史;大型或長壽專案可能從原本只需補數十至數百個 commit,膨脹成數 GB 網路傳輸、磁碟占用與分鐘級等待。後面的 --deepen=1000 因已解除 shallow 幾乎失去意義。

修改建議

先採固定深度的漸進補抓並於每次補抓後重試 merge-base,例如依序 deepen 100、1000;只有仍找不到共同祖先時,才把 --unshallow 當最後手段。

建議寫法

const strategies = [
  ['deepen 100', 'fetch', '--no-tags', '--deepen=100', 'origin'],
  ['deepen 1000', 'fetch', '--no-tags', '--deepen=1000', 'origin'],
];
if (gitTrim(cwd, 'rev-parse', '--is-shallow-repository') === 'true') {
  strategies.push(['unshallow', 'fetch', '--no-tags', '--unshallow', 'origin']);
}
<!-- ai-code-review --> ### 🟠 警告|⚡ Rogue **位置**:`src/lib/gitrepo.js` 第 134–135 行 **問題描述** 淺層 checkout 一旦首次 merge-base 失敗,就優先執行 `--unshallow`,會下載整個存取庫歷史;大型或長壽專案可能從原本只需補數十至數百個 commit,膨脹成數 GB 網路傳輸、磁碟占用與分鐘級等待。後面的 `--deepen=1000` 因已解除 shallow 幾乎失去意義。 **修改建議** 先採固定深度的漸進補抓並於每次補抓後重試 merge-base,例如依序 deepen 100、1000;只有仍找不到共同祖先時,才把 `--unshallow` 當最後手段。 **建議寫法** ``` const strategies = [ ['deepen 100', 'fetch', '--no-tags', '--deepen=100', 'origin'], ['deepen 1000', 'fetch', '--no-tags', '--deepen=1000', 'origin'], ]; if (gitTrim(cwd, 'rev-parse', '--is-shallow-repository') === 'true') { strategies.push(['unshallow', 'fetch', '--no-tags', '--unshallow', 'origin']); } ```

🟠 警告|🔮 Mage

位置src/lib/gitrepo.js 第 143–147 行

問題描述

補深 HEAD 的策略實際執行 git fetch ... origin HEAD;這裡的 HEAD 由遠端解析,通常代表遠端預設分支,而不是目前 checkout 的 PR head。最小重現:淺層 checkout 的 PR 分支與預設分支不同、base 歷史已足夠但本地 PR head 祖先不足,且 --unshallow 失敗;「deepen HEAD」會補抓預設分支,當前本地 HEAD 仍缺歷史,最後錯誤地判定無法取得 merge-base。

修改建議

以 PR head 的確切 SHA 或來源分支 refspec 補抓,而非遠端 HEAD;可將 headShaheadRef 傳入 resolveMergeBase,例如 fetch <headSha>,並在每次補抓後驗證目前 HEAD 的 shallow boundary 是否確實前移。

建議寫法

strategies.push([
  'deepen PR head',
  'fetch', '--no-tags', '--deepen=1000', 'origin', headSha,
]);
<!-- ai-code-review --> ### 🟠 警告|🔮 Mage **位置**:`src/lib/gitrepo.js` 第 143–147 行 **問題描述** 補深 HEAD 的策略實際執行 `git fetch ... origin HEAD`;這裡的 `HEAD` 由遠端解析,通常代表遠端預設分支,而不是目前 checkout 的 PR head。最小重現:淺層 checkout 的 PR 分支與預設分支不同、base 歷史已足夠但本地 PR head 祖先不足,且 `--unshallow` 失敗;「deepen HEAD」會補抓預設分支,當前本地 HEAD 仍缺歷史,最後錯誤地判定無法取得 merge-base。 **修改建議** 以 PR head 的確切 SHA 或來源分支 refspec 補抓,而非遠端 `HEAD`;可將 `headSha`/`headRef` 傳入 `resolveMergeBase`,例如 fetch `<headSha>`,並在每次補抓後驗證目前 HEAD 的 shallow boundary 是否確實前移。 **建議寫法** ``` strategies.push([ 'deepen PR head', 'fetch', '--no-tags', '--deepen=1000', 'origin', headSha, ]); ```

🔵 建議|🎼 Bard

位置readme.md 第 41–50 行

問題描述

流程圖依執行順序呈現 1 → 3 → 4 → … → 8 → 2 → 9,步驟編號逆行,讀起來像樂譜突然倒拍。雖然「步驟 2 延後執行」有文字說明,但編號本身仍迫使讀者反覆確認這是刻意安排而非文件筆誤。

修改建議

流程圖改用階段名稱而非固定數字,或依實際執行順序重新編號;若固定編號具有相容性意義,至少把節點標成「延後執行步驟 2」,使逆序意圖在圖中立即可辨。

建議寫法

S8 --> S2[延後執行步驟 2:將舊留言標記解決]
S2 --> S9[步驟 9:嚴重問題逐條掛行留言]
<!-- ai-code-review --> ### 🔵 建議|🎼 Bard **位置**:`readme.md` 第 41–50 行 **問題描述** 流程圖依執行順序呈現 `1 → 3 → 4 → … → 8 → 2 → 9`,步驟編號逆行,讀起來像樂譜突然倒拍。雖然「步驟 2 延後執行」有文字說明,但編號本身仍迫使讀者反覆確認這是刻意安排而非文件筆誤。 **修改建議** 流程圖改用階段名稱而非固定數字,或依實際執行順序重新編號;若固定編號具有相容性意義,至少把節點標成「延後執行步驟 2」,使逆序意圖在圖中立即可辨。 **建議寫法** ``` S8 --> S2[延後執行步驟 2:將舊留言標記解決] S2 --> S9[步驟 9:嚴重問題逐條掛行留言] ```

🔵 建議|🎼 Bard

位置src/index.js 第 194–207 行

問題描述

postComment 這個名字過於泛化,讀者會直覺以為它必定「發布留言」,但建問題模式下可能只寫入 issueBuffer 並回傳 null。名稱與實際副作用走了不同旋律,呼叫端難以一眼判斷留言究竟已發布、被暫存,或發往 PR/issue。

修改建議

將名稱改為能呈現路由語義的 routeReviewCommentpostOrBufferReviewComment,並同步調整呼叫處;若保留 nullable 回傳值,也可定義較明確的結果型別,避免 Promise<Object|null> 的含義只能靠長篇註解補足。

建議寫法

const postOrBufferReviewComment = async (body) => {
  if (ctx.createIssue) {
    if (issue) return gitea.createCommentOnIssue(ctx, issue.number, body);
    issueBuffer.push(body);
    return null;
  }
  const created = await gitea.createIssueComment(ctx, body);
  currentRunCommentIds.add(created.id);
  return created;
};
<!-- ai-code-review --> ### 🔵 建議|🎼 Bard **位置**:`src/index.js` 第 194–207 行 **問題描述** `postComment` 這個名字過於泛化,讀者會直覺以為它必定「發布留言」,但建問題模式下可能只寫入 `issueBuffer` 並回傳 `null`。名稱與實際副作用走了不同旋律,呼叫端難以一眼判斷留言究竟已發布、被暫存,或發往 PR/issue。 **修改建議** 將名稱改為能呈現路由語義的 `routeReviewComment` 或 `postOrBufferReviewComment`,並同步調整呼叫處;若保留 nullable 回傳值,也可定義較明確的結果型別,避免 `Promise<Object|null>` 的含義只能靠長篇註解補足。 **建議寫法** ``` const postOrBufferReviewComment = async (body) => { if (ctx.createIssue) { if (issue) return gitea.createCommentOnIssue(ctx, issue.number, body); issueBuffer.push(body); return null; } const created = await gitea.createIssueComment(ctx, body); currentRunCommentIds.add(created.id); return created; }; ```
Member

🧩 code-review-resolve 處理進度

本議題為 AI Code Review 建問題模式的追蹤議題。以 --issue all 併同 .gitea/ai-review/findings/ 逐條處理後結果如下(對照目前程式碼與 exclusions.json):

# 等級 審查員 位置 處理結果 說明
1 🔴 嚴重 Assassin action.yml 第 49–59 行 已解決 現行 action.yml 已無 push-token input(僅 token/model/create-issue),PAT 停留執行期的疑慮所依附程式碼已移除。
2 🟠 警告 Leo src/index.js 第 119–139 行 ⏭️待人工 以語意階段常數取代硬編步驟編號屬可維護性重構取捨,skill 規範不得硬改,標記待人工。
3 🟠 警告 Maya src/index.js 第 260–276 行 🚫誤報 補測試指控(含建問題模式主流程空檔案案例)已列入 exclusions 裁決為誤報,不重複新增。
4 🟠 警告 Rogue src/lib/gitrepo.js 第 134–135 行 已解決 現行程式碼已把 deepen base/deepen PR HEAD 放前,--unshallow 僅在仍失敗且為淺層 repo 時當最後手段。
5 🟠 警告 Mage src/lib/gitrepo.js 第 143–147 行 已解決 現行程式碼已改用 rev-parse HEAD 取得 headSha,以 fetch --deepen=1000 origin 補抓 PR head。
6 🔵 建議 Bard readme.md 第 41–50 行 🚫誤報 步驟 2 延後執行造成流程圖編號逆行的閱讀負擔已列入 exclusions 裁決為誤報。
7 🔵 建議 Bard src/index.js 第 194–207 行 已解決 postComment 已改名為 queueOrPostComment,名稱已對齊留言路由(發布/暫存)語義。

小計 已解決 4 條、🚫 誤報(已列入 exclusions)2 條、⏭️ 待人工處理 1 條。

⏭️ 待人工處理項目屬設計/效能/慣例取捨(skill 規範不得硬改),已將「只來自議題」的待人工問題(依主題去重)寫回 .gitea/ai-review/findings/2026-07-20-18:31:07.json 追蹤,關閉本議題不會遺失待辦。

  • 已解決:問題於目前程式碼已修復(如 resolveMergeBase 補抓策略調整、deepen PR HEAD 改用 head SHA、留言閉包改名、push-token input 移除等)。
  • 🚫 誤報:與 .gitea/ai-review/exclusions.json 既有裁決等價,不重複新增排除條目。

處理完成,依 code-review-resolve 流程關閉本議題。

<!-- code-review-resolve --> ## 🧩 code-review-resolve 處理進度 本議題為 AI Code Review 建問題模式的追蹤議題。以 `--issue all` 併同 `.gitea/ai-review/findings/` 逐條處理後結果如下(對照目前程式碼與 `exclusions.json`): | # | 等級 | 審查員 | 位置 | 處理結果 | 說明 | | --- | --- | --- | --- | --- | --- | | 1 | 🔴 嚴重 | Assassin | `action.yml` 第 49–59 行 | ✅已解決 | 現行 action.yml 已無 push-token input(僅 token/model/create-issue),PAT 停留執行期的疑慮所依附程式碼已移除。 | | 2 | 🟠 警告 | Leo | `src/index.js` 第 119–139 行 | ⏭️待人工 | 以語意階段常數取代硬編步驟編號屬可維護性重構取捨,skill 規範不得硬改,標記待人工。 | | 3 | 🟠 警告 | Maya | `src/index.js` 第 260–276 行 | 🚫誤報 | 補測試指控(含建問題模式主流程空檔案案例)已列入 exclusions 裁決為誤報,不重複新增。 | | 4 | 🟠 警告 | Rogue | `src/lib/gitrepo.js` 第 134–135 行 | ✅已解決 | 現行程式碼已把 deepen base/deepen PR HEAD 放前,--unshallow 僅在仍失敗且為淺層 repo 時當最後手段。 | | 5 | 🟠 警告 | Mage | `src/lib/gitrepo.js` 第 143–147 行 | ✅已解決 | 現行程式碼已改用 rev-parse HEAD 取得 headSha,以 fetch --deepen=1000 origin <headSha> 補抓 PR head。 | | 6 | 🔵 建議 | Bard | `readme.md` 第 41–50 行 | 🚫誤報 | 步驟 2 延後執行造成流程圖編號逆行的閱讀負擔已列入 exclusions 裁決為誤報。 | | 7 | 🔵 建議 | Bard | `src/index.js` 第 194–207 行 | ✅已解決 | postComment 已改名為 queueOrPostComment,名稱已對齊留言路由(發布/暫存)語義。 | **小計**:✅ 已解決 4 條、🚫 誤報(已列入 exclusions)2 條、⏭️ 待人工處理 1 條。 > ⏭️ 待人工處理項目屬設計/效能/慣例取捨(skill 規範不得硬改),已將「只來自議題」的待人工問題(依主題去重)寫回 `.gitea/ai-review/findings/2026-07-20-18:31:07.json` 追蹤,關閉本議題不會遺失待辦。 - ✅ 已解決:問題於目前程式碼已修復(如 `resolveMergeBase` 補抓策略調整、`deepen PR HEAD` 改用 head SHA、留言閉包改名、`push-token` input 移除等)。 - 🚫 誤報:與 `.gitea/ai-review/exclusions.json` 既有裁決等價,不重複新增排除條目。 處理完成,依 code-review-resolve 流程關閉本議題。
Sign in to join this conversation.
No labels
2 Participants
Notifications
Due Date
No due date set.
Reference: node-actions/ai-code-review#11