quality: enforce typhon source LOC hygiene in CI
This commit is contained in:
parent
5384958aca
commit
9e039e34c5
47
Jenkinsfile
vendored
47
Jenkinsfile
vendored
@ -122,6 +122,7 @@ spec:
|
|||||||
|
|
||||||
node <<'NODE'
|
node <<'NODE'
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
const junitPath = 'build/junit-typhon.xml';
|
const junitPath = 'build/junit-typhon.xml';
|
||||||
const coveragePath = 'coverage/coverage-summary.json';
|
const coveragePath = 'coverage/coverage-summary.json';
|
||||||
@ -143,6 +144,44 @@ const skipped = Number((junit.match(/skipped="([0-9]+)"/) || [])[1] || 0);
|
|||||||
|
|
||||||
const cov = JSON.parse(fs.readFileSync(coveragePath, 'utf8'));
|
const cov = JSON.parse(fs.readFileSync(coveragePath, 'utf8'));
|
||||||
const total = cov.total || {};
|
const total = cov.total || {};
|
||||||
|
const sourceRoots = ['src', 'tests', 'scripts'];
|
||||||
|
const sourceExts = new Set(['.ts', '.js', '.cjs', '.mjs', '.sh']);
|
||||||
|
const maxSourceLines = 500;
|
||||||
|
|
||||||
|
function collectOverLimitFiles(rootDir) {
|
||||||
|
const offenders = [];
|
||||||
|
const stack = [rootDir];
|
||||||
|
while (stack.length > 0) {
|
||||||
|
const current = stack.pop();
|
||||||
|
if (!fs.existsSync(current)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
||||||
|
const fullPath = path.join(current, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
stack.push(fullPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!sourceExts.has(path.extname(entry.name))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const lines = fs.readFileSync(fullPath, 'utf8').split(/\\r?\\n/).length;
|
||||||
|
if (lines > maxSourceLines) {
|
||||||
|
offenders.push({ file: fullPath, lines });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return offenders;
|
||||||
|
}
|
||||||
|
|
||||||
|
const overLimitFiles = sourceRoots.flatMap((root) => collectOverLimitFiles(root));
|
||||||
|
if (overLimitFiles.length > 0) {
|
||||||
|
console.error('source files exceed 500 LOC:');
|
||||||
|
for (const item of overLimitFiles) {
|
||||||
|
console.error(`- ${item.file}: ${item.lines}`);
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
const report = {
|
const report = {
|
||||||
suite: 'typhon',
|
suite: 'typhon',
|
||||||
@ -158,6 +197,9 @@ const report = {
|
|||||||
statements: 85,
|
statements: 85,
|
||||||
functions: 85,
|
functions: 85,
|
||||||
branches: 75
|
branches: 75
|
||||||
|
},
|
||||||
|
hygiene: {
|
||||||
|
sourceLinesOver500: overLimitFiles.length
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,6 +229,7 @@ if (!fs.existsSync(qualityPath)) {
|
|||||||
|
|
||||||
const quality = JSON.parse(fs.readFileSync(qualityPath, 'utf8'));
|
const quality = JSON.parse(fs.readFileSync(qualityPath, 'utf8'));
|
||||||
const status = quality.tests.failures > 0 || quality.tests.errors > 0 ? 'failed' : 'ok';
|
const status = quality.tests.failures > 0 || quality.tests.errors > 0 ? 'failed' : 'ok';
|
||||||
|
const sourceLinesOver500 = Number(quality.hygiene?.sourceLinesOver500 ?? 0);
|
||||||
|
|
||||||
function fetchCounter(targetStatus) {
|
function fetchCounter(targetStatus) {
|
||||||
try {
|
try {
|
||||||
@ -219,6 +262,10 @@ const payload = [
|
|||||||
`typhon_quality_gate_coverage_percent{suite="${suite}",scope="statements"} ${quality.coverage.statements}`,
|
`typhon_quality_gate_coverage_percent{suite="${suite}",scope="statements"} ${quality.coverage.statements}`,
|
||||||
`typhon_quality_gate_coverage_percent{suite="${suite}",scope="functions"} ${quality.coverage.functions}`,
|
`typhon_quality_gate_coverage_percent{suite="${suite}",scope="functions"} ${quality.coverage.functions}`,
|
||||||
`typhon_quality_gate_coverage_percent{suite="${suite}",scope="branches"} ${quality.coverage.branches}`,
|
`typhon_quality_gate_coverage_percent{suite="${suite}",scope="branches"} ${quality.coverage.branches}`,
|
||||||
|
'# TYPE platform_quality_gate_workspace_line_coverage_percent gauge',
|
||||||
|
`platform_quality_gate_workspace_line_coverage_percent{suite="${suite}"} ${quality.coverage.lines}`,
|
||||||
|
'# TYPE platform_quality_gate_source_lines_over_500_total gauge',
|
||||||
|
`platform_quality_gate_source_lines_over_500_total{suite="${suite}"} ${sourceLinesOver500}`,
|
||||||
''
|
''
|
||||||
].join('\\n');
|
].join('\\n');
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user