chore: skip ai review bot commits

This commit is contained in:
2026-05-15 14:10:12 +00:00
parent 3ae08052a3
commit 9012fe64d1
5 changed files with 28 additions and 32 deletions
+1 -29
View File
@@ -5,36 +5,9 @@ on:
- master - master
types: [opened, synchronize] types: [opened, synchronize]
jobs: jobs:
detect-bot-commit:
name: 偵測自動提交
runs-on: ubuntu
outputs:
skip: ${{ steps.detect.outputs.skip }}
steps:
- name: 檢查 head commit marker
id: detect
env:
GITEA_API_URL: ${{ github.api_url }}
GITEA_REPOSITORY: ${{ github.repository }}
GITEA_SHA: ${{ github.sha }}
GITEA_TOKEN: ${{ github.token }}
run: |
set -e
commit_json="$(curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" "${GITEA_API_URL}/repos/${GITEA_REPOSITORY}/git/commits/${GITEA_SHA}")" || {
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
}
if printf '%s' "$commit_json" | grep -q '\[ai-review-bot\]'; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "偵測到 AI Review Bot commit,跳過 review workflow"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
version: version:
name: 計算版本號 name: 計算版本號
runs-on: ubuntu runs-on: ubuntu
needs: [detect-bot-commit]
if: needs.detect-bot-commit.outputs.skip != 'true'
outputs: outputs:
version: ${{ steps.version.outputs.version }} version: ${{ steps.version.outputs.version }}
steps: steps:
@@ -52,8 +25,7 @@ jobs:
code-review: code-review:
name: Code Review name: Code Review
runs-on: ubuntu runs-on: ubuntu
needs: [detect-bot-commit, version] needs: [version]
if: needs.detect-bot-commit.outputs.skip != 'true'
steps: steps:
- name: AI Code Review - name: AI Code Review
uses: https://gitea.jsc.idv.tw/actions/code-review@v${{ needs.version.outputs.version }} uses: https://gitea.jsc.idv.tw/actions/code-review@v${{ needs.version.outputs.version }}
+1 -1
View File
@@ -33,7 +33,7 @@
2.`.gitea/workflows` 資料夾中建立 `ai-review.yaml' 2.`.gitea/workflows` 資料夾中建立 `ai-review.yaml'
3.`ai-review.yaml` 中填入以下內容(選擇一個使用) 3.`ai-review.yaml` 中填入以下內容(選擇一個使用)
> **自動提交排除說明**:此 Action 會將自己的 commit message 標記為 `[ai-review-bot]`。建議在 review workflow 的最前面先檢查 head commit 是否含有這個 marker,若有就直接成功結束,避免 bot commit 造成重複觸發。 > **自動提交排除說明**:此 Action 會將自己的 commit message 標記為 `[ai-review-bot]`,而且 action 執行時也會先檢查 head commit 是否含有這個 marker,若有就直接成功結束,避免 bot commit 造成重複觸發。若外層 workflow 也能先檢查一次,效果最好。
> **權限說明**:此 Action 需要 `contents: write`(寫入 findings.json)、`pull-requests: write`(發佈 PR comment)、`issues: write`(發佈 issue comment)三項權限,為正常運作所必要,無法縮減。 > **權限說明**:此 Action 需要 `contents: write`(寫入 findings.json)、`pull-requests: write`(發佈 PR comment)、`issues: write`(發佈 issue comment)三項權限,為正常運作所必要,無法縮減。
+9
View File
@@ -59,6 +59,15 @@ export function getRepoState(repoDir, _spawnSync = spawnSync) {
return { repoDir, branch, headSha, shortSha, commitTime }; return { repoDir, branch, headSha, shortSha, commitTime };
} }
export function getHeadCommitMessage(repoDir, _spawnSync = spawnSync) {
const run = makeRunner(_spawnSync);
return readGitOutput(run, ['show', '-s', '--format=%B', 'HEAD'], repoDir);
}
export function isBotAutoCommit(repoDir, _spawnSync = spawnSync) {
return getHeadCommitMessage(repoDir, _spawnSync).includes(BOT_COMMIT_MARKER);
}
/** /**
* Clone PR head branch to workspace/repo (idempotent) * Clone PR head branch to workspace/repo (idempotent)
*/ */
+10 -1
View File
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
import fs from 'fs'; import fs from 'fs';
import os from 'os'; import os from 'os';
import path from 'path'; import path from 'path';
import { commitAndPush, cloneRepo, SYNC_PATHS, BOT_COMMIT_MARKER } from './git.js'; import { commitAndPush, cloneRepo, SYNC_PATHS, BOT_COMMIT_MARKER, getHeadCommitMessage, isBotAutoCommit } from './git.js';
// --- helpers --- // --- helpers ---
function makeTmpWorkspace() { function makeTmpWorkspace() {
@@ -241,4 +241,13 @@ describe('cloneRepo', () => {
const result = cloneRepo(workspace, spawn); const result = cloneRepo(workspace, spawn);
assert.equal(result, path.join(workspace, 'repo')); assert.equal(result, path.join(workspace, 'repo'));
}); });
it('reads head commit message and detects bot auto commits', () => {
const spawn = makeSpawn({
show: () => ({ status: 0, stdout: `chore: update ai-review findings ${BOT_COMMIT_MARKER}\n`, stderr: '', error: null }),
});
assert.ok(getHeadCommitMessage(workspace, spawn).includes(BOT_COMMIT_MARKER));
assert.equal(isBotAutoCommit(workspace, spawn), true);
});
}); });
+7 -1
View File
@@ -4,7 +4,7 @@ import { loadRoles, getRoleIntro } from './roles.js';
import { getPRDiff, postComment } from './gitea.js'; import { getPRDiff, postComment } from './gitea.js';
import { analyzeWithRole, loadOldFindings, mergeFindings, sortByLevel, deduplicateWithAI, loadExclusions, applyExclusions, filterFalsePositivesWithAI } from './findings.js'; import { analyzeWithRole, loadOldFindings, mergeFindings, sortByLevel, deduplicateWithAI, loadExclusions, applyExclusions, filterFalsePositivesWithAI } from './findings.js';
import { saveFindings, postOldFindingsComment, postNewNonCriticalComment, postNewCriticalComments } from './comments.js'; import { saveFindings, postOldFindingsComment, postNewNonCriticalComment, postNewCriticalComments } from './comments.js';
import { cloneRepo, commitAndPush, getRepoState } from './git.js'; import { cloneRepo, commitAndPush, getRepoState, isBotAutoCommit } from './git.js';
import { validateJSONArrayFile, ensureJSONArrayFileExists } from './json.js'; import { validateJSONArrayFile, ensureJSONArrayFileExists } from './json.js';
const WORKSPACE = process.env.GITHUB_WORKSPACE || '/workspace'; const WORKSPACE = process.env.GITHUB_WORKSPACE || '/workspace';
@@ -15,6 +15,12 @@ async function main() {
console.log(` repo=${GITEA_REPOSITORY} PR=#${PR_NUMBER}`); console.log(` repo=${GITEA_REPOSITORY} PR=#${PR_NUMBER}`);
console.log(` ${PR_HEAD_BRANCH} -> ${PR_BASE_BRANCH}`); console.log(` ${PR_HEAD_BRANCH} -> ${PR_BASE_BRANCH}`);
if (isBotAutoCommit(WORKSPACE)) {
console.log(' 🤖 偵測到 [ai-review-bot] 自動提交,直接完成 action');
console.log('='.repeat(60));
process.exit(0);
}
const { provider, baseURL, model } = getLLMConfig(); const { provider, baseURL, model } = getLLMConfig();
if (!provider) { if (!provider) {
console.error('❌ 未設定任何 LLM API Key,請檢查 action inputs'); console.error('❌ 未設定任何 LLM API Key,請檢查 action inputs');