| name | quality-gates-enforcer |
| description | Enforces minimum quality thresholds in CI including code coverage, linting, type checking, and security scanning. Provides required checks, PR rules, and automated enforcement. Use for "quality gates", "CI checks", "code quality", or "PR requirements". |
Quality Gates Enforcer
Enforce minimum quality standards before merging code.
Coverage Requirements
# .github/workflows/quality-gates.yml
name: Quality Gates
on:
pull_request:
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: Run tests with coverage
run: npm test -- --coverage
- name: Check coverage threshold
run: |
COVERAGE=$(node -p "require('./coverage/coverage-summary.json').total.lines.pct")
THRESHOLD=80
if (( $(echo "$COVERAGE < $THRESHOLD" | bc -l) )); then
echo "❌ Coverage $COVERAGE% is below threshold $THRESHOLD%"
exit 1
fi
echo "✅ Coverage $COVERAGE% meets threshold $THRESHOLD%"
- name: Comment coverage on PR
uses: romeovs/lcov-reporter-action@v0.3.1
with:
lcov-file: ./coverage/lcov.info
github-token: ${{ secrets.GITHUB_TOKEN }}
delete-old-comments: true
Jest Configuration
// jest.config.js
module.exports = {
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
"./src/critical/": {
branches: 90,
functions: 90,
lines: 90,
statements: 90,
},
},
};
Linting Gate
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: Run ESLint
run: npm run lint -- --max-warnings 0
- name: Check formatting
run: npm run format:check
Type Checking Gate
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: TypeScript check
run: npx tsc --noEmit
Security Scanning
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Snyk security scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
- name: Audit dependencies
run: npm audit --audit-level=moderate
- name: Check for outdated dependencies
run: |
OUTDATED=$(npm outdated || true)
if [ ! -z "$OUTDATED" ]; then
echo "⚠️ Outdated dependencies found:"
echo "$OUTDATED"
fi
Bundle Size Gate
bundle-size:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- run: npm run build
- name: Check bundle size
uses: andresz1/size-limit-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
skip_step: install
Required Status Checks
# .github/workflows/required-checks.yml
name: Required Checks
on:
pull_request:
jobs:
required:
runs-on: ubuntu-latest
needs: [lint, typecheck, test, coverage, security]
if: always()
steps:
- name: Check all required jobs passed
run: |
if [ "${{ contains(needs.*.result, 'failure') }}" == "true" ]; then
echo "❌ Required checks failed"
exit 1
fi
echo "✅ All required checks passed"
Quality Thresholds
// quality-thresholds.ts
export const QUALITY_GATES = {
coverage: {
lines: 80,
branches: 80,
functions: 80,
statements: 80,
},
linting: {
maxWarnings: 0,
maxErrors: 0,
},
bundleSize: {
maxSize: "200kb",
maxGzipSize: "100kb",
},
performance: {
maxLighthouseScore: 90,
},
security: {
maxVulnerabilities: 0,
maxSeverity: "moderate",
},
dependencies: {
maxOutdated: 5,
},
};
Branch Protection Rules
# Configure via GitHub settings or API
{
"required_status_checks":
{
"strict": true,
"contexts":
["lint", "typecheck", "test", "coverage", "security", "bundle-size"],
},
"required_pull_request_reviews":
{
"required_approving_review_count": 1,
"dismiss_stale_reviews": true,
"require_code_owner_reviews": true,
},
"enforce_admins": true,
"restrictions": null,
}
Quality Report
- name: Generate quality report
run: |
cat > quality-report.md << EOF
# Quality Report
## Coverage
- Lines: $(node -p "require('./coverage/coverage-summary.json').total.lines.pct")%
- Branches: $(node -p "require('./coverage/coverage-summary.json').total.branches.pct")%
- Functions: $(node -p "require('./coverage/coverage-summary.json').total.functions.pct")%
## Linting
- ESLint warnings: $(npm run lint 2>&1 | grep -c warning || echo 0)
- ESLint errors: $(npm run lint 2>&1 | grep -c error || echo 0)
## Type Safety
- TypeScript errors: $(npx tsc --noEmit 2>&1 | grep -c error || echo 0)
## Security
- Vulnerabilities: $(npm audit --json | jq '.metadata.vulnerabilities.total')
## Bundle Size
- Main bundle: $(ls -lh dist/main.js | awk '{print $5}')
EOF
- name: Comment report on PR
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('quality-report.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: report
});
Auto-fail on Thresholds
- name: Check all quality gates
run: |
EXIT_CODE=0
# Coverage
COVERAGE=$(node -p "require('./coverage/coverage-summary.json').total.lines.pct")
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "❌ Coverage below 80%"
EXIT_CODE=1
fi
# Lint warnings
WARNINGS=$(npm run lint 2>&1 | grep -c warning || echo 0)
if [ "$WARNINGS" -gt 0 ]; then
echo "❌ Found $WARNINGS lint warnings"
EXIT_CODE=1
fi
# TypeScript errors
if ! npx tsc --noEmit; then
echo "❌ TypeScript errors found"
EXIT_CODE=1
fi
# Security vulnerabilities
if ! npm audit --audit-level=moderate; then
echo "❌ Security vulnerabilities found"
EXIT_CODE=1
fi
exit $EXIT_CODE
Best Practices
- Strict thresholds: No compromises on quality
- Fast feedback: Run checks early in CI
- Clear messages: Explain why checks failed
- Incremental improvement: Gradually increase thresholds
- Bypass mechanism: For emergencies only
- Local pre-commit: Catch issues before push
- Team agreement: Align on standards
Output Checklist
- Coverage threshold enforced (80%+)
- Linting with zero warnings
- Type checking required
- Security scanning enabled
- Bundle size checks
- Branch protection rules
- Quality report generated
- PR comments automated