refactor(ai-review 統計): 精簡 action log 統計輸出
This commit is contained in:
+9
-4
@@ -77,6 +77,13 @@ export function formatFindingsStats(findings) {
|
|||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function formatFindingsStatsLine(findings) {
|
||||||
|
const oldFindings = findings.filter(f => f.is_new === false);
|
||||||
|
const newFindings = newFindingsOnly(findings);
|
||||||
|
const row = items => `嚴重${countBy(items, f => f.level === 'critical')} / 警告${countBy(items, f => f.level === 'warning')} / 建議${countBy(items, f => f.level === 'info')}`;
|
||||||
|
return `舊: ${row(oldFindings)};新: ${row(newFindings)}`;
|
||||||
|
}
|
||||||
|
|
||||||
function buildReviewSummary(findings) {
|
function buildReviewSummary(findings) {
|
||||||
return [
|
return [
|
||||||
'## AI Code Review 統計',
|
'## AI Code Review 統計',
|
||||||
@@ -111,10 +118,8 @@ export async function postFindingsReview(findings, deps = {}) {
|
|||||||
const body = buildReviewSummary(summaryFindings);
|
const body = buildReviewSummary(summaryFindings);
|
||||||
await postReview({ body, comments });
|
await postReview({ body, comments });
|
||||||
ok(`review 發布: summary=${summaryFindings.length} total=${sortedComments.length} commentable=${comments.length}`);
|
ok(`review 發布: summary=${summaryFindings.length} total=${sortedComments.length} commentable=${comments.length}`);
|
||||||
line('review summary 統計:');
|
line(`review summary 統計: ${formatFindingsStatsLine(summaryFindings)}`);
|
||||||
for (const row of formatFindingsStats(summaryFindings).split('\n')) line(row);
|
line(`review comments 統計: ${formatFindingsStatsLine(sortedComments)}`);
|
||||||
line('review comments 統計:');
|
|
||||||
for (const row of formatFindingsStats(sortedComments).split('\n')) line(row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+13
-4
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview, formatFindingsStats } from './comments.js';
|
import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview, formatFindingsStats, formatFindingsStatsLine } from './comments.js';
|
||||||
import { FINDINGS_PATH } from './config.js';
|
import { FINDINGS_PATH } from './config.js';
|
||||||
|
|
||||||
describe('saveFindings', () => {
|
describe('saveFindings', () => {
|
||||||
@@ -97,13 +97,15 @@ describe('parseLocation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('formatFindingsStats', () => {
|
describe('formatFindingsStats', () => {
|
||||||
it('formats old and new findings by severity', () => {
|
const statsFindings = [
|
||||||
const stats = formatFindingsStats([
|
|
||||||
{ level: 'critical', is_new: false },
|
{ level: 'critical', is_new: false },
|
||||||
{ level: 'warning', is_new: true },
|
{ level: 'warning', is_new: true },
|
||||||
{ level: 'info' },
|
{ level: 'info' },
|
||||||
{ level: 'custom', is_new: true },
|
{ level: 'custom', is_new: true },
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
it('formats old and new findings by severity', () => {
|
||||||
|
const stats = formatFindingsStats(statsFindings);
|
||||||
|
|
||||||
assert.equal(stats, [
|
assert.equal(stats, [
|
||||||
'| 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 |',
|
'| 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 |',
|
||||||
@@ -112,6 +114,13 @@ describe('formatFindingsStats', () => {
|
|||||||
'| 新問題 | 0 筆 | 1 筆 | 1 筆 |',
|
'| 新問題 | 0 筆 | 1 筆 | 1 筆 |',
|
||||||
].join('\n'));
|
].join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('formats compact one-line stats for action logs', () => {
|
||||||
|
assert.equal(
|
||||||
|
formatFindingsStatsLine(statsFindings),
|
||||||
|
'舊: 嚴重1 / 警告0 / 建議0;新: 嚴重0 / 警告1 / 建議1',
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('postNewCriticalComments', () => {
|
describe('postNewCriticalComments', () => {
|
||||||
|
|||||||
+2
-3
@@ -3,7 +3,7 @@ import { GITEA_REPOSITORY, PR_NUMBER, PR_HEAD_BRANCH, PR_BASE_BRANCH, getLLMConf
|
|||||||
import { loadRoles, getRoleIntro } from './roles.js';
|
import { loadRoles, getRoleIntro } from './roles.js';
|
||||||
import { getPRDiff, postComment, getCommitMessageBySha, getBotReviewOutcome, shouldSkipBotCommit } from './gitea.js';
|
import { getPRDiff, postComment, getCommitMessageBySha, getBotReviewOutcome, shouldSkipBotCommit } 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, postFindingsReview, formatFindingsStats } from './comments.js';
|
import { saveFindings, postFindingsReview, formatFindingsStatsLine } from './comments.js';
|
||||||
import { cloneRepo, commitAndPush, getRepoState } from './git.js';
|
import { cloneRepo, commitAndPush, getRepoState } from './git.js';
|
||||||
import { validateJSONArrayFile, ensureJSONArrayFileExists } from './json.js';
|
import { validateJSONArrayFile, ensureJSONArrayFileExists } from './json.js';
|
||||||
import { runPreflight } from './preflight.js';
|
import { runPreflight } from './preflight.js';
|
||||||
@@ -12,8 +12,7 @@ import { section, step, line, ok, warn, error } from './log.js';
|
|||||||
const WORKSPACE = process.env.GITHUB_WORKSPACE || '/workspace';
|
const WORKSPACE = process.env.GITHUB_WORKSPACE || '/workspace';
|
||||||
|
|
||||||
function logFindingsStats(label, findings) {
|
function logFindingsStats(label, findings) {
|
||||||
line(`${label}:`);
|
line(`${label}: ${formatFindingsStatsLine(findings)}`);
|
||||||
for (const row of formatFindingsStats(findings).split('\n')) line(row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user