fix(推送觸發 CI): 合併 push-token 進 token,findings 一律以 token 認證推送觸發 CI
- 移除 push-token input,token 兼作 Gitea API 認證與 findings 推送
- commitAndPushFindings 一律以 token 明確認證推送(不走 origin 自動 token);
只要 token 為能觸發 CI 的 PAT,結果 commit 即再觸發 PR 的 CI,避免新 head 缺檢查卡合併
- ci.yaml 三個 job 移除 push-token,保留 token: ${{ secrets.TOKEN }}
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9e6e8bb793
commit
05178be520
@@ -48,9 +48,6 @@ jobs:
|
|||||||
create-issue: 'true'
|
create-issue: 'true'
|
||||||
# 指定 AI 模型:CI 測試固定用 Antigravity 最省模型以降低消耗。
|
# 指定 AI 模型:CI 測試固定用 Antigravity 最省模型以降低消耗。
|
||||||
model: gemini-3.5-flash
|
model: gemini-3.5-flash
|
||||||
# 推送 findings/exclusions commit 用的 PAT:以 PAT 身分推送才會讓結果 commit 再觸發 CI,
|
|
||||||
# 由步驟 1 快速回報把結果蓋到新 head,避免自動 token 推送不觸發而卡合併。
|
|
||||||
push-token: ${{ secrets.TOKEN }}
|
|
||||||
# Codex 工具環境測試 job。
|
# Codex 工具環境測試 job。
|
||||||
test-codex:
|
test-codex:
|
||||||
# Job 在 workflow UI 顯示的名稱。
|
# Job 在 workflow UI 顯示的名稱。
|
||||||
@@ -81,9 +78,6 @@ jobs:
|
|||||||
create-issue: 'true'
|
create-issue: 'true'
|
||||||
# 指定 AI 模型:CI 測試固定用 Codex 最省模型以降低消耗。
|
# 指定 AI 模型:CI 測試固定用 Codex 最省模型以降低消耗。
|
||||||
model: gpt-5.5
|
model: gpt-5.5
|
||||||
# 推送 findings/exclusions commit 用的 PAT:以 PAT 身分推送才會讓結果 commit 再觸發 CI,
|
|
||||||
# 由步驟 1 快速回報把結果蓋到新 head,避免自動 token 推送不觸發而卡合併。
|
|
||||||
push-token: ${{ secrets.TOKEN }}
|
|
||||||
# Claude 工具環境測試 job。
|
# Claude 工具環境測試 job。
|
||||||
test-claude:
|
test-claude:
|
||||||
# Job 在 workflow UI 顯示的名稱。
|
# Job 在 workflow UI 顯示的名稱。
|
||||||
@@ -114,6 +108,3 @@ jobs:
|
|||||||
create-issue: 'true'
|
create-issue: 'true'
|
||||||
# 指定 AI 模型:Claude job 使用 Opus 4.8。
|
# 指定 AI 模型:Claude job 使用 Opus 4.8。
|
||||||
model: claude-opus-4-8
|
model: claude-opus-4-8
|
||||||
# 推送 findings/exclusions commit 用的 PAT:以 PAT 身分推送才會讓結果 commit 再觸發 CI,
|
|
||||||
# 由步驟 1 快速回報把結果蓋到新 head,避免自動 token 推送不觸發而卡合併。
|
|
||||||
push-token: ${{ secrets.TOKEN }}
|
|
||||||
|
|||||||
+6
-15
@@ -16,11 +16,13 @@ author: 'Jeffery'
|
|||||||
# 輸入參數區塊:呼叫端 workflow 以 `with:` 傳入,
|
# 輸入參數區塊:呼叫端 workflow 以 `with:` 傳入,
|
||||||
# runner 會自動注入為 INPUT_* 環境變數(例如 INPUT_TOKEN、INPUT_MODEL、INPUT_CREATE-ISSUE)供主程式讀取。
|
# runner 會自動注入為 INPUT_* 環境變數(例如 INPUT_TOKEN、INPUT_MODEL、INPUT_CREATE-ISSUE)供主程式讀取。
|
||||||
inputs:
|
inputs:
|
||||||
# Gitea API token:用於對 PR 留言審查結果、以及 push 審查結果檔回 repo。
|
# Gitea API token:用於對 PR/issue 留言審查結果,以及 push 審查結果檔(findings/exclusions)回 repo。
|
||||||
token:
|
token:
|
||||||
# 參數用途說明:secrets/vars context 在 action 內不可用,
|
# 參數用途說明:secrets/vars context 在 action 內不可用,故由呼叫端 workflow 以 secrets 傳入。
|
||||||
# 故由呼叫端 workflow 以 secrets.GITHUB_TOKEN 傳入。
|
# 建議傳入「能觸發 CI 的 PAT」:以自動 token(gitea.token / GITHUB_TOKEN)推送的結果 commit 不會
|
||||||
description: 'Gitea API token(PR 留言與 push findings 用;呼叫端以 secrets.GITHUB_TOKEN 傳入)'
|
# 再觸發 CI,導致新 head 缺檢查而卡合併;改用 PAT 推送會讓 PR 的 synchronize 事件再觸發 CI,
|
||||||
|
# 由主程式步驟 1 快速回報([success]/[failure])廉價地把結果蓋到新 head。
|
||||||
|
description: 'Gitea API token(PR/issue 留言與 push findings 用;建議以能觸發 CI 的 PAT 由 secrets 傳入)'
|
||||||
# 必填:缺少 token 無法呼叫 Gitea API,action 無法運作。
|
# 必填:缺少 token 無法呼叫 Gitea API,action 無法運作。
|
||||||
required: true
|
required: true
|
||||||
# 指定 AI 工具使用的模型名稱。
|
# 指定 AI 工具使用的模型名稱。
|
||||||
@@ -41,17 +43,6 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
# 預設為字串 'false',代表不啟用建問題模式(主程式只認字串 'true' 才啟用)。
|
# 預設為字串 'false',代表不啟用建問題模式(主程式只認字串 'true' 才啟用)。
|
||||||
default: 'false'
|
default: 'false'
|
||||||
# 推送用 PAT:推送 findings/exclusions commit 時改以此 token 進行。
|
|
||||||
push-token:
|
|
||||||
# 參數用途說明:以自動 token(gitea.token / GITHUB_TOKEN)推送的 commit 不會再觸發 CI,
|
|
||||||
# 導致新 head 缺檢查而卡合併;改用 PAT 推送會讓 PR 的 synchronize 事件再觸發 CI,
|
|
||||||
# 由主程式步驟 1 快速回報([success]/[failure])廉價地把結果蓋到新 head。
|
|
||||||
# 呼叫端以 secrets 傳入(例如 secrets.TOKEN)。留空=退回以 token 走 origin 推送(不會再觸發)。
|
|
||||||
description: '推送 findings/exclusions commit 用的 PAT(讓 CI 再觸發;呼叫端以 secrets 傳入;留空=退回 token 推送、不再觸發)'
|
|
||||||
# 選填:未指定時退回以 token 推送。
|
|
||||||
required: false
|
|
||||||
# 預設為空字串,代表不使用專用推送 PAT。
|
|
||||||
default: ''
|
|
||||||
# 執行方式區塊:宣告本 action 為 node action 及其進入點。
|
# 執行方式區塊:宣告本 action 為 node action 及其進入點。
|
||||||
runs:
|
runs:
|
||||||
# 以 Node.js 24 runtime 直接在 runner 上執行(非 Docker 容器、非 composite)。
|
# 以 Node.js 24 runtime 直接在 runner 上執行(非 Docker 容器、非 composite)。
|
||||||
|
|||||||
+2
-2
@@ -90,7 +90,8 @@ function saveFindings({ cwd, ctx, tool, kept, excluded }) {
|
|||||||
* 依模式組出 filesToCommit(一般模式:findings 檔+有變更時的 exclusions.json;
|
* 依模式組出 filesToCommit(一般模式:findings 檔+有變更時的 exclusions.json;
|
||||||
* 建問題模式:只有 exclusions.json)後呼叫本函式;另在步驟 4 判定無可審查變更且非建問題模式時,
|
* 建問題模式:只有 exclusions.json)後呼叫本函式;另在步驟 4 判定無可審查變更且非建問題模式時,
|
||||||
* 也會以 result: 'success' 提交空 findings。
|
* 也會以 result: 'success' 提交空 findings。
|
||||||
* 推送以 `ctx.pushToken`(PAT)優先,使結果 commit 再觸發 CI、由步驟 1 快速回報;
|
* 推送一律以 `ctx.token` 的身分進行(不走 runner 的 origin 自動 token);只要 token 是能觸發 CI 的
|
||||||
|
* PAT,結果 commit 就會再觸發 CI、由步驟 1 快速回報;
|
||||||
* 注意 commit 訊息與模組常數 `BOT_COMMIT_PREFIX` 耦合,修改前綴會使步驟 1 的快速回報失效。
|
* 注意 commit 訊息與模組常數 `BOT_COMMIT_PREFIX` 耦合,修改前綴會使步驟 1 的快速回報失效。
|
||||||
*/
|
*/
|
||||||
function commitFindings({ cwd, ctx, files, result }) {
|
function commitFindings({ cwd, ctx, files, result }) {
|
||||||
@@ -101,7 +102,6 @@ function commitFindings({ cwd, ctx, files, result }) {
|
|||||||
message: `${BOT_COMMIT_PREFIX}[${result}]`,
|
message: `${BOT_COMMIT_PREFIX}[${result}]`,
|
||||||
files,
|
files,
|
||||||
token: ctx.token,
|
token: ctx.token,
|
||||||
pushToken: ctx.pushToken,
|
|
||||||
serverUrl: ctx.serverUrl,
|
serverUrl: ctx.serverUrl,
|
||||||
repository: ctx.repository,
|
repository: ctx.repository,
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-6
@@ -20,7 +20,6 @@ const path = require('path');
|
|||||||
* token: string,
|
* token: string,
|
||||||
* model: string,
|
* model: string,
|
||||||
* createIssue: boolean,
|
* createIssue: boolean,
|
||||||
* pushToken: string,
|
|
||||||
* event: Object,
|
* event: Object,
|
||||||
* pr: (Object|null),
|
* pr: (Object|null),
|
||||||
* prNumber: (number|null),
|
* prNumber: (number|null),
|
||||||
@@ -38,12 +37,11 @@ const path = require('path');
|
|||||||
* - repository:`owner/repo` 全名(GITHUB_REPOSITORY)。
|
* - repository:`owner/repo` 全名(GITHUB_REPOSITORY)。
|
||||||
* - owner / repo:自 repository 拆出的擁有者與專案名,缺值時為空字串。
|
* - owner / repo:自 repository 拆出的擁有者與專案名,缺值時為空字串。
|
||||||
* - apiBase:Gitea REST API 基底網址(`<serverUrl>/api/v1`)。
|
* - apiBase:Gitea REST API 基底網址(`<serverUrl>/api/v1`)。
|
||||||
* - token:action input `token`(INPUT_TOKEN),用於 API 認證,缺值時為空字串。
|
* - token:action input `token`(INPUT_TOKEN),用於 Gitea API 認證,以及 push findings/exclusions
|
||||||
|
* commit 回 repo;建議為「能觸發 CI 的 PAT」(自動 token 推送不會再觸發 CI)。缺值時為空字串。
|
||||||
* - model:action input `model`(INPUT_MODEL,已 trim),指定 AI 模型,缺值時為空字串。
|
* - model:action input `model`(INPUT_MODEL,已 trim),指定 AI 模型,缺值時為空字串。
|
||||||
* - createIssue:action input `create-issue`(INPUT_CREATE-ISSUE),是否將問題建到
|
* - createIssue:action input `create-issue`(INPUT_CREATE-ISSUE),是否將問題建到
|
||||||
* 存取庫的問題追蹤(建問題模式);trim + 小寫後與字串 'true' 嚴格比對,預設 false。
|
* 存取庫的問題追蹤(建問題模式);trim + 小寫後與字串 'true' 嚴格比對,預設 false。
|
||||||
* - pushToken:action input `push-token`(INPUT_PUSH-TOKEN),推送 findings/exclusions commit 用的 PAT;
|
|
||||||
* 提供時以 PAT 身分推送使 CI 再觸發(配合步驟 1 快速回報);留空=退回以 token 走 origin 推送(不會再觸發)。
|
|
||||||
* - event:事件 payload 解析後的完整物件;讀取失敗時為空物件。
|
* - event:事件 payload 解析後的完整物件;讀取失敗時為空物件。
|
||||||
* - pr:payload 內的 pull_request 物件;非 PR 事件時為 null。
|
* - pr:payload 內的 pull_request 物件;非 PR 事件時為 null。
|
||||||
* - prNumber:PR 編號,優先取 payload,退而從 GITHUB_REF(refs/pull/N/...)解析;皆無時為 null。
|
* - prNumber:PR 編號,優先取 payload,退而從 GITHUB_REF(refs/pull/N/...)解析;皆無時為 null。
|
||||||
@@ -95,8 +93,6 @@ function loadContext() {
|
|||||||
model: (process.env.INPUT_MODEL || '').trim(),
|
model: (process.env.INPUT_MODEL || '').trim(),
|
||||||
// 是否將問題建到存取庫的問題追蹤(input: create-issue,字串 'true' 才啟用,預設否)。
|
// 是否將問題建到存取庫的問題追蹤(input: create-issue,字串 'true' 才啟用,預設否)。
|
||||||
createIssue: (process.env['INPUT_CREATE-ISSUE'] || '').trim().toLowerCase() === 'true',
|
createIssue: (process.env['INPUT_CREATE-ISSUE'] || '').trim().toLowerCase() === 'true',
|
||||||
// 推送 findings/exclusions commit 用的 PAT(input: push-token);提供時以 PAT 推送讓 CI 再觸發,留空=退回 token。
|
|
||||||
pushToken: (process.env['INPUT_PUSH-TOKEN'] || '').trim(),
|
|
||||||
event,
|
event,
|
||||||
pr,
|
pr,
|
||||||
prNumber,
|
prNumber,
|
||||||
|
|||||||
+8
-18
@@ -223,9 +223,9 @@ function fileLastUpdatedIso(cwd, file) {
|
|||||||
* 若目前 HEAD 不在 PR head commit(例如 checkout 停在 merge commit),
|
* 若目前 HEAD 不在 PR head commit(例如 checkout 停在 merge commit),
|
||||||
* 會先 `git checkout --detach <headSha>` 站上 head,避免把 merge 內容推回來源分支。
|
* 會先 `git checkout --detach <headSha>` 站上 head,避免把 merge 內容推回來源分支。
|
||||||
* commit 以 `-c` 臨時覆寫 user.name / user.email,不改動 repo 的 git 設定。
|
* commit 以 `-c` 臨時覆寫 user.name / user.email,不改動 repo 的 git 設定。
|
||||||
* push 策略:提供 `pushToken`(PAT)時直接以該 token 的 URL 推送(略過 origin)——因為 origin
|
* push 策略:一律以 `token` 的身分明確認證推送({@link pushWithCredential},不走 runner 的
|
||||||
* 帶的是不會再觸發 CI 的自動 token,改以 PAT 身分推送才會讓 PR 的 synchronize 事件再觸發 CI;
|
* origin 自動 token)——origin 帶的自動 token(gitea.token / GITHUB_TOKEN)推送不會再觸發 CI,
|
||||||
* 未提供 `pushToken` 時先走 origin,失敗(遠端未帶認證)再改用帶 `token` 的 URL 重試。
|
* 改以呼叫端提供的 `token`(建議為 PAT)身分推送,才會讓 PR 的 synchronize 事件再觸發 CI。
|
||||||
*
|
*
|
||||||
* @param {string} cwd - git 工作目錄(repo 的 checkout 路徑)。
|
* @param {string} cwd - git 工作目錄(repo 的 checkout 路徑)。
|
||||||
* @param {object} options - 提交與推送設定。
|
* @param {object} options - 提交與推送設定。
|
||||||
@@ -233,8 +233,7 @@ function fileLastUpdatedIso(cwd, file) {
|
|||||||
* @param {string} [options.headSha] - PR head 的 commit SHA;有提供且與目前 HEAD 不同時會先 detach 到此 commit。可省略(falsy 時不 detach,直接於目前 HEAD 上 commit)。
|
* @param {string} [options.headSha] - PR head 的 commit SHA;有提供且與目前 HEAD 不同時會先 detach 到此 commit。可省略(falsy 時不 detach,直接於目前 HEAD 上 commit)。
|
||||||
* @param {string} options.message - commit 訊息。
|
* @param {string} options.message - commit 訊息。
|
||||||
* @param {string[]} options.files - 要加入 commit 的檔案路徑清單(相對 repo 根目錄);全數無實際變更時不 commit、回傳 false。
|
* @param {string[]} options.files - 要加入 commit 的檔案路徑清單(相對 repo 根目錄);全數無實際變更時不 commit、回傳 false。
|
||||||
* @param {string} options.token - 具該 repo push 權限的 Gitea access token;未提供 pushToken 時,於 origin push 失敗才用於組出帶認證的重試 URL。
|
* @param {string} options.token - 具該 repo push 權限的 Gitea access token(建議為能觸發 CI 的 PAT);用於 findings commit 的認證推送。
|
||||||
* @param {string} [options.pushToken] - 專用推送 token(PAT);提供時直接以此 token 的 URL 推送(略過 origin),使 push 以 PAT 身分進行以再觸發 CI;未提供時走 origin、失敗再退回 `token`。
|
|
||||||
* @param {string} options.serverUrl - Gitea 伺服器根網址(例如 https://gitea.example.com),須為合法 URL。
|
* @param {string} options.serverUrl - Gitea 伺服器根網址(例如 https://gitea.example.com),須為合法 URL。
|
||||||
* @param {string} options.repository - repo 完整名稱(owner/repo 格式),與 serverUrl 組成 clone URL。
|
* @param {string} options.repository - repo 完整名稱(owner/repo 格式),與 serverUrl 組成 clone URL。
|
||||||
* @returns {boolean} true=有變更且已 commit 並 push 到來源分支;false=暫存區與 HEAD 無差異,略過 commit/push。
|
* @returns {boolean} true=有變更且已 commit 並 push 到來源分支;false=暫存區與 HEAD 無差異,略過 commit/push。
|
||||||
@@ -249,7 +248,7 @@ function fileLastUpdatedIso(cwd, file) {
|
|||||||
* 推送目標 URL 本身不含帳密;且 push 失敗時改拋固定訊息,避免 `execFileSync`
|
* 推送目標 URL 本身不含帳密;且 push 失敗時改拋固定訊息,避免 `execFileSync`
|
||||||
* 例外把命令列(含 token)回顯到 CI log 或程序清單。
|
* 例外把命令列(含 token)回顯到 CI log 或程序清單。
|
||||||
*/
|
*/
|
||||||
function commitAndPushFindings(cwd, { headRef, headSha, message, files, token, pushToken, serverUrl, repository }) {
|
function commitAndPushFindings(cwd, { headRef, headSha, message, files, token, serverUrl, repository }) {
|
||||||
const current = gitTrim(cwd, 'rev-parse', 'HEAD');
|
const current = gitTrim(cwd, 'rev-parse', 'HEAD');
|
||||||
if (headSha && current !== headSha) {
|
if (headSha && current !== headSha) {
|
||||||
git(cwd, 'checkout', '--detach', headSha);
|
git(cwd, 'checkout', '--detach', headSha);
|
||||||
@@ -269,18 +268,9 @@ function commitAndPushFindings(cwd, { headRef, headSha, message, files, token, p
|
|||||||
);
|
);
|
||||||
const refspec = `HEAD:refs/heads/${headRef}`;
|
const refspec = `HEAD:refs/heads/${headRef}`;
|
||||||
const remoteUrl = `${serverUrl}/${repository}.git`;
|
const remoteUrl = `${serverUrl}/${repository}.git`;
|
||||||
if (pushToken) {
|
// 一律以 token 的身分明確認證推送(不走 origin 的自動 token)——只要 token 是能觸發 CI 的 PAT,
|
||||||
// 有專用 PAT → 以 PAT 推送(略過 origin,因 origin 帶的是不會再觸發 CI 的自動 token);
|
// 結果 commit 就會讓 PR 的 synchronize 事件再觸發 CI,由步驟 1 快速回報把結果蓋到新 head。
|
||||||
// 以 PAT 身分推送才會讓 PR 的 synchronize 事件再觸發 CI。
|
pushWithCredential(cwd, remoteUrl, token, refspec);
|
||||||
pushWithCredential(cwd, remoteUrl, pushToken, refspec);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
git(cwd, 'push', 'origin', refspec);
|
|
||||||
} catch {
|
|
||||||
// 遠端未帶認證(checkout 未保留 credentials)時,改用帶認證的推送重試。
|
|
||||||
pushWithCredential(cwd, remoteUrl, token, refspec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user