From 75ca8cdb834ab588d7867ce6ea05d9c8dba35340 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 21 Jul 2026 15:57:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor(ai-review=20=E8=A8=BA=E6=96=B7):=20?= =?UTF-8?q?=E6=94=B6=E6=96=82=E5=A4=B1=E6=95=97=E8=BC=B8=E5=87=BA=E8=99=95?= =?UTF-8?q?=E7=90=86=E8=88=87=E6=8E=A8=E9=80=81=E8=A8=BB=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/diagnostics.js | 19 +++++++++++++++---- src/lib/gitrepo.js | 5 ++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/lib/diagnostics.js b/src/lib/diagnostics.js index d39e9ee..99c7862 100644 --- a/src/lib/diagnostics.js +++ b/src/lib/diagnostics.js @@ -29,6 +29,19 @@ function redactSecrets(text) { .trim(); } +/** + * 將 AI CLI 失敗輸出整理成單行、遮罩且限長的診斷片段。 + * + * @param {string[]} parts - 要附加診斷片段的陣列。 + * @param {string} label - 診斷欄位名稱(如 stderr/stdout)。 + * @param {*} value - 原始診斷輸出。 + * @returns {void} + */ +function appendRedactedOutput(parts, label, value) { + const redacted = redactSecrets(String(value || '').slice(0, AGENT_DIAGNOSTIC_INPUT_LIMIT)); + if (redacted) parts.push(`${label}:${redacted.slice(0, AGENT_DIAGNOSTIC_OUTPUT_LIMIT)}`); +} + /** * 從 `runAgent` 的失敗結果組出可診斷的一行摘要:退出碼/訊號為主,原始輸出預設隱藏。 * @@ -52,10 +65,8 @@ function agentFailureDetail(agentResult) { } // 失敗輸出可能含 token 或 PII,預設不寫入長期 CI log;debug 模式才輸出遮罩後片段。 if (process.env.ACTIONS_STEP_DEBUG === 'true') { - const stderr = redactSecrets(String((agentResult && agentResult.stderr) || '').slice(0, AGENT_DIAGNOSTIC_INPUT_LIMIT)); - if (stderr) parts.push(`stderr:${stderr.slice(0, AGENT_DIAGNOSTIC_OUTPUT_LIMIT)}`); - const stdout = redactSecrets(String((agentResult && agentResult.output) || '').slice(0, AGENT_DIAGNOSTIC_INPUT_LIMIT)); - if (stdout) parts.push(`stdout:${stdout.slice(0, AGENT_DIAGNOSTIC_OUTPUT_LIMIT)}`); + appendRedactedOutput(parts, 'stderr', agentResult && agentResult.stderr); + appendRedactedOutput(parts, 'stdout', agentResult && agentResult.output); } if (parts.length === 0) { parts.push((err && err.message && redactSecrets(err.message)) || 'AI CLI 執行失敗(無診斷輸出)'); diff --git a/src/lib/gitrepo.js b/src/lib/gitrepo.js index a9278a3..cd67754 100644 --- a/src/lib/gitrepo.js +++ b/src/lib/gitrepo.js @@ -300,8 +300,7 @@ function commitAndPushFindings(cwd, { headRef, headSha, message, files, token, s ); const refspec = `HEAD:refs/heads/${headRef}`; const remoteUrl = `${serverUrl}/${repository}.git`; - // 一律以 token 的身分明確認證推送(不走 origin 的自動 token)——只要 token 是能觸發 CI 的 PAT, - // 結果 commit 就會讓 PR 的 synchronize 事件再觸發 CI,由步驟 1 快速回報把結果蓋到新 head。 + // 一律以 token 的身分明確認證推送,不沿用 origin 的自動 token。 pushWithCredential(cwd, remoteUrl, token, refspec, serverUrl); return true; } @@ -348,7 +347,7 @@ function pushWithCredential(cwd, remoteUrl, token, refspec, serverUrl) { env: { ...process.env, GIT_TERMINAL_PROMPT: '0', - // 兩筆同 scope 設定:先空值清掉 checkout 的自動 token,再注入 PAT 的 Authorization。 + // 先清空 checkout extraheader,再注入本次 PAT header。 GIT_CONFIG_COUNT: '2', GIT_CONFIG_KEY_0: headerScope, GIT_CONFIG_VALUE_0: '',