Files
SubMiner/src/quality-gate-workflow.test.ts
T

90 lines
4.1 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { existsSync, readFileSync } from 'node:fs';
import { resolve } from 'node:path';
const qualityGateWorkflowPath = resolve(__dirname, '../.github/workflows/quality-gate.yml');
const qualityGateWorkflow = existsSync(qualityGateWorkflowPath)
? readFileSync(qualityGateWorkflowPath, 'utf8').replace(/\r\n/g, '\n')
: '';
const verificationDocPath = resolve(__dirname, '../docs/workflow/verification.md');
const verificationDoc = readFileSync(verificationDocPath, 'utf8').replace(/\r\n/g, '\n');
test('quality gate is a reusable workflow', () => {
assert.match(qualityGateWorkflow, /on:\s*\n\s*workflow_call:/);
assert.match(qualityGateWorkflow, /permissions:\s*\n\s*contents: read/);
});
test('quality gate checkout does not persist GitHub credentials', () => {
assert.match(
qualityGateWorkflow,
/uses: actions\/checkout@v4[\s\S]*?fetch-depth: 0[\s\S]*?submodules: true[\s\S]*?persist-credentials: false/,
);
});
test('quality gate runs non-covered source suites and lets coverage gate the src lane', () => {
assert.match(qualityGateWorkflow, /name: Install Lua/);
assert.match(
qualityGateWorkflow,
/apt_sources=\(-o Dir::Etc::sourcelist=sources\.list\.d\/ubuntu\.sources -o Dir::Etc::sourceparts=-\)/,
);
assert.match(qualityGateWorkflow, /apt-get\s+"\$\{apt_sources\[@\]\}"\s+update/);
assert.match(qualityGateWorkflow, /apt-get\s+"\$\{apt_sources\[@\]\}"\s+install\s+-y\s+lua5\.4/);
assert.match(
qualityGateWorkflow,
/Launcher unit and script suites\n\s*run: bun run test:launcher:unit:src && bun run test:scripts/,
);
assert.doesNotMatch(qualityGateWorkflow, /bun run test:fast/);
assert.match(qualityGateWorkflow, /run: bun run test:coverage:src/);
});
test('quality gate runs launcher smoke once through the environment suite and keeps artifacts', () => {
assert.match(qualityGateWorkflow, /name: Environment suite\n\s*run: bun run test:env/);
assert.doesNotMatch(qualityGateWorkflow, /run: bun run test:launcher:smoke:src/);
assert.match(
qualityGateWorkflow,
/name: Upload launcher smoke artifacts \(on failure\)[\s\S]*?if: failure\(\)[\s\S]*?path: \.tmp\/launcher-smoke\/\*\*/,
);
});
test('quality gate uploads maintained source coverage', () => {
assert.match(qualityGateWorkflow, /run: bun run test:coverage:src/);
assert.match(qualityGateWorkflow, /name: Upload coverage artifact/);
assert.match(qualityGateWorkflow, /path: coverage\/test-src\/lcov\.info/);
});
test('quality gate preserves stats, compiled SQLite, and dist runtime checks', () => {
assert.match(qualityGateWorkflow, /run: bun run test:stats/);
assert.match(qualityGateWorkflow, /run: bun run build/);
assert.match(qualityGateWorkflow, /run: bun run test:immersion:sqlite:dist/);
assert.match(qualityGateWorkflow, /run: bun run test:smoke:dist/);
});
test('quality gate keeps pull request changelog enforcement event-aware', () => {
assert.match(qualityGateWorkflow, /bun run changelog:lint/);
assert.match(qualityGateWorkflow, /if: github\.event_name == 'pull_request'/);
assert.match(
qualityGateWorkflow,
/env:\s*\n\s*BASE_REF: \${{ github\.base_ref }}\s*\n\s*PR_LABELS: \${{ join\(github\.event\.pull_request\.labels\.\*\.name, ','\) }}\s*\n\s*run: bun run changelog:pr-check --base-ref "origin\/\$BASE_REF" --head-ref "HEAD" --labels "\$PR_LABELS"/,
);
assert.match(qualityGateWorkflow, /skip-changelog/);
});
test('quality gate verifies generated config examples', () => {
assert.match(qualityGateWorkflow, /bun run verify:config-example/);
});
test('quality gate blocks on high-severity audit findings', () => {
const securityAuditStep =
qualityGateWorkflow.match(/- name: Security audit[\s\S]*?(?=\n {6}- name:|\n?$)/)?.[0] ?? '';
const dependencyAuditPolicySection =
verificationDoc.match(/## Dependency Audit Policy[\s\S]*?(?=\n## |\n?$)/)?.[0] ?? '';
assert.match(securityAuditStep, /run: bun audit --audit-level high/);
assert.doesNotMatch(securityAuditStep, /continue-on-error: true/);
assert.match(
dependencyAuditPolicySection,
/`bun audit --audit-level high` blocks the reusable quality gate/,
);
});