Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ece7377fc8 | |||
| 68cd124f59 | |||
| e9f3baf95f | |||
| 33d5cdde7c | |||
| ae96ead6cf |
@@ -7,7 +7,7 @@ When the task is to triage review findings, follow this workflow:
|
|||||||
3. Sort by severity: `critical` -> `warning` -> `info`.
|
3. Sort by severity: `critical` -> `warning` -> `info`.
|
||||||
4. Renumber from 1 after sorting.
|
4. Renumber from 1 after sorting.
|
||||||
5. Fix real issues with the smallest safe change.
|
5. Fix real issues with the smallest safe change.
|
||||||
6. Add false positives to `.gitea/ai-review/exclusions.json`.
|
6. Add false positives to `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
|
||||||
7. Add or update tests when behavior changes.
|
7. Add or update tests when behavior changes.
|
||||||
8. Re-check the issue after each fix.
|
8. Re-check the issue after each fix.
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ description: Triage findings, fix real issues, and exclude false positives.
|
|||||||
- info
|
- info
|
||||||
3. Renumber from 1.
|
3. Renumber from 1.
|
||||||
4. Fix real issues.
|
4. Fix real issues.
|
||||||
5. Put false positives into `.gitea/ai-review/exclusions.json`.
|
5. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
|
||||||
6. Add tests when behavior changes.
|
6. Add tests when behavior changes.
|
||||||
|
|
||||||
## Output Rules
|
## Output Rules
|
||||||
@@ -26,3 +26,4 @@ description: Triage findings, fix real issues, and exclude false positives.
|
|||||||
- Keep the final list short.
|
- Keep the final list short.
|
||||||
- Keep numbering contiguous.
|
- Keep numbering contiguous.
|
||||||
- Preserve file path, location, and fix.
|
- Preserve file path, location, and fix.
|
||||||
|
- When writing exclusions, prefer the original issue text over paraphrased rewrites.
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ It is also used when some findings are false positives and should be moved into
|
|||||||
4. Renumber the sorted list from 1 upward.
|
4. Renumber the sorted list from 1 upward.
|
||||||
5. Rewrite each finding concisely so the final list reads cleanly and consistently.
|
5. Rewrite each finding concisely so the final list reads cleanly and consistently.
|
||||||
6. If a finding is a false positive, do not keep it in the final list.
|
6. If a finding is a false positive, do not keep it in the final list.
|
||||||
7. Add false positives to the exclusions list using the existing schema in the repo or task context.
|
7. Add false positives to the exclusions list using the existing schema in the repo or task context, and preserve the original finding wording as much as possible, including language and semantics.
|
||||||
|
|
||||||
## Resolution Flow
|
## Resolution Flow
|
||||||
|
|
||||||
@@ -41,4 +41,5 @@ After the list is merged and ordered, resolve the remaining findings one by one.
|
|||||||
- Keep numbering contiguous after filtering and merging.
|
- Keep numbering contiguous after filtering and merging.
|
||||||
- Preserve useful details like file path, location, and suggested fix.
|
- Preserve useful details like file path, location, and suggested fix.
|
||||||
- Keep exclusions entries minimal and consistent with the project schema.
|
- Keep exclusions entries minimal and consistent with the project schema.
|
||||||
|
- When writing exclusions, prefer the original issue text and language; only paraphrase if needed to fit the schema.
|
||||||
- If the source already provides a severity or title, keep it unless it conflicts with the final ordering.
|
- If the source already provides a severity or title, keep it unless it conflicts with the final ordering.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ description: Triage findings, fix real issues, and exclude false positives.
|
|||||||
- info
|
- info
|
||||||
3. Renumber from 1.
|
3. Renumber from 1.
|
||||||
4. Fix real issues.
|
4. Fix real issues.
|
||||||
5. Put false positives into `.gitea/ai-review/exclusions.json`.
|
5. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
|
||||||
6. Add tests when behavior changes.
|
6. Add tests when behavior changes.
|
||||||
|
|
||||||
## Output Rules
|
## Output Rules
|
||||||
@@ -26,3 +26,4 @@ description: Triage findings, fix real issues, and exclude false positives.
|
|||||||
- Keep the final list short.
|
- Keep the final list short.
|
||||||
- Keep numbering contiguous.
|
- Keep numbering contiguous.
|
||||||
- Preserve file path, location, and fix.
|
- Preserve file path, location, and fix.
|
||||||
|
- When writing exclusions, prefer the original issue text over paraphrased rewrites.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Use the triage-finding workflow for review issue lists:
|
|||||||
3. Sort by severity: `critical` -> `warning` -> `info`.
|
3. Sort by severity: `critical` -> `warning` -> `info`.
|
||||||
4. Renumber from 1.
|
4. Renumber from 1.
|
||||||
5. Fix real issues with the smallest safe change.
|
5. Fix real issues with the smallest safe change.
|
||||||
6. Put false positives into `.gitea/ai-review/exclusions.json`.
|
6. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
|
||||||
7. Add or update tests when behavior changes.
|
7. Add or update tests when behavior changes.
|
||||||
8. Re-check after each fix.
|
8. Re-check after each fix.
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Use the triage-finding workflow for review issue lists:
|
|||||||
3. Sort by severity: `critical` -> `warning` -> `info`.
|
3. Sort by severity: `critical` -> `warning` -> `info`.
|
||||||
4. Renumber from 1.
|
4. Renumber from 1.
|
||||||
5. Fix real issues with the smallest safe change.
|
5. Fix real issues with the smallest safe change.
|
||||||
6. Put false positives into `.gitea/ai-review/exclusions.json`.
|
6. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
|
||||||
7. Add or update tests when behavior changes.
|
7. Add or update tests when behavior changes.
|
||||||
8. Re-check after each fix.
|
8. Re-check after each fix.
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ When the task is to triage review findings, follow this workflow:
|
|||||||
3. Sort by severity: `critical` -> `warning` -> `info`.
|
3. Sort by severity: `critical` -> `warning` -> `info`.
|
||||||
4. Renumber from 1 after sorting.
|
4. Renumber from 1 after sorting.
|
||||||
5. Fix real issues with the smallest safe change.
|
5. Fix real issues with the smallest safe change.
|
||||||
6. Add false positives to `.gitea/ai-review/exclusions.json`.
|
6. Add false positives to `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
|
||||||
7. Add or update tests when behavior changes.
|
7. Add or update tests when behavior changes.
|
||||||
8. Re-check the issue after each fix.
|
8. Re-check the issue after each fix.
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ COPY app/package.json /action/app/
|
|||||||
RUN cd /action/app && npm install
|
RUN cd /action/app && npm install
|
||||||
|
|
||||||
COPY .amazonq/ /action/.amazonq/
|
COPY .amazonq/ /action/.amazonq/
|
||||||
|
COPY .codex/ /action/.codex/
|
||||||
COPY .claude/ /action/.claude/
|
COPY .claude/ /action/.claude/
|
||||||
COPY .gemini/ /action/.gemini/
|
COPY .gemini/ /action/.gemini/
|
||||||
COPY .github/ /action/.github/
|
COPY .github/ /action/.github/
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Use the triage-finding workflow for review issue lists:
|
|||||||
3. Sort by severity: `critical` -> `warning` -> `info`.
|
3. Sort by severity: `critical` -> `warning` -> `info`.
|
||||||
4. Renumber from 1.
|
4. Renumber from 1.
|
||||||
5. Fix real issues with the smallest safe change.
|
5. Fix real issues with the smallest safe change.
|
||||||
6. Put false positives into `.gitea/ai-review/exclusions.json`.
|
6. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
|
||||||
7. Add or update tests when behavior changes.
|
7. Add or update tests when behavior changes.
|
||||||
8. Re-check after each fix.
|
8. Re-check after each fix.
|
||||||
|
|
||||||
|
|||||||
@@ -227,4 +227,4 @@ Amazon Q:直接輸入 `triage-findings 問題原始檔(文字或截圖)`
|
|||||||
|
|
||||||
### 版本包含
|
### 版本包含
|
||||||
|
|
||||||
提交時一併包含 `triage-findings` skill 與各平台入口檔;已存在檔案一律覆蓋,同步到最新內容;若 workspace 沒有某個同步檔,記憶區會保留原檔,不做刪除。
|
提交時一併包含 `triage-findings` skill 與各平台入口檔;已存在檔案一律覆蓋,同步到最新內容;若 workspace 沒有某個同步檔,記憶區會保留原檔,不做刪除。寫入 `.gitea/ai-review/exclusions.json` 時,盡量保留原始問題文字的語言與語意,避免過度改寫。未來若新增任何 skill 或新增其他平台的 skill 入口,必須同時把對應檔案複製進 Docker image,並把同步清單更新到會使用此 action 的目標專案,避免 action 與目標專案內容脫節。
|
||||||
|
|||||||
@@ -40,13 +40,13 @@
|
|||||||
## 階段八:記憶區 commit/push 與錯誤處理
|
## 階段八:記憶區 commit/push 與錯誤處理
|
||||||
- 目標:記憶區能成功 commit/push,且一併包含 `triage-findings` skill 與各平台入口檔;skill 檔案已存在時一律以來源覆蓋,workspace 沒有的同步檔則保留記憶區既有內容,不做刪除;錯誤時有明確 log,流程結束有總結訊息。
|
- 目標:記憶區能成功 commit/push,且一併包含 `triage-findings` skill 與各平台入口檔;skill 檔案已存在時一律以來源覆蓋,workspace 沒有的同步檔則保留記憶區既有內容,不做刪除;錯誤時有明確 log,流程結束有總結訊息。
|
||||||
- 驗收:log 有「persisted findings」、「commit=...」、「push=...」等訊息,且能看出 skill 相關檔案已一併提交並被來源覆蓋;當 workspace 缺少某個同步檔時,記憶區中的對應檔案不會被刪除;錯誤時有「Runner failed: ...」等明確錯誤說明。
|
- 驗收:log 有「persisted findings」、「commit=...」、「push=...」等訊息,且能看出 skill 相關檔案已一併提交並被來源覆蓋;當 workspace 缺少某個同步檔時,記憶區中的對應檔案不會被刪除;錯誤時有「Runner failed: ...」等明確錯誤說明。
|
||||||
- 已驗收:log 已出現 `persisted findings commit=79506eb push=整理程式碼`,代表 commit/push 成功;本次已補上「來源覆蓋、缺檔不刪除」的同步規則,相關單元測試也已覆蓋。
|
- 已驗收:log 已出現 `persisted findings commit=b867eaa push=feat/解決問題`,代表 commit/push 成功;本次已補上「來源覆蓋、缺檔不刪除」的同步規則,相關單元測試也已覆蓋。
|
||||||
|
|
||||||
## 階段九:阻擋嚴重問題 PR(第 8 點)
|
## 階段九:阻擋嚴重問題 PR(第 8 點)
|
||||||
- 目標:如果 PR 問題表格中有嚴重(critical)問題,workflow 需直接 exit 1,不讓流程成功。
|
- 目標:如果 PR 問題表格中有嚴重(critical)問題,workflow 需直接 exit 1,不讓流程成功。
|
||||||
- 驗收:log 中能看到「critical 問題存在,workflow 結束(exit 1)」等明確訊息,且 workflow 狀態為失敗。
|
- 驗收:log 中能看到「critical 問題存在,workflow 結束(exit 1)」等明確訊息,且 workflow 狀態為失敗。
|
||||||
- 部分驗收:這次 log 顯示 `✅ 無嚴重問題`,因此只驗到正常放行路徑;`exit 1` 的阻擋分支仍需另一次含 critical 的 PR log 驗證。
|
- 已驗收:這次 log 已明確出現 `❌ 發現 2 個嚴重問題,workflow 結束(exit 1)`,且 job 以失敗結束,證明阻擋分支確實生效。
|
||||||
- 可驗收紀錄情境:只要 `Step8` 出現 `發現 X 個嚴重問題,workflow 結束(exit 1)`,且 job 以失敗結束,就能驗收這一項;如果該次 PR 的 `filtered` 清單含 `critical`,就應該會看到這段 log。
|
- 補充紀錄:`Step8` 的退出訊息屬於預期行為,不代表 Step7 commit/push 失敗。
|
||||||
|
|
||||||
## 階段十:API Key 輪替
|
## 階段十:API Key 輪替
|
||||||
- 目標:所有平台的 API Key 支援逗號分隔傳入多個,隨機順序各嘗試一次,單一 Key 失敗時自動換下一個,全部失敗則 exit 1。
|
- 目標:所有平台的 API Key 支援逗號分隔傳入多個,隨機順序各嘗試一次,單一 Key 失敗時自動換下一個,全部失敗則 exit 1。
|
||||||
|
|||||||
+7
-1
@@ -5,10 +5,12 @@ import { fileURLToPath } from 'url';
|
|||||||
import { GITEA_SERVER_URL, GITEA_REPOSITORY, GITEA_TOKEN, PR_HEAD_BRANCH, FINDINGS_PATH } from './config.js';
|
import { GITEA_SERVER_URL, GITEA_REPOSITORY, GITEA_TOKEN, PR_HEAD_BRANCH, FINDINGS_PATH } from './config.js';
|
||||||
|
|
||||||
const ACTION_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
const ACTION_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||||
|
const GENERATED_SYNC_PATHS = [FINDINGS_PATH, '.gitea/ai-review/exclusions.json'];
|
||||||
const remoteUrl = `${GITEA_SERVER_URL.replace(/\/$/, '')}/${GITEA_REPOSITORY}.git`;
|
const remoteUrl = `${GITEA_SERVER_URL.replace(/\/$/, '')}/${GITEA_REPOSITORY}.git`;
|
||||||
export const SYNC_PATHS = [
|
export const SYNC_PATHS = [
|
||||||
FINDINGS_PATH,
|
|
||||||
'.amazonq/rules/triage-findings.md',
|
'.amazonq/rules/triage-findings.md',
|
||||||
|
'.codex/skills/triage-findings/SKILL.md',
|
||||||
|
'.codex/skills/triage-findings/agents/openai.yaml',
|
||||||
'.claude/skills/triage-findings/SKILL.md',
|
'.claude/skills/triage-findings/SKILL.md',
|
||||||
'.gemini/skills/triage-findings/SKILL.md',
|
'.gemini/skills/triage-findings/SKILL.md',
|
||||||
'.github/copilot-instructions.md',
|
'.github/copilot-instructions.md',
|
||||||
@@ -84,6 +86,10 @@ export async function commitAndPush(workspace, repoDir, _spawnSync = spawnSync,
|
|||||||
if (existingSyncPaths.length > 0) {
|
if (existingSyncPaths.length > 0) {
|
||||||
run(['add', ...existingSyncPaths], repoDir);
|
run(['add', ...existingSyncPaths], repoDir);
|
||||||
}
|
}
|
||||||
|
const generatedSyncPaths = GENERATED_SYNC_PATHS.filter(relPath => fs.existsSync(path.join(repoDir, relPath)));
|
||||||
|
if (generatedSyncPaths.length > 0) {
|
||||||
|
run(['add', ...generatedSyncPaths], repoDir);
|
||||||
|
}
|
||||||
|
|
||||||
const status = run(['status', '--porcelain'], repoDir);
|
const status = run(['status', '--porcelain'], repoDir);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
|
|||||||
+21
-11
@@ -94,18 +94,28 @@ describe('commitAndPush', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds skill and entry files together with findings', async () => {
|
it('adds skill and entry files together with findings', async () => {
|
||||||
|
const repoDir = path.join(workspace, 'repo');
|
||||||
|
fs.mkdirSync(path.join(repoDir, '.gitea/ai-review'), { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(repoDir, '.gitea/ai-review/findings.json'), '[]\n');
|
||||||
|
fs.writeFileSync(path.join(repoDir, '.gitea/ai-review/exclusions.json'), '[]\n');
|
||||||
const spawn = makeSpawn();
|
const spawn = makeSpawn();
|
||||||
await commitAndPush(workspace, path.join(workspace, 'repo'), spawn, sourceRoot);
|
await commitAndPush(workspace, repoDir, spawn, sourceRoot);
|
||||||
const addCall = spawn.calls.find(c => c.args[0] === 'add');
|
const addCalls = spawn.calls.filter(c => c.args[0] === 'add');
|
||||||
assert.ok(addCall, 'expected git add to run');
|
const skillAddCall = addCalls.find(c => c.args.includes('.github/skills/triage-findings/SKILL.md'));
|
||||||
assert.ok(addCall.args.includes('.github/skills/triage-findings/SKILL.md'));
|
const generatedAddCall = addCalls.find(c => c.args.includes('.gitea/ai-review/exclusions.json'));
|
||||||
assert.ok(addCall.args.includes('.claude/skills/triage-findings/SKILL.md'));
|
assert.ok(skillAddCall, 'expected git add for synced skill files');
|
||||||
assert.ok(addCall.args.includes('.gemini/skills/triage-findings/SKILL.md'));
|
assert.ok(generatedAddCall, 'expected git add for generated review files');
|
||||||
assert.ok(addCall.args.includes('.github/copilot-instructions.md'));
|
assert.ok(skillAddCall.args.includes('.codex/skills/triage-findings/SKILL.md'));
|
||||||
assert.ok(addCall.args.includes('.amazonq/rules/triage-findings.md'));
|
assert.ok(skillAddCall.args.includes('.codex/skills/triage-findings/agents/openai.yaml'));
|
||||||
assert.ok(addCall.args.includes('CLAUDE.md'));
|
assert.ok(skillAddCall.args.includes('.claude/skills/triage-findings/SKILL.md'));
|
||||||
assert.ok(addCall.args.includes('GEMINI.md'));
|
assert.ok(skillAddCall.args.includes('.gemini/skills/triage-findings/SKILL.md'));
|
||||||
assert.ok(!addCall.args.includes('README.md'));
|
assert.ok(skillAddCall.args.includes('.github/copilot-instructions.md'));
|
||||||
|
assert.ok(skillAddCall.args.includes('.amazonq/rules/triage-findings.md'));
|
||||||
|
assert.ok(skillAddCall.args.includes('CLAUDE.md'));
|
||||||
|
assert.ok(skillAddCall.args.includes('GEMINI.md'));
|
||||||
|
assert.ok(!skillAddCall.args.includes('README.md'));
|
||||||
|
assert.ok(generatedAddCall.args.includes('.gitea/ai-review/findings.json'));
|
||||||
|
assert.ok(generatedAddCall.args.includes('.gitea/ai-review/exclusions.json'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('keeps repo copies when the source sync file is missing', async () => {
|
it('keeps repo copies when the source sync file is missing', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user