--- id: devops-cicd-pipeline-patterns title: CI/CD Pipeline 패턴 category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [devops, cicd, github-actions, vibe-coding] tech_stack: { language: "GitHub Actions / GitLab CI", applicable_to: ["Backend", "Web", "Mobile"] } applied_in: [] aliases: [GitHub Actions, fan-out, matrix, artifacts, secrets] --- # CI/CD Pipeline > 빠르고 신뢰할 수 있는 파이프라인 = (1) 매 PR 5분 안 검증, (2) 캐시 적극 활용, (3) **fan-out/fan-in** 으로 병렬, (4) deploy 가 원자적 + 롤백 1분. ## 📖 핵심 개념 - Trigger: PR / push / cron / manual. - Stages: lint → typecheck → test → build → deploy. - Artifact: stage 사이 파일 전달. - Secret: 환경별 token. - Cache: deps / build output. ## 💻 코드 패턴 (GitHub Actions) ### 기본 PR 검증 ```yaml name: PR Check on: pull_request: branches: [main] jobs: test: 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 lint - run: npm run typecheck - run: npm test -- --coverage - uses: codecov/codecov-action@v4 ``` ### Matrix — 병렬 ```yaml test: strategy: matrix: node: ['18', '20'] os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/setup-node@v4 with: { node-version: ${{ matrix.node }} } - run: npm test ``` ### Fan-out / fan-in — build 한 번 → 여러 곳 deploy ```yaml jobs: build: runs-on: ubuntu-latest steps: - run: npm run build - uses: actions/upload-artifact@v4 with: { name: dist, path: dist/ } deploy-staging: needs: build runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v4 with: { name: dist } - run: ./scripts/deploy.sh staging deploy-prod: needs: build if: github.ref == 'refs/heads/main' environment: production # 승인 필요 runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v4 with: { name: dist } - run: ./scripts/deploy.sh prod ``` ### Cache 전략 ```yaml - uses: actions/cache@v4 with: path: | node_modules .next/cache key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-deps- ``` ### Concurrency — 같은 PR 만 최신 한 개 ```yaml concurrency: group: ci-${{ github.ref }} cancel-in-progress: true ``` ### Reusable workflow ```yaml # .github/workflows/test.yml (reusable) on: { workflow_call: { inputs: { node: { type: string } } } } jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: ${{ inputs.node }} } - run: npm ci && npm test # 호출 - uses: ./.github/workflows/test.yml with: { node: '20' } ``` ## 🤔 의사결정 기준 | 단계 | 빈도 | 시간 한도 | |---|---|---| | Lint / format | 매 commit | < 30s | | Typecheck | 매 PR | < 1m | | Unit test | 매 PR | < 3m | | Integration | 매 PR | < 5m | | E2E | 매 PR (smoke) + main (full) | < 10m | | Build | 매 PR (artifact 보관) | < 5m | | Deploy staging | 매 main merge | auto | | Deploy prod | 승인 후 | manual gate | ## ❌ 안티패턴 - **모든 step 직렬**: 30분 PR 검증 → 사람 떠남. 병렬 + cache. - **secret hardcode**: code 또는 log 노출. 항상 secrets context. - **cache 키 stable 안 함**: 매번 cache miss. lock file hash. - **artifact 무한 보관**: 비용. retention. - **production deploy 승인 없음**: 사고 위험. environment + reviewer. - **rollback 절차 없음**: 사고 시 panic. 1-click rollback. - **deploy 가 비원자적**: 일부 인스턴스만 새 버전 → 사고. blue-green / canary. - **dependent test 가 한 job 안에서 실행**: 한 fail 시 모두 stop. matrix 분리. ## 🤖 LLM 활용 힌트 - "PR 검증 5분 이내 목표. cache + concurrency cancel + fan-out" 강조. - production gate = environment + 승인. ## 🔗 관련 문서 - [[DevOps_Docker_Layer_Cache]] - [[DevOps_Deployment_Strategies]]