Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,29 @@ jobs:
cache-version: v1

- name: Enforce critical and global coverage thresholds
run: npm run test:coverage
run: |
set -o pipefail
mkdir -p coverage
npm run test:coverage 2>&1 | tee coverage/coverage-gate.log

- name: Summarize coverage gate
if: always()
run: |
{
echo "### Coverage gate"
echo
echo "Command: \`npm run test:coverage\`"
echo
echo "Critical-module and global coverage thresholds are enforced by this required job."
echo
echo "\`\`\`text"
if [ -f coverage/coverage-gate.log ]; then
tail -n 120 coverage/coverage-gate.log
else
echo "coverage/coverage-gate.log was not created."
fi
echo "\`\`\`"
} >> "$GITHUB_STEP_SUMMARY"

mutation-baseline:
name: Mutation Baseline (Advisory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,23 @@ describe('quality workflow Node compatibility contract', () => {
expect(setupNodeStep.uses).toBe(lockedInstallActionPath);
expect(setupNodeStep.with.get('node-version')).toBe('22');
expect(setupNodeStep.with.get('cache-namespace')).toBe('coverage');
expect(
getWorkflowStep(coverageJob, 'Enforce critical and global coverage thresholds').run,
).toBe('npm run test:coverage');
expectTextIncludes(
getWorkflowStep(coverageJob, 'Enforce critical and global coverage thresholds').run ?? '',
{
text: 'npm run test:coverage 2>&1 | tee coverage/coverage-gate.log',
rationale: 'Coverage gate must preserve threshold output for actionable job summaries.',
},
);
const summaryStep = getWorkflowStep(coverageJob, 'Summarize coverage gate');
expect(summaryStep.if).toBe('always()');
expectTextIncludes(summaryStep.run ?? '', {
text: 'GITHUB_STEP_SUMMARY',
rationale: 'Coverage gate must publish a summary even after threshold failures.',
});
expectTextIncludes(summaryStep.run ?? '', {
text: 'coverage/coverage-gate.log',
rationale: 'Coverage summary must identify the module/floor output that failed.',
});
});

it('makes Redis integration and guarded self-heal proof mandatory in quality gates', () => {
Expand Down