Compare commits
6
Commits
v0.0.1
...
ccbe615c2a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccbe615c2a | ||
|
|
c4c23d4531 | ||
|
|
3fe643c003 | ||
|
|
3fea48472f | ||
|
|
10b1612fe6 | ||
|
|
703f1d753d |
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"generatedAt": "2026/07/17 19:03:13",
|
||||
"commitSha": "c4c23d45314bb260d7ec350db4f968021076ee17",
|
||||
"prNumber": 4,
|
||||
"tool": {
|
||||
"name": "codex",
|
||||
"version": "codex-cli 0.144.5",
|
||||
"model": "(工具預設)"
|
||||
},
|
||||
"findings": [],
|
||||
"excluded": []
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
# ============================================================================
|
||||
# 用途:Gitea Actions CI workflow —— 當 PR 開啟或同步(推新 commit)到 master/develop 時,
|
||||
# 自動 checkout 完整 git 歷史、計算下一個語意化版本號(develop 走 beta 預發布),
|
||||
# 接著建立 Gitea Release(副作用:建立 git tag 與 Release),正式版並會清理舊 Release。
|
||||
# 更新時間:2026/07/17 16:49:21
|
||||
# ============================================================================
|
||||
|
||||
# workflow 名稱:顯示於 Gitea Actions 執行清單,方便辨識這條 CI pipeline
|
||||
name: CI
|
||||
|
||||
# 觸發條件設定區塊
|
||||
on:
|
||||
# 以 pull request 事件觸發(非 push),確保版本計算與發布綁定 PR 流程
|
||||
pull_request:
|
||||
# 只有目標分支(base branch)為下列分支的 PR 才會觸發
|
||||
branches:
|
||||
# 正式分支:PR 目標為 master 時發布正式版 Release
|
||||
- master
|
||||
# 開發分支:PR 目標為 develop 時發布 beta 預發布(prerelease)
|
||||
- develop
|
||||
# 只在 PR 開啟(opened)與來源分支推新 commit 同步(synchronize)時觸發,
|
||||
# 避免 reopened/labeled 等其他 PR 事件重複跑 CI
|
||||
types: [opened, synchronize]
|
||||
|
||||
# workflow 層級環境變數:所有 job/step 皆可透過 env.* 取用
|
||||
env:
|
||||
# 目前 repo 名稱,取自 Gitea 事件 payload,供後續步驟組合 Release 名稱等用途
|
||||
REPOSITORY_NAME: ${{ gitea.event.repository.name }}
|
||||
# 是否為 beta(預發布)流程:PR 目標分支為 develop 時為 'true',否則為 'false';
|
||||
# 注意此值為字串型別,後續 if 條件需以字串比較(== 'false')
|
||||
IS_BETA: ${{ gitea.base_ref == 'develop' }}
|
||||
|
||||
# job 定義區塊
|
||||
jobs:
|
||||
# 唯一的 job:建置與發布
|
||||
build:
|
||||
# job 顯示名稱:於 Gitea Actions 介面顯示為 BUILD
|
||||
name: BUILD
|
||||
# 指定 runner 標籤:由標籤為 ubuntu 的 Gitea Actions runner 執行
|
||||
runs-on: ubuntu
|
||||
# 依序執行的步驟
|
||||
steps:
|
||||
# 步驟 1:checkout 原始碼與完整 git 歷史(含所有 tag),
|
||||
# 版本計算需要既有 tag 才能推算下一個版本號
|
||||
- name: 取得存取庫資訊 (含 Tag)
|
||||
# 使用官方 checkout action;vars.ACTION_CHECKOUT_VERSION 為
|
||||
# Gitea 組織/repo 層級變數(Actions variables)提供的 action 版本,集中管理升版
|
||||
uses: actions/checkout@${{ vars.ACTION_CHECKOUT_VERSION }}
|
||||
with:
|
||||
# fetch-depth: 0 代表抓取完整歷史(非 shallow clone),確保 tag 與 commit 歷史齊全
|
||||
fetch-depth: 0
|
||||
# 步驟 2:依既有 tag 計算下一個語意化版本號
|
||||
- name: 計算下一個版本號
|
||||
# 使用自建的 calculate-next-version action(gitea.jsc.idv.tw 私有 Gitea 上的 docker action);
|
||||
# vars.ACTION_CALCULATE_NEXT_VERSION 同為 Gitea 組織/repo 變數提供的版本
|
||||
uses: https://gitea.jsc.idv.tw/docker-actions/calculate-next-version@${{ vars.ACTION_CALCULATE_NEXT_VERSION }}
|
||||
# step id:後續步驟以 steps.calculate-next-version.outputs.value 取得計算結果
|
||||
id: calculate-next-version
|
||||
with:
|
||||
# 傳入是否為 beta:true 時產生預發布版號(例如帶 -beta 後綴),false 時產生正式版號
|
||||
is_beta: ${{ env.IS_BETA }}
|
||||
# 步驟 3:建立 Gitea Release(副作用:建立對應 git tag 與 Release 頁面)
|
||||
# 需人工確認:此步驟在 PR opened/synchronize 就會發布 Release 並打 tag,
|
||||
# 亦即 PR 尚未合併前每次推 commit 都會產生 Release;請確認這是預期行為
|
||||
# (通常發布會放在 push 到 master/develop 或 PR merged 之後)。
|
||||
- name: 發布成品
|
||||
# 使用第三方 akkuman/gitea-release-action 建立 Release;
|
||||
# vars.ACTION_GITEA_RELEASE_VERSION 為 Gitea 組織/repo 變數提供的 action 版本
|
||||
# 需人工確認:此 action 通常需要 GITEA_TOKEN/token 才能建立 Release,
|
||||
# 本設定未見明確傳入 token,請確認 runner 預設 token 權限是否足夠。
|
||||
uses: akkuman/gitea-release-action@${{ vars.ACTION_GITEA_RELEASE_VERSION }}
|
||||
# step 層級環境變數
|
||||
env:
|
||||
# 將上一步計算出的版本號存為 VERSION,供本步驟的 with 參數引用
|
||||
VERSION: ${{ steps.calculate-next-version.outputs.value }}
|
||||
with:
|
||||
# Release 顯示名稱:{repo 名稱} v{版本號}
|
||||
name: "${{ gitea.event.repository.name }} v${{ env.VERSION }}"
|
||||
# 要建立的 git tag 名稱:v{版本號}
|
||||
tag_name: "v${{ env.VERSION }}"
|
||||
# tag 指向的 commit:gitea.sha 為觸發此 workflow 的 commit
|
||||
# 需人工確認:pull_request 事件的 sha 通常是 PR 的 merge commit(暫時性 ref),
|
||||
# 對其打 tag 可能指向未實際合入分支的 commit,請確認 tag 目標是否符合預期。
|
||||
target_commitish: "${{ gitea.sha }}"
|
||||
# 是否標記為預發布:develop 目標的 PR 為 true(beta),master 為 false(正式版)
|
||||
prerelease: ${{ env.IS_BETA }}
|
||||
# 步驟 4:清理舊 Release,避免 Release 清單無限增長
|
||||
- name: 清理舊成品
|
||||
# 使用自建的 clean-old-release action;
|
||||
# vars.ACTION_CLEAN_OLD_RELEASE 為 Gitea 組織/repo 變數提供的 action 版本
|
||||
# 需人工確認:其他兩個自建 action 的變數名皆以 _VERSION 結尾,
|
||||
# 此變數名為 ACTION_CLEAN_OLD_RELEASE(無 _VERSION 後綴),請確認命名是否刻意如此。
|
||||
uses: https://gitea.jsc.idv.tw/docker-actions/clean-old-release@${{ vars.ACTION_CLEAN_OLD_RELEASE }}
|
||||
# 僅在非 beta(正式版,PR 目標為 master)時執行清理;
|
||||
# 因 env.IS_BETA 為字串,故以 == 'false' 比較
|
||||
if: ${{ env.IS_BETA == 'false' }}
|
||||
@@ -0,0 +1,92 @@
|
||||
# ============================================================================
|
||||
# 用途:在 pull request 針對 develop 分支開啟或同步時,分別以 Antigravity、Codex、Claude 環境執行本機 AI Code Review action。
|
||||
# 更新時間:2026/07/17 18:49:58
|
||||
# ============================================================================
|
||||
# Workflow 顯示名稱。
|
||||
name: CI
|
||||
|
||||
# Workflow 觸發條件區塊。
|
||||
on:
|
||||
# 以 pull request 事件觸發。
|
||||
pull_request:
|
||||
# 限定 pull request 目標分支。
|
||||
branches:
|
||||
# 僅在目標分支為 develop 時執行。
|
||||
- develop
|
||||
# 限定 pull request 開啟與同步更新時執行。
|
||||
types: [opened, synchronize]
|
||||
|
||||
# Job 定義區塊。
|
||||
jobs:
|
||||
# Antigravity 工具環境測試 job。
|
||||
test-antigravity:
|
||||
# Job 在 workflow UI 顯示的名稱。
|
||||
name: TEST (Antigravity)
|
||||
# 指定執行 runner 標籤;需人工確認本 Gitea runner 是否使用 ubuntu 標籤。
|
||||
runs-on: ubuntu
|
||||
# Job 執行步驟。
|
||||
steps:
|
||||
# 取得存取庫內容供後續 action 使用。
|
||||
- name: 取得存取庫資訊
|
||||
# 使用呼叫端 vars 指定的 checkout action 版本。
|
||||
uses: actions/checkout@${{ vars.ACTION_CHECKOUT_VERSION }}
|
||||
# 安裝 Antigravity 工具環境。
|
||||
- name: 安裝工具
|
||||
# 使用 Gitea composite action 安裝 Antigravity,版本由 vars 指定。
|
||||
uses: https://gitea.jsc.idv.tw/composite-actions/setup-antigravity@${{ vars.ACTION_SETUP_ANTIGRAVITY_VERSION }}
|
||||
# 執行目前存取庫的 AI Code Review action。
|
||||
- name: 程式碼審查
|
||||
# 以目前存取庫根目錄的 action.yml 作為 action 來源。
|
||||
uses: ./
|
||||
# 傳入 action inputs。
|
||||
with:
|
||||
# Gitea / GitHub token,用於 PR 留言與 findings 寫回。
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Codex 工具環境測試 job。
|
||||
test-codex:
|
||||
# Job 在 workflow UI 顯示的名稱。
|
||||
name: TEST (Codex)
|
||||
# 指定執行 runner 標籤;需人工確認本 Gitea runner 是否使用 ubuntu 標籤。
|
||||
runs-on: ubuntu
|
||||
# Job 執行步驟。
|
||||
steps:
|
||||
# 取得存取庫內容供後續 action 使用。
|
||||
- name: 取得存取庫資訊
|
||||
# 使用呼叫端 vars 指定的 checkout action 版本。
|
||||
uses: actions/checkout@${{ vars.ACTION_CHECKOUT_VERSION }}
|
||||
# 安裝 Codex 工具環境。
|
||||
- name: 安裝工具
|
||||
# 使用 Gitea composite action 安裝 Codex,版本由 vars 指定。
|
||||
uses: https://gitea.jsc.idv.tw/composite-actions/setup-codex@${{ vars.ACTION_SETUP_CODEX_VERSION }}
|
||||
# 執行目前存取庫的 AI Code Review action。
|
||||
- name: 程式碼審查
|
||||
# 以目前存取庫根目錄的 action.yml 作為 action 來源。
|
||||
uses: ./
|
||||
# 傳入 action inputs。
|
||||
with:
|
||||
# Gitea / GitHub token,用於 PR 留言與 findings 寫回。
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Claude 工具環境測試 job。
|
||||
test-claude:
|
||||
# Job 在 workflow UI 顯示的名稱。
|
||||
name: TEST (Claude)
|
||||
# 指定執行 runner 標籤;需人工確認本 Gitea runner 是否使用 ubuntu 標籤。
|
||||
runs-on: ubuntu
|
||||
# Job 執行步驟。
|
||||
steps:
|
||||
# 取得存取庫內容供後續 action 使用。
|
||||
- name: 取得存取庫資訊
|
||||
# 使用呼叫端 vars 指定的 checkout action 版本。
|
||||
uses: actions/checkout@${{ vars.ACTION_CHECKOUT_VERSION }}
|
||||
# 安裝 Claude 工具環境。
|
||||
- name: 安裝工具
|
||||
# 使用 Gitea composite action 安裝 Claude,版本由 vars 指定。
|
||||
uses: https://gitea.jsc.idv.tw/composite-actions/setup-claude@${{ vars.ACTION_SETUP_CLAUDE_VERSION }}
|
||||
# 執行目前存取庫的 AI Code Review action。
|
||||
- name: 程式碼審查
|
||||
# 以目前存取庫根目錄的 action.yml 作為 action 來源。
|
||||
uses: ./
|
||||
# 傳入 action inputs。
|
||||
with:
|
||||
# Gitea / GitHub token,用於 PR 留言與 findings 寫回。
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,41 @@
|
||||
# Workflow 文件草稿
|
||||
|
||||
更新時間:2026/07/17 18:49:58
|
||||
|
||||
## Workflow 總覽
|
||||
|
||||
| 名稱 | 檔案位置 | 用途 | 觸發條件 |
|
||||
| --- | --- | --- | --- |
|
||||
| CI | `.gitea/workflows/ci.yaml` | 在 PR 事件中分別以 Antigravity、Codex、Claude 工具環境執行本存取庫的 AI Code Review action,驗證 action 可在不同 AI 工具環境下運作。 | `pull_request` 目標分支為 `develop`,事件類型為 `opened` 或 `synchronize`。 |
|
||||
|
||||
## CI
|
||||
|
||||
- Workflow 名稱:`CI`
|
||||
- 檔案位置:`.gitea/workflows/ci.yaml`
|
||||
- 用途:針對送往 `develop` 的 pull request 執行三組測試 job,分別安裝 Antigravity、Codex、Claude 環境後呼叫 `uses: ./` 執行目前 action。
|
||||
- 觸發條件:`pull_request.branches` 為 `develop`;`pull_request.types` 為 `opened`、`synchronize`。
|
||||
|
||||
## Job
|
||||
|
||||
| Job ID | 顯示名稱 | Runner | 主要流程 |
|
||||
| --- | --- | --- | --- |
|
||||
| `test-antigravity` | `TEST (Antigravity)` | `ubuntu` | checkout 存取庫、安裝 Antigravity、執行本地 action。 |
|
||||
| `test-codex` | `TEST (Codex)` | `ubuntu` | checkout 存取庫、安裝 Codex、執行本地 action。 |
|
||||
| `test-claude` | `TEST (Claude)` | `ubuntu` | checkout 存取庫、安裝 Claude、執行本地 action。 |
|
||||
|
||||
## 主要輸入 / 環境參數
|
||||
|
||||
| 名稱 | 來源 | 使用位置 | 說明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `vars.ACTION_CHECKOUT_VERSION` | Gitea / GitHub repository 或 organization vars | `actions/checkout@...` | 指定 checkout action 版本。 |
|
||||
| `vars.ACTION_SETUP_ANTIGRAVITY_VERSION` | Gitea / GitHub vars | `setup-antigravity@...` | 指定 Antigravity 安裝 action 版本。 |
|
||||
| `vars.ACTION_SETUP_CODEX_VERSION` | Gitea / GitHub vars | `setup-codex@...` | 指定 Codex 安裝 action 版本。 |
|
||||
| `vars.ACTION_SETUP_CLAUDE_VERSION` | Gitea / GitHub vars | `setup-claude@...` | 指定 Claude 安裝 action 版本。 |
|
||||
| `secrets.GITHUB_TOKEN` | Gitea / GitHub secrets | 本地 action input `token` | 提供 action 呼叫 Gitea API 留言與寫回 findings 所需 token。 |
|
||||
|
||||
## 注意事項
|
||||
|
||||
- `.gitea/workflows/readme.md` 目前不存在;本檔為新增 workflow README 的草稿。
|
||||
- `runs-on: ubuntu` 是否符合實際 Gitea runner 標籤需人工確認。
|
||||
- `vars.*` 與 `secrets.GITHUB_TOKEN` 必須由呼叫端環境提供,否則 checkout、工具安裝或程式碼審查步驟可能失敗。
|
||||
- 三個 job 均以 `uses: ./` 呼叫目前存取庫根目錄的 `action.yml`;因此 `action.yml` 的 `runs.main` 需保持可被 runner 直接執行。
|
||||
+25
-25
@@ -1,53 +1,53 @@
|
||||
# =====================================================
|
||||
# 用途 : AI 多角色 code review:攻擊方找問題、防守方裁決誤報,結果留言到 PR 並保存 findings
|
||||
# 更新時間: 2026/07/17 16:49:21
|
||||
# =====================================================
|
||||
# ============================================================================
|
||||
# 用途:定義 AI Code Review Node action 的名稱、輸入參數與 Node.js 24 進入點,供 Gitea / GitHub workflow 以 uses 引用。
|
||||
# 更新時間:2026/07/17 18:49:58
|
||||
# ============================================================================
|
||||
# Gitea / GitHub node action 的 manifest(action.yml):
|
||||
# 定義本 action 的名稱、說明、輸入參數(inputs)與執行方式(runs),
|
||||
# 供呼叫端 workflow 以 `uses:` 引用;runner 讀取此檔後以 node24 執行 src/index.js。
|
||||
|
||||
# action 顯示名稱:呼叫端 workflow log 與 marketplace 列表上看到的名稱
|
||||
# action 顯示名稱:呼叫端 workflow log 與 marketplace 列表上看到的名稱。
|
||||
name: 'AI Code Review'
|
||||
# action 用途說明:多角色 AI code review 流程(攻擊方找問題、防守方裁決誤報),
|
||||
# 審查結果會留言到 PR 並保存 findings(.gitea/ai-review/findings/)
|
||||
# 審查結果會留言到 PR 並保存 findings(.gitea/ai-review/findings/)。
|
||||
description: 'AI 多角色 code review:攻擊方找問題、防守方裁決誤報,結果留言到 PR 並保存 findings'
|
||||
# action 作者資訊(僅供辨識,不影響執行)
|
||||
# action 作者資訊(僅供辨識,不影響執行)。
|
||||
author: 'Jeffery'
|
||||
# 輸入參數區塊:呼叫端 workflow 以 `with:` 傳入,
|
||||
# runner 會自動注入為 INPUT_* 環境變數(例如 INPUT_TOKEN、INPUT_MODEL、INPUT_CREATE-ISSUE)供主程式讀取
|
||||
# runner 會自動注入為 INPUT_* 環境變數(例如 INPUT_TOKEN、INPUT_MODEL、INPUT_CREATE-ISSUE)供主程式讀取。
|
||||
inputs:
|
||||
# Gitea API token:用於對 PR 留言審查結果、以及 push 審查結果檔回 repo
|
||||
# Gitea API token:用於對 PR 留言審查結果、以及 push 審查結果檔回 repo。
|
||||
token:
|
||||
# 參數用途說明:secrets/vars context 在 action 內不可用,
|
||||
# 故由呼叫端 workflow 以 secrets.GITHUB_TOKEN 傳入
|
||||
# 故由呼叫端 workflow 以 secrets.GITHUB_TOKEN 傳入。
|
||||
description: 'Gitea API token(PR 留言與 push findings 用;呼叫端以 secrets.GITHUB_TOKEN 傳入)'
|
||||
# 必填:缺少 token 無法呼叫 Gitea API,action 無法運作
|
||||
# 必填:缺少 token 無法呼叫 Gitea API,action 無法運作。
|
||||
required: true
|
||||
# 指定 AI 工具使用的模型名稱
|
||||
# 指定 AI 工具使用的模型名稱。
|
||||
model:
|
||||
# 參數用途說明:留空表示使用各 AI 工具自身的預設模型
|
||||
# 參數用途說明:留空表示使用各 AI 工具自身的預設模型。
|
||||
description: '指定 AI 工具使用的模型(空值=各工具預設)'
|
||||
# 選填:未指定時採用預設值
|
||||
# 選填:未指定時採用預設值。
|
||||
required: false
|
||||
# 預設為空字串,代表不覆寫各工具的預設模型
|
||||
# 預設為空字串,代表不覆寫各工具的預設模型。
|
||||
default: ''
|
||||
# 建問題模式開關:是否把審查保留的問題另建 issue 追蹤
|
||||
# 建問題模式開關:是否把審查保留的問題另建 issue 追蹤。
|
||||
create-issue:
|
||||
# 參數用途說明:字串 'true' 時建立 issue(標題=PR 標題、描述=PR 描述、AI 挑標籤)
|
||||
# 參數用途說明:字串 'true' 時建立 issue(標題=PR 標題、描述=PR 描述、AI 挑標籤),
|
||||
# 並逐條留言問題明細,findings 檔不進版控、收尾只 commit exclusions.json;
|
||||
# 預設 'false' 走原流程(findings 檔與 exclusions.json 一併 commit 回 PR 來源分支)
|
||||
# 預設 'false' 走原流程(findings 檔與 exclusions.json 一併 commit 回 PR 來源分支)。
|
||||
description: '是否將問題建到存取庫的問題追蹤(true 時建立 issue 逐條留言問題明細,最後只 commit exclusions.json;預設 false 走原流程)'
|
||||
# 選填:未指定時採用預設值
|
||||
# 選填:未指定時採用預設值。
|
||||
required: false
|
||||
# 預設為字串 'false',代表不啟用建問題模式(主程式只認字串 'true' 才啟用)
|
||||
# 預設為字串 'false',代表不啟用建問題模式(主程式只認字串 'true' 才啟用)。
|
||||
default: 'false'
|
||||
# 執行方式區塊:宣告本 action 為 node action 及其進入點
|
||||
# 執行方式區塊:宣告本 action 為 node action 及其進入點。
|
||||
runs:
|
||||
# 以 Node.js 24 runtime 直接在 runner 上執行(非 Docker 容器、非 composite)
|
||||
# 以 Node.js 24 runtime 直接在 runner 上執行(非 Docker 容器、非 composite)。
|
||||
using: 'node24'
|
||||
# 主程式進入點:直接指向 src/index.js(entry point)
|
||||
# 主程式進入點:直接指向 src/index.js(entry point)。
|
||||
# 主程式為零外部相依(package.json 無 dependencies,src 僅 require Node 內建模組與本地 lib),
|
||||
# runner 不會自動 npm install,零相依時依 node action 慣例 main 直接指向 src/index.js 即正確;
|
||||
# 日後若新增外部相依,需改以 @vercel/ncc 打包(package.json 已備有 build script)
|
||||
# 並將 main 改指 dist/index.js、把 dist/ commit 進 repo
|
||||
# 日後若新增外部相依,需改以 @vercel/ncc 打包(package.json 已備有 build script),
|
||||
# 並將 main 改指 dist/index.js、把 dist/ commit 進 repo。
|
||||
main: 'src/index.js'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI Code Review
|
||||
|
||||
> 更新時間:2026/07/17 16:49:21
|
||||
> 更新時間:2026/07/17 18:49:58
|
||||
|
||||
AI 多角色 code review 的 Gitea **node action**(`node24`、零外部相依):以攻擊方六角色(🔮 Mage 邏輯、🗡️ Assassin 安全、⚡ Rogue 效率、🎼 Bard 風格、🧪 Maya 測試、🧰 Leo 可維護性)並行找問題、防守方(🛡️ Paladin)裁決誤報,結果留言到 PR、保存 findings,並以 bot commit 標記審查結果(`[success]`/`[failure]`)供下次觸發快速回報。
|
||||
|
||||
@@ -56,19 +56,19 @@ flowchart TD
|
||||
|
||||
| 專案名稱 | 專案描述 |
|
||||
| --- | --- |
|
||||
| [ai-code-review](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/) | Gitea node action:提供台北時區日誌工具、runner 上下文載入、git diff/commit 操作、Gitea REST API 客戶端(留言/review/issue/標籤)、AI CLI 工具偵測與 sub agent 執行、角色提示載入、固定留言模板,以及多角色審查編排(攻擊方找問題、防守方裁決、findings 保存、誤判回寫、建問題模式) |
|
||||
| [ai-code-review](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/) | Gitea node action:提供台北時區日誌工具、runner 上下文載入、git diff/commit 操作、Gitea REST API 客戶端(留言/review/issue/標籤)、AI CLI 工具偵測與 sub agent 執行、角色提示載入、固定留言模板,以及多角色審查編排(攻擊方找問題、防守方裁決、findings 保存、誤判回寫、建問題模式) |
|
||||
|
||||
### 參考專案表
|
||||
|
||||
| 專案名稱 | 參考專案列表 |
|
||||
| --- | --- |
|
||||
| [ai-code-review](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/) | 無 |
|
||||
| [ai-code-review](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/) | 無 |
|
||||
|
||||
### NuGet 套件表
|
||||
|
||||
| 專案名稱 | NuGet 套件列表 |
|
||||
| --- | --- |
|
||||
| [ai-code-review](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/) | 無 |
|
||||
| [ai-code-review](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/) | 無 |
|
||||
|
||||
## 功能列表
|
||||
|
||||
@@ -76,56 +76,56 @@ flowchart TD
|
||||
|
||||
| 功能名稱 | 功能描述 |
|
||||
| --- | --- |
|
||||
| [log.taipeiNow](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/log.js#L20) | [取得台北時區 yyyy/MM/dd HH:mm:ss 時間字串](#logtaipeinow) |
|
||||
| [log.taipeiFileStamp](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/log.js#L41) | [取得檔名用時間戳 yyyy-MM-dd-HH:mm:ss](#logtaipeifilestamp) |
|
||||
| [log.taipeiFromIso](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/log.js#L60) | [將 ISO 時間字串轉為台北時區顯示字串](#logtaipeifromiso) |
|
||||
| [log.log](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/log.js#L83) | [以統一格式輸出一行日誌](#loglog) |
|
||||
| [context.loadContext](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/context.js#L64) | [彙整 runner 環境變數與事件 payload 為執行上下文](#contextloadcontext) |
|
||||
| [gitrepo.latestCommitSubject](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitrepo.js#L60) | [取得最新 commit 的訊息標題](#gitrepolatestcommitsubject) |
|
||||
| [gitrepo.resolveMergeBase](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitrepo.js#L81) | [解析 base 分支與 HEAD 的 merge-base](#gitreporesolvemergebase) |
|
||||
| [gitrepo.changedFiles](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitrepo.js#L104) | [列出 base 與 HEAD 之間有變更的檔案](#gitrepochangedfiles) |
|
||||
| [gitrepo.fileDiff](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitrepo.js#L125) | [取得單一檔案的 git diff 內容](#gitrepofilediff) |
|
||||
| [gitrepo.fileLastUpdatedIso](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitrepo.js#L143) | [取得檔案最後一次 commit 的 ISO 時間](#gitrepofilelastupdatediso) |
|
||||
| [gitrepo.commitAndPushFindings](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitrepo.js#L181) | [以 bot 身分 commit 結果檔並 push 回 PR 來源分支](#gitrepocommitandpushfindings) |
|
||||
| [gitea.whoAmI](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L87) | [取得 token 對應的使用者(bot 身分)](#giteawhoami) |
|
||||
| [gitea.createCommentOnIssue](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L106) | [對指定編號 issue/PR 新增一般留言](#giteacreatecommentonissue) |
|
||||
| [gitea.createIssueComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L124) | [對本次 PR 新增一般留言](#giteacreateissuecomment) |
|
||||
| [gitea.listLabels](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L141) | [列出存取庫可用標籤](#gitealistlabels) |
|
||||
| [gitea.createIssue](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L164) | [在存取庫建立 issue(可掛標籤)](#giteacreateissue) |
|
||||
| [gitea.listIssueComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L184) | [列出 PR 全部一般留言(自動分頁)](#gitealistissuecomments) |
|
||||
| [gitea.editIssueComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L202) | [編輯既有一般留言](#giteaeditissuecomment) |
|
||||
| [gitea.createReview](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L223) | [建立 code review 並掛行內留言](#giteacreatereview) |
|
||||
| [gitea.listReviews](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L243) | [列出 PR 全部 review(自動分頁)](#gitealistreviews) |
|
||||
| [gitea.listReviewComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L264) | [列出某 review 的全部行內留言](#gitealistreviewcomments) |
|
||||
| [gitea.tryResolveReviewComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/gitea.js#L287) | [盡力將行內留言標記為已解決](#giteatryresolvereviewcomment) |
|
||||
| [agents.detectTool](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/agents.js#L53) | [依優先序偵測可用的 AI CLI 工具](#agentsdetecttool) |
|
||||
| [agents.runAgent](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/agents.js#L98) | [非互動執行一次 sub agent 並取回回覆](#agentsrunagent) |
|
||||
| [agents.extractJson](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/agents.js#L144) | [從 agent 回覆萃取 JSON(容忍雜訊)](#agentsextractjson) |
|
||||
| [roles.loadRoles](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/roles.js#L32) | [載入角色提示檔並解析 frontmatter](#rolesloadroles) |
|
||||
| [roles.attackersOf](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/roles.js#L71) | [過濾出攻擊方角色](#rolesattackersof) |
|
||||
| [roles.defendersOf](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/roles.js#L90) | [過濾出防守方角色](#rolesdefendersof) |
|
||||
| [templates.toolComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L88) | [產生步驟 2 審查工具留言](#templatestoolcomment) |
|
||||
| [templates.diffComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L132) | [產生步驟 3 變更摘要留言](#templatesdiffcomment) |
|
||||
| [templates.rolesComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L173) | [產生步驟 4/6 角色登場留言](#templatesrolescomment) |
|
||||
| [templates.severeCommentBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L215) | [產生步驟 9 單條嚴重問題留言](#templatesseverecommentbody) |
|
||||
| [templates.severeReviewBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L247) | [產生步驟 9 嚴重問題 review 總覽](#templatesseverereviewbody) |
|
||||
| [templates.othersComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L277) | [產生步驟 10 警告+建議彙整表格留言](#templatesotherscomment) |
|
||||
| [templates.issueBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L309) | [產生建問題模式的 issue 本文](#templatesissuebody) |
|
||||
| [templates.issueFindingComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L341) | [產生建問題模式單條問題的 issue 留言](#templatesissuefindingcomment) |
|
||||
| [templates.nothingToReviewComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/templates.js#L379) | [產生無可審查變更留言](#templatesnothingtoreviewcomment) |
|
||||
| [review.loadReviewIgnore](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L29) | [讀取 .reviewignore 忽略前綴清單](#reviewloadreviewignore) |
|
||||
| [review.isIgnored](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L53) | [判斷檔案是否忽略不送審](#reviewisignored) |
|
||||
| [review.collectDiffRows](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L77) | [整理送審 diff 資料列(含長度上限)](#reviewcollectdiffrows) |
|
||||
| [review.fillPurposes](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L127) | [以 AI 補齊每個檔案的一行用途描述](#reviewfillpurposes) |
|
||||
| [review.runAttackers](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L276) | [攻擊方 sub agent 並行找問題並合併列表](#reviewrunattackers) |
|
||||
| [review.runDefenders](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L448) | [防守方 sub agent 裁決保留或排除](#reviewrundefenders) |
|
||||
| [review.sortFindings](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L572) | [依嚴重度→檔案→行號排序 findings](#reviewsortfindings) |
|
||||
| [review.appendExclusions](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L521) | [誤判問題附加到 exclusions.json](#reviewappendexclusions) |
|
||||
| [review.sortFindingsForIssue](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L596) | [依檔案→嚴重度→行號排序(建問題模式)](#reviewsortfindingsforissue) |
|
||||
| [review.selectLabels](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L627) | [以 AI 從可用標籤挑選 issue 標籤](#reviewselectlabels) |
|
||||
| [review.createIssueWithFindings](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L694) | [建 issue 並逐條留言問題明細](#reviewcreateissuewithfindings) |
|
||||
| [review.resolveOldComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L778) | [將 PR 舊留言標記為解決/過時](#reviewresolveoldcomments) |
|
||||
| [review.postSevereComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/master/src/lib/review.js#L855) | [嚴重問題逐條掛行留言(含降級)](#reviewpostseverecomments) |
|
||||
| [log.taipeiNow](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/log.js#L20) | [取得台北時區 yyyy/MM/dd HH:mm:ss 時間字串](#logtaipeinow) |
|
||||
| [log.taipeiFileStamp](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/log.js#L41) | [取得檔名用時間戳 yyyy-MM-dd-HH:mm:ss](#logtaipeifilestamp) |
|
||||
| [log.taipeiFromIso](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/log.js#L60) | [將 ISO 時間字串轉為台北時區顯示字串](#logtaipeifromiso) |
|
||||
| [log.log](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/log.js#L83) | [以統一格式輸出一行日誌](#loglog) |
|
||||
| [context.loadContext](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/context.js#L64) | [彙整 runner 環境變數與事件 payload 為執行上下文](#contextloadcontext) |
|
||||
| [gitrepo.latestCommitSubject](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitrepo.js#L79) | [取得最新 commit 的訊息標題](#gitrepolatestcommitsubject) |
|
||||
| [gitrepo.resolveMergeBase](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitrepo.js#L100) | [解析 base 分支與 HEAD 的 merge-base](#gitreporesolvemergebase) |
|
||||
| [gitrepo.changedFiles](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitrepo.js#L136) | [列出 base 與 HEAD 之間有變更的檔案](#gitrepochangedfiles) |
|
||||
| [gitrepo.fileDiff](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitrepo.js#L157) | [取得單一檔案的 git diff 內容](#gitrepofilediff) |
|
||||
| [gitrepo.fileLastUpdatedIso](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitrepo.js#L175) | [取得檔案最後一次 commit 的 ISO 時間](#gitrepofilelastupdatediso) |
|
||||
| [gitrepo.commitAndPushFindings](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitrepo.js#L213) | [以 bot 身分 commit 結果檔並 push 回 PR 來源分支](#gitrepocommitandpushfindings) |
|
||||
| [gitea.whoAmI](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L87) | [取得 token 對應的使用者(bot 身分)](#giteawhoami) |
|
||||
| [gitea.createCommentOnIssue](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L106) | [對指定編號 issue/PR 新增一般留言](#giteacreatecommentonissue) |
|
||||
| [gitea.createIssueComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L124) | [對本次 PR 新增一般留言](#giteacreateissuecomment) |
|
||||
| [gitea.listLabels](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L141) | [列出存取庫可用標籤](#gitealistlabels) |
|
||||
| [gitea.createIssue](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L164) | [在存取庫建立 issue(可掛標籤)](#giteacreateissue) |
|
||||
| [gitea.listIssueComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L184) | [列出 PR 全部一般留言(自動分頁)](#gitealistissuecomments) |
|
||||
| [gitea.editIssueComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L202) | [編輯既有一般留言](#giteaeditissuecomment) |
|
||||
| [gitea.createReview](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L223) | [建立 code review 並掛行內留言](#giteacreatereview) |
|
||||
| [gitea.listReviews](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L243) | [列出 PR 全部 review(自動分頁)](#gitealistreviews) |
|
||||
| [gitea.listReviewComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L264) | [列出某 review 的全部行內留言](#gitealistreviewcomments) |
|
||||
| [gitea.tryResolveReviewComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/gitea.js#L287) | [盡力將行內留言標記為已解決](#giteatryresolvereviewcomment) |
|
||||
| [agents.detectTool](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/agents.js#L53) | [依優先序偵測可用的 AI CLI 工具](#agentsdetecttool) |
|
||||
| [agents.runAgent](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/agents.js#L98) | [非互動執行一次 sub agent 並取回回覆](#agentsrunagent) |
|
||||
| [agents.extractJson](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/agents.js#L144) | [從 agent 回覆萃取 JSON(容忍雜訊)](#agentsextractjson) |
|
||||
| [roles.loadRoles](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/roles.js#L32) | [載入角色提示檔並解析 frontmatter](#rolesloadroles) |
|
||||
| [roles.attackersOf](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/roles.js#L71) | [過濾出攻擊方角色](#rolesattackersof) |
|
||||
| [roles.defendersOf](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/roles.js#L90) | [過濾出防守方角色](#rolesdefendersof) |
|
||||
| [templates.toolComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L88) | [產生步驟 2 審查工具留言](#templatestoolcomment) |
|
||||
| [templates.diffComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L132) | [產生步驟 3 變更摘要留言](#templatesdiffcomment) |
|
||||
| [templates.rolesComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L173) | [產生步驟 4/6 角色登場留言](#templatesrolescomment) |
|
||||
| [templates.severeCommentBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L215) | [產生步驟 9 單條嚴重問題留言](#templatesseverecommentbody) |
|
||||
| [templates.severeReviewBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L247) | [產生步驟 9 嚴重問題 review 總覽](#templatesseverereviewbody) |
|
||||
| [templates.othersComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L277) | [產生步驟 10 警告+建議彙整表格留言](#templatesotherscomment) |
|
||||
| [templates.issueBody](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L309) | [產生建問題模式的 issue 本文](#templatesissuebody) |
|
||||
| [templates.issueFindingComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L341) | [產生建問題模式單條問題的 issue 留言](#templatesissuefindingcomment) |
|
||||
| [templates.nothingToReviewComment](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/templates.js#L379) | [產生無可審查變更留言](#templatesnothingtoreviewcomment) |
|
||||
| [review.loadReviewIgnore](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L29) | [讀取 .reviewignore 忽略前綴清單](#reviewloadreviewignore) |
|
||||
| [review.isIgnored](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L53) | [判斷檔案是否忽略不送審](#reviewisignored) |
|
||||
| [review.collectDiffRows](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L77) | [整理送審 diff 資料列(含長度上限)](#reviewcollectdiffrows) |
|
||||
| [review.fillPurposes](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L127) | [以 AI 補齊每個檔案的一行用途描述](#reviewfillpurposes) |
|
||||
| [review.runAttackers](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L276) | [攻擊方 sub agent 並行找問題並合併列表](#reviewrunattackers) |
|
||||
| [review.runDefenders](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L448) | [防守方 sub agent 裁決保留或排除](#reviewrundefenders) |
|
||||
| [review.sortFindings](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L572) | [依嚴重度→檔案→行號排序 findings](#reviewsortfindings) |
|
||||
| [review.appendExclusions](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L521) | [誤判問題附加到 exclusions.json](#reviewappendexclusions) |
|
||||
| [review.sortFindingsForIssue](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L596) | [依檔案→嚴重度→行號排序(建問題模式)](#reviewsortfindingsforissue) |
|
||||
| [review.selectLabels](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L627) | [以 AI 從可用標籤挑選 issue 標籤](#reviewselectlabels) |
|
||||
| [review.createIssueWithFindings](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L694) | [建 issue 並逐條留言問題明細](#reviewcreateissuewithfindings) |
|
||||
| [review.resolveOldComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L778) | [將 PR 舊留言標記為解決/過時](#reviewresolveoldcomments) |
|
||||
| [review.postSevereComments](https://gitea.jsc.idv.tw/node-actions/ai-code-review/src/branch/develop/src/lib/review.js#L855) | [嚴重問題逐條掛行留言(含降級)](#reviewpostseverecomments) |
|
||||
|
||||
## 使用範例
|
||||
|
||||
|
||||
+11
-1
@@ -4,7 +4,7 @@
|
||||
console.log('================================================');
|
||||
console.log('Action : AI Code Review');
|
||||
console.log('用途 : AI 多角色 code review:攻擊方找問題、防守方裁決誤報,結果留言到 PR 並保存 findings');
|
||||
console.log('更新時間: 2026/07/17 16:49:21');
|
||||
console.log('更新時間: 2026/07/17 18:49:58');
|
||||
console.log('================================================');
|
||||
|
||||
const fs = require('fs');
|
||||
@@ -169,6 +169,16 @@ async function main() {
|
||||
|
||||
// 本回合發出的一般留言 id:步驟 8 標註過時時要跳過這些。
|
||||
const currentRunCommentIds = new Set();
|
||||
/**
|
||||
* 建立本回合 PR 一般留言並記錄留言 id,供後續舊留言處理排除。
|
||||
*
|
||||
* @param {string} body 要發布到 PR 的 Markdown 留言內容。
|
||||
* @returns {Promise<Object>} Gitea API 建立的留言物件;至少預期包含 `id`。
|
||||
* @remarks
|
||||
* 使用情境:只在 `main()` 內部使用,處理工具資訊、diff 摘要、角色登場與
|
||||
* 警告/建議彙整等一般留言。若 Gitea API 失敗,例外會往上拋出並由
|
||||
* 主流程頂層 catch 收斂。
|
||||
*/
|
||||
const postComment = async (body) => {
|
||||
const created = await gitea.createIssueComment(ctx, body);
|
||||
currentRunCommentIds.add(created.id);
|
||||
|
||||
+40
-8
@@ -44,6 +44,25 @@ function gitTrim(cwd, ...args) {
|
||||
return git(cwd, ...args).trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 嘗試同步執行 git 指令,失敗時回傳 false,成功時回傳 true。
|
||||
*
|
||||
* @param {string} cwd - git 工作目錄(repo 的 checkout 路徑)。
|
||||
* @param {...string} args - 傳給 git 的參數。
|
||||
* @returns {boolean} git 指令是否成功結束。
|
||||
* @remarks
|
||||
* 使用情境:修復淺層 checkout 的歷史不足時,部分 fetch 策略可能因 runner
|
||||
* 或遠端版本不同而失敗;呼叫端可依序嘗試多種策略,不讓第一個失敗中斷流程。
|
||||
*/
|
||||
function tryGit(cwd, ...args) {
|
||||
try {
|
||||
git(cwd, ...args);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得目前 HEAD 最新一筆 commit 的訊息標題(commit message 第一行)。
|
||||
*
|
||||
@@ -64,14 +83,14 @@ function latestCommitSubject(cwd) {
|
||||
/**
|
||||
* 解析 PR base 分支與目前 HEAD 的 merge-base commit SHA。
|
||||
*
|
||||
* 先嘗試 `git fetch origin <baseRef>` 更新 base 分支資料(失敗時靜默忽略,
|
||||
* 因 fetch-depth: 0 的 checkout 通常已含 base 分支,可直接沿用本地資料),
|
||||
* 再以 `git merge-base origin/<baseRef> HEAD` 取得共同祖先。
|
||||
* 先以 refspec 明確更新 `origin/<baseRef>`,再以 `git merge-base origin/<baseRef> HEAD`
|
||||
* 取得共同祖先。若 checkout 是淺層歷史而導致 merge-base 失敗,會補抓完整或更深的
|
||||
* base/head 歷史後重試,避免 PR workflow 因 checkout 預設深度不足而中斷。
|
||||
*
|
||||
* @param {string} cwd - git 工作目錄(repo 的 checkout 路徑)。
|
||||
* @param {string} baseRef - PR 目標(base)分支名稱,例如 'master' 或 'develop';不含 'origin/' 前綴。
|
||||
* @returns {string} merge-base 的 commit SHA(40 碼十六進位字串)。
|
||||
* @throws {Error} 本地不存在 origin/<baseRef>、或兩者無共同祖先時,`git merge-base` 失敗並拋出(fetch 失敗不會拋出)。
|
||||
* @throws {Error} 補抓歷史後仍無法取得共同祖先時,丟出含 baseRef 的明確錯誤。
|
||||
* @remarks
|
||||
* 使用情境:AI code review 以此結果作為 diff 比較基準——
|
||||
* 先 `resolveMergeBase(cwd, pr.base.ref)` 取得基準 SHA,
|
||||
@@ -79,12 +98,25 @@ function latestCommitSubject(cwd) {
|
||||
* 避免把 base 分支後續演進誤算進 diff。
|
||||
*/
|
||||
function resolveMergeBase(cwd, baseRef) {
|
||||
const remoteBase = `origin/${baseRef}`;
|
||||
tryGit(cwd, 'fetch', '--no-tags', 'origin', `+refs/heads/${baseRef}:refs/remotes/${remoteBase}`);
|
||||
try {
|
||||
git(cwd, 'fetch', 'origin', baseRef);
|
||||
} catch {
|
||||
// fetch-depth: 0 的 checkout 通常已含 base 分支,抓不到時直接沿用本地資料。
|
||||
return gitTrim(cwd, 'merge-base', remoteBase, 'HEAD');
|
||||
} catch (firstError) {
|
||||
const isShallow = gitTrim(cwd, 'rev-parse', '--is-shallow-repository') === 'true';
|
||||
if (isShallow) {
|
||||
tryGit(cwd, 'fetch', '--no-tags', '--unshallow', 'origin');
|
||||
}
|
||||
tryGit(cwd, 'fetch', '--no-tags', '--deepen=1000', 'origin', `+refs/heads/${baseRef}:refs/remotes/${remoteBase}`);
|
||||
tryGit(cwd, 'fetch', '--no-tags', '--deepen=1000', 'origin', 'HEAD');
|
||||
try {
|
||||
return gitTrim(cwd, 'merge-base', remoteBase, 'HEAD');
|
||||
} catch {
|
||||
const error = new Error(`無法解析 origin/${baseRef} 與 HEAD 的 merge-base;請確認 checkout 有足夠歷史,或設定 checkout fetch-depth: 0。`);
|
||||
error.cause = firstError;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return gitTrim(cwd, 'merge-base', `origin/${baseRef}`, 'HEAD');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user