--- id: wiki-2026-0508-quality-gates title: Quality Gates category: 10_Wiki/Topics status: verified canonical_id: self aliases: [CI Gates, Merge Gates, Pipeline Gates] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [ci-cd, devops, code-quality, security] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: YAML/Shell framework: GitHub-Actions/SonarQube --- # Quality Gates ## 매 한 줄 > **"매 fail-fast checkpoint between commit and production"**. 1990s ISO 9000 의 stage-gate 의 software 의 응용. 매 modern CI/CD 에서 매 PR merge / deploy 의 block 하는 자동 check 의 set. 매 SonarQube 가 popularized — coverage + bugs + smells + security 의 threshold-based gate. ## 매 핵심 ### 매 layer (commit → prod) - **Pre-commit (local)**: format, lint, secrets scan. - **PR gate**: build, unit test, coverage, security scan, type check. - **Merge gate**: full integration test, mutation test (선택). - **Pre-deploy**: smoke test, perf budget, manual approval. - **Post-deploy**: canary metrics, error rate, SLO. ### 매 dimensions - **Correctness**: tests pass, type-check. - **Coverage**: line / branch / mutation %. - **Style**: lint, format. - **Security**: SAST, dep scan, secret scan, license. - **Performance**: benchmark regression, bundle size. - **Docs**: changelog, ADR for breaking change. ### 매 응용 1. Open-source PR review automation. 2. Regulated industry (SOX, HIPAA) audit trail. 3. Monorepo platform consistency. 4. AI-generated code 의 sanity gate. 5. Deploy promotion. ## 💻 패턴 ### Pre-commit (local) ```yaml # .pre-commit-config.yaml repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.8.0 hooks: [{id: ruff}, {id: ruff-format}] - repo: https://github.com/gitleaks/gitleaks rev: v8.21.0 hooks: [{id: gitleaks}] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.13.0 hooks: [{id: mypy}] ``` ### GitHub Actions PR gate ```yaml name: PR Gate on: [pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v3 - run: uv sync - run: uv run pytest --cov=src --cov-report=xml --cov-fail-under=80 - run: uv run ruff check . - run: uv run mypy src - uses: codecov/codecov-action@v5 security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: aquasecurity/trivy-action@master with: {scan-type: fs, severity: 'HIGH,CRITICAL', exit-code: 1} - uses: github/codeql-action/init@v3 - uses: github/codeql-action/analyze@v3 ``` ### SonarQube quality gate (Sonar Way) ``` - Coverage on new code ≥ 80% - Duplicated lines on new code ≤ 3% - Maintainability rating on new code = A - Reliability rating on new code = A - Security rating on new code = A - Security hotspots reviewed = 100% ``` ### Branch protection (GitHub API) ```bash gh api -X PUT "repos/{owner}/{repo}/branches/main/protection" \ -F required_status_checks[strict]=true \ -F required_status_checks[contexts][]=test \ -F required_status_checks[contexts][]=security \ -F required_pull_request_reviews[required_approving_review_count]=2 \ -F enforce_admins=true ``` ### Performance budget gate ```yaml - name: Bundle size check run: | npm run build SIZE=$(stat -c%s dist/main.js) if [ $SIZE -gt 250000 ]; then echo "Bundle exceeds 250KB budget: $SIZE" exit 1 fi ``` ### Mutation testing gate (Stryker / mutmut) ```yaml - run: uv run mutmut run - run: | SCORE=$(uv run mutmut results | grep -oP 'killed.*\K\d+') if [ $SCORE -lt 70 ]; then exit 1; fi ``` ### Canary deploy gate ```yaml - name: Canary 5% run: kubectl set image deploy/app app=app:${{ github.sha }} --namespace=canary - name: Wait + check SLO run: | sleep 600 ERROR_RATE=$(prom_query 'rate(http_5xx[10m])') if (( $(echo "$ERROR_RATE > 0.01" | bc -l) )); then kubectl rollout undo deploy/app --namespace=canary exit 1 fi ``` ### AI-generated code gate (2026) ```yaml - name: AI code review uses: anthropics/claude-code-action@v1 with: api-key: ${{ secrets.ANTHROPIC_API_KEY }} review-mode: security-and-quality fail-on: high ``` ### Required-files / docs gate ```bash # require ADR for breaking change if git log -1 --pretty=%B | grep -qi 'BREAKING'; then git diff --name-only HEAD~1 | grep -q '^docs/adr/' || { echo "Breaking change requires ADR"; exit 1; } fi ``` ## 매 결정 기준 | 상황 | Gate set | |---|---| | Solo prototype | Pre-commit only | | Team project | **+ PR test/lint/security** | | Production SaaS | + coverage + perf + canary | | Regulated (HIPAA/SOX) | + SAST + DAST + audit log | | Open source | + DCO + license + dep review | **기본값**: pre-commit + PR test/lint/type/coverage 80% + Trivy + branch protection. ## 🔗 Graph - 부모: [[CI CD]] · [[DevOps]] - 응용: [[Code-Review]] - Adjacent: [[SonarQube]] · [[GitHub-Actions]] · [[Trunk-Based-Development]] ## 🤖 LLM 활용 **언제**: 매 gate config draft, 매 SonarQube 의 ruleset 의 explain, 매 CI YAML 의 generate. **언제 X**: 매 production gate threshold (coverage %, SLO %) — 매 team-context 결정. ## ❌ 안티패턴 - **Coverage as only gate**: 매 100% coverage + 매 0 assertion 가능. 매 mutation test 의 augment. - **Slow gates (>10min)**: 매 dev velocity kill. 매 parallelize / shard. - **Flaky gates**: 매 false positive 의 retry-bypass culture. 매 quarantine + fix. - **Legacy code 의 same threshold**: 매 new-code only 의 ratchet. - **Gates without humans**: 매 automation alone 의 architectural smell 의 miss. - **Bypass culture**: `--no-verify` / admin merge — 매 audit log + alert. ## 🧪 검증 / 중복 - Verified (SonarQube docs, GitHub branch protection API, ISO 9000 stage-gate origin). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — quality gates CI/CD layered framework. |