Skip to content

refactor: Decompose 6 mega-files into 13 focused modules, remove lega… #92

refactor: Decompose 6 mega-files into 13 focused modules, remove lega…

refactor: Decompose 6 mega-files into 13 focused modules, remove lega… #92

Workflow file for this run

name: Quality Gates
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
quality-gates:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: TypeScript compilation
run: |
echo "::group::TypeScript Compilation"
npm run build
echo "::endgroup::"
- name: Lint check
run: |
echo "::group::ESLint"
npm run lint || echo "::warning::ESLint found issues"
echo "::endgroup::"
- name: Type safety validation
run: |
echo "::group::Type Safety"
npx vitest run src/test/quality/type-safety.test.ts
echo "::endgroup::"
- name: Run tests with coverage
run: |
echo "::group::Test Suite"
npm run test -- --coverage --run
echo "::endgroup::"
- name: Coverage enforcement
run: |
echo "::group::Coverage Check"
# Vitest will fail if coverage thresholds not met
if [ -f coverage/coverage-summary.json ]; then
LINES=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
STATEMENTS=$(cat coverage/coverage-summary.json | jq '.total.statements.pct')
FUNCTIONS=$(cat coverage/coverage-summary.json | jq '.total.functions.pct')
BRANCHES=$(cat coverage/coverage-summary.json | jq '.total.branches.pct')
echo "Coverage Results:"
echo " Lines: $LINES%"
echo " Statements: $STATEMENTS%"
echo " Functions: $FUNCTIONS%"
echo " Branches: $BRANCHES%"
# Quality gate: minimum 85% coverage
if (( $(echo "$LINES < 85" | bc -l) )); then
echo "::error::Line coverage $LINES% is below 85% threshold"
exit 1
fi
if (( $(echo "$STATEMENTS < 85" | bc -l) )); then
echo "::error::Statement coverage $STATEMENTS% is below 85% threshold"
exit 1
fi
else
echo "::warning::No coverage report found"
fi
echo "::endgroup::"
- name: Security audit
run: |
echo "::group::Security Audit"
npx tsx src/test/reports/security-audit.ts
# Check for critical security issues
if [ -f .claude/reports/security-audit.json ]; then
CRITICAL=$(cat .claude/reports/security-audit.json | jq '.summary.violations.critical')
HIGH=$(cat .claude/reports/security-audit.json | jq '.summary.violations.high')
SCORE=$(cat .claude/reports/security-audit.json | jq '.summary.overallScore')
echo "Security Score: $SCORE/100"
echo "Critical Issues: $CRITICAL"
echo "High Issues: $HIGH"
# Quality gate: no critical issues, score >= 70
if [ "$CRITICAL" -gt 0 ]; then
echo "::error::Found $CRITICAL critical security issues"
exit 1
fi
if [ "$HIGH" -gt 5 ]; then
echo "::error::Found $HIGH high security issues (max 5 allowed)"
exit 1
fi
if (( $(echo "$SCORE < 70" | bc -l) )); then
echo "::error::Security score $SCORE is below 70 threshold"
exit 1
fi
fi
echo "::endgroup::"
- name: Performance tests
run: |
echo "::group::Performance Tests"
npx vitest run src/test/performance/performance.test.ts
echo "::endgroup::"
- name: Integration tests
run: |
echo "::group::Integration Tests"
npx vitest run src/test/integration/
echo "::endgroup::"
- name: Generate quality metrics
run: |
echo "::group::Quality Metrics"
npx tsx src/test/reports/quality-dashboard.ts
if [ -f .claude/reports/quality-metrics.json ]; then
GRADE=$(cat .claude/reports/quality-metrics.json | jq -r '.overallGrade')
SCORE=$(cat .claude/reports/quality-metrics.json | jq '.overallScore')
echo "Overall Grade: $GRADE"
echo "Overall Score: $SCORE/100"
# Quality gate: minimum grade B (80+)
if [ "$GRADE" == "C" ] || [ "$GRADE" == "D" ] || [ "$GRADE" == "F" ]; then
echo "::warning::Quality grade $GRADE is below B threshold"
fi
fi
echo "::endgroup::"
- name: Upload coverage reports
uses: codecov/codecov-action@v3
if: always()
with:
files: ./coverage/lcov.info
flags: unittests
name: codecov-nxtg-forge
- name: Upload quality reports
uses: actions/upload-artifact@v3
if: always()
with:
name: quality-reports
path: |
.claude/reports/
coverage/
- name: Comment PR with quality metrics
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let comment = '## Quality Gates Report\n\n';
// Coverage
if (fs.existsSync('coverage/coverage-summary.json')) {
const coverage = JSON.parse(fs.readFileSync('coverage/coverage-summary.json', 'utf8'));
comment += '### Test Coverage\n';
comment += `- Lines: ${coverage.total.lines.pct}%\n`;
comment += `- Statements: ${coverage.total.statements.pct}%\n`;
comment += `- Functions: ${coverage.total.functions.pct}%\n`;
comment += `- Branches: ${coverage.total.branches.pct}%\n\n`;
}
// Security
if (fs.existsSync('.claude/reports/security-audit.json')) {
const security = JSON.parse(fs.readFileSync('.claude/reports/security-audit.json', 'utf8'));
comment += '### Security Audit\n';
comment += `- Score: ${security.summary.overallScore}/100\n`;
comment += `- Critical: ${security.summary.violations.critical}\n`;
comment += `- High: ${security.summary.violations.high}\n`;
comment += `- Medium: ${security.summary.violations.medium}\n\n`;
}
// Quality Metrics
if (fs.existsSync('.claude/reports/quality-metrics.json')) {
const quality = JSON.parse(fs.readFileSync('.claude/reports/quality-metrics.json', 'utf8'));
comment += '### Overall Quality\n';
comment += `- Grade: ${quality.overallGrade}\n`;
comment += `- Score: ${quality.overallScore}/100\n\n`;
}
// Status
comment += '### Status\n';
comment += process.env.GITHUB_WORKFLOW_CONCLUSION === 'success'
? '✅ All quality gates passed!\n'
: '❌ Some quality gates failed. Please review the logs.\n';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
- name: Quality gate summary
if: always()
run: |
echo "::notice::Quality Gates Complete"
echo "See artifacts for detailed reports"