feat(建問題模式): 審查留言改發到 issue、跳過舊留言處理並回貼 PR 連結

This commit is contained in:
Jeffery
2026-07-20 11:24:48 +08:00
parent af6b9a197f
commit 91fff79f22
4 changed files with 199 additions and 115 deletions
+30 -9
View File
@@ -99,8 +99,8 @@ function whoAmI(ctx) {
* @returns {Promise<object>} 建立成功的留言物件(含 `id`、`body`、`user` 等欄位,
* 依 Gitea API 回應而定)。
* @throws {Error} 請求失敗(非 2xx)由底層 `api` 丟出,錯誤附 `status`、`data`。
* @remarks 使用情境:建問題模式(input: create-issue)下,
* `createIssueWithFindings` 建立 issue 後,逐條把 finding 明細留言到該 issue
* @remarks 使用情境:建問題模式(input: create-issue)下,`main()` 建立 issue 後,
* 把工具/diff/角色情境留言與 `review.postSevereToIssue` 的嚴重問題明細留言到該 issue
* 另外 `createIssueComment` 也委派本函式對 `ctx.prNumber` 留言。
*/
function createCommentOnIssue(ctx, issueNumber, body) {
@@ -134,9 +134,9 @@ function createIssueComment(ctx, body) {
* @returns {Promise<object[]>} 標籤物件陣列(每筆含 `id`、`name`、`color` 等欄位,
* 依 Gitea API 回應而定);存取庫無標籤時為空陣列。
* @throws {Error} 任一頁請求失敗(非 2xx)由底層 `api` 丟出,錯誤附 `status`、`data`。
* @remarks 使用情境:建問題模式(input: create-issue)下,
* `createIssueWithFindings` 先以本函式取得可用標籤,再交給 `selectLabels`
* 讓 AI 從中挑選適合掛在新 issue 上的標籤子集合
* @remarks 使用情境:建問題模式(input: create-issue)下,`main()` 收束時
* 先以本函式取得可用標籤,再交給 `review.selectLabels` 讓 AI 挑出適合的標籤子集合,
* 最後以 `addLabelsToIssue` 補掛到追蹤 issue 上。
*/
function listLabels(ctx) {
return listAll(ctx, `/repos/${ctx.owner}/${ctx.repo}/labels`);
@@ -156,10 +156,9 @@ function listLabels(ctx) {
* @returns {Promise<object>} 建立成功的 issue 物件(含 `number`、`title`、
* `html_url` 等欄位,依 Gitea API 回應而定)。
* @throws {Error} 請求失敗(非 2xx)由底層 `api` 丟出,錯誤附 `status`、`data`。
* @remarks 使用情境:建問題模式(input: create-issue)下,
* `createIssueWithFindings` 以 PR 標題/描述為 issue 標題與本文、
* 配上 `selectLabels` 挑出的標籤 id,呼叫本函式建立追蹤問題的 issue,
* 再逐條把 finding 明細留言到該 issue。
* @remarks 使用情境:建問題模式(input: create-issue)下,`main()` 的 `ensureIssueCreated`
* 以 PR 標題/描述為 issue 標題與本文(先不掛標籤)呼叫本函式建立追蹤問題的 issue,
* 之後再把審查內容留言到該 issue、並以 `addLabelsToIssue` 補掛標籤。
*/
function createIssue(ctx, { title, body, labels }) {
return api(ctx, 'POST', `/repos/${ctx.owner}/${ctx.repo}/issues`, {
@@ -169,6 +168,27 @@ function createIssue(ctx, { title, body, labels }) {
});
}
/**
* 為既有 issue 追加標籤(不影響既有標籤)。
* 對應 endpoint`POST /repos/{owner}/{repo}/issues/{issueNumber}/labels`。
* `labels` 為空陣列時不呼叫 API、直接回傳 `null`(省一次無意義請求)。
*
* @param {object} ctx - 執行環境 context。必要欄位:`apiBase`、`token`、
* `owner`repo 擁有者)、`repo`repo 名稱)。
* @param {number|string} issueNumber - 目標 issue 編號。
* @param {number[]} labels - 要追加的標籤 id 陣列。
* @returns {Promise<object[]|null>} 追加後該 issue 的標籤陣列(依 Gitea API 回應而定);
* `labels` 為空時回傳 `null`(未發出請求)。
* @throws {Error} 請求失敗(非 2xx)由底層 `api` 丟出,錯誤附 `status`、`data`。
* @remarks 使用情境:建問題模式(input: create-issue)下先以空標籤建立 issue、
* 待防守方裁決得到保留問題後,再以 `selectLabels` 挑出的標籤 id 呼叫本函式補掛,
* 讓標籤挑選能參考最終的問題清單。
*/
function addLabelsToIssue(ctx, issueNumber, labels) {
if (!labels || labels.length === 0) return Promise.resolve(null);
return api(ctx, 'POST', `/repos/${ctx.owner}/${ctx.repo}/issues/${issueNumber}/labels`, { labels });
}
/**
* 列出 PR 上的全部一般留言(自動分頁撈取,每頁 50 筆直到取完)。
* 對應 endpoint`GET /repos/{owner}/{repo}/issues/{prNumber}/comments`。
@@ -303,6 +323,7 @@ module.exports = {
createCommentOnIssue,
listLabels,
createIssue,
addLabelsToIssue,
listIssueComments,
editIssueComment,
createReview,