63 lines
1.8 KiB
JavaScript
63 lines
1.8 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Coverage Trend Script
|
||
|
|
*
|
||
|
|
* Reads Vitest coverage summary and appends to a JSON trend file.
|
||
|
|
* Usage: node scripts/coverage-trend.mjs [coverage-summary.json] [trend-output.json]
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
||
|
|
|
||
|
|
const summaryPath = process.argv[2] || 'apps/web/coverage/coverage-summary.json';
|
||
|
|
const trendPath = process.argv[3] || 'coverage-trend.json';
|
||
|
|
|
||
|
|
function readTrend() {
|
||
|
|
if (existsSync(trendPath)) {
|
||
|
|
return JSON.parse(readFileSync(trendPath, 'utf8'));
|
||
|
|
}
|
||
|
|
return { entries: [] };
|
||
|
|
}
|
||
|
|
|
||
|
|
function extractCoverage(summaryPath) {
|
||
|
|
if (!existsSync(summaryPath)) {
|
||
|
|
console.error(`Coverage summary not found: ${summaryPath}`);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const summary = JSON.parse(readFileSync(summaryPath, 'utf8'));
|
||
|
|
const total = summary.total || {};
|
||
|
|
|
||
|
|
return {
|
||
|
|
date: new Date().toISOString().split('T')[0],
|
||
|
|
commit: process.env.GITHUB_SHA?.slice(0, 7) || 'local',
|
||
|
|
lines: total.lines?.pct ?? 0,
|
||
|
|
branches: total.branches?.pct ?? 0,
|
||
|
|
functions: total.functions?.pct ?? 0,
|
||
|
|
statements: total.statements?.pct ?? 0,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
const coverage = extractCoverage(summaryPath);
|
||
|
|
if (coverage) {
|
||
|
|
const trend = readTrend();
|
||
|
|
|
||
|
|
// Keep last 100 entries
|
||
|
|
trend.entries.push(coverage);
|
||
|
|
if (trend.entries.length > 100) {
|
||
|
|
trend.entries = trend.entries.slice(-100);
|
||
|
|
}
|
||
|
|
|
||
|
|
writeFileSync(trendPath, JSON.stringify(trend, null, 2));
|
||
|
|
console.log(`Coverage trend updated: lines=${coverage.lines}%, branches=${coverage.branches}%`);
|
||
|
|
|
||
|
|
// Check for regression (> 2% drop from last entry)
|
||
|
|
if (trend.entries.length >= 2) {
|
||
|
|
const prev = trend.entries[trend.entries.length - 2];
|
||
|
|
const linesDrop = prev.lines - coverage.lines;
|
||
|
|
if (linesDrop > 2) {
|
||
|
|
console.warn(`WARNING: Line coverage dropped ${linesDrop.toFixed(1)}% (${prev.lines}% -> ${coverage.lines}%)`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|