개요

GitHub Actions는 CI/CD를 넘어 전체 개발 워크플로우를 자동화하는 강력한 플랫폼입니다. 기본적인 빌드-테스트-배포 파이프라인을 넘어, 재사용 가능한 워크플로우, 매트릭스 전략, 환경 보호 규칙 등 고급 기능을 활용하면 엔터프라이즈급 CI/CD 파이프라인을 구축할 수 있습니다.

핵심 개념

GitHub Actions의 고급 기능들을 이해하면 더 효율적이고 안전한 워크플로우를 설계할 수 있습니다.

  • Reusable Workflows: workflow_call 이벤트로 워크플로우를 모듈화하여 여러 리포지토리에서 재사용
  • Composite Actions: 여러 단계를 하나의 액션으로 패키징하여 DRY 원칙 적용
  • Matrix Strategy: 여러 OS, 언어 버전, 환경 조합을 병렬로 테스트
  • Environment Protection: 승인자 지정, 대기 타이머, 브랜치 제한으로 배포 안전성 확보
  • Concurrency Control: 동일 그룹의 중복 실행을 방지하여 리소스 최적화

실전 예제

고급 패턴을 적용한 프로덕션급 워크플로우입니다.

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
  lint-and-typecheck:
    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

  test:
    needs: lint-and-typecheck
    strategy:
      matrix:
        node-version: [18, 20, 22]
        os: [ubuntu-latest, macos-latest]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test -- --coverage
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: coverage-${{ matrix.os }}-${{ matrix.node-version }}
          path: coverage/

  deploy-staging:
    needs: test
    if: github.ref == 'refs/heads/develop'
    environment: staging
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Deploying to staging..."

  deploy-production:
    needs: test
    if: github.ref == 'refs/heads/main'
    environment:
      name: production
      url: https://myapp.com
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Deploying to production..."

재사용 가능한 워크플로우 예시입니다.

# .github/workflows/reusable-deploy.yml
name: Reusable Deploy
on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
      app-version:
        required: true
        type: string
    secrets:
      deploy-key:
        required: true

jobs:
  deploy:
    environment: ${{ inputs.environment }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Deploy
        run: |
          echo "Deploying v${{ inputs.app-version }} to ${{ inputs.environment }}"
        env:
          DEPLOY_KEY: ${{ secrets.deploy-key }}

활용 팁

  • Concurrency 활용: PR 브랜치에서는 cancel-in-progress: true로 이전 실행을 취소하고, main에서는 false로 설정하여 배포가 중단되지 않도록 합니다.
  • 캐시 전략: actions/cache와 setup-node의 cache 옵션을 활용하되, lock 파일(package-lock.json)을 기준으로 캐시 키를 생성하세요.
  • 시크릿 관리: Environment secrets와 Repository secrets를 구분하여 사용하세요. 프로덕션 배포 키는 반드시 Environment secrets에 저장합니다.
  • 조건부 실행: paths 필터와 if 조건을 조합하여 불필요한 실행을 줄이세요. 문서만 변경된 PR에서 전체 테스트를 실행할 필요는 없습니다.
  • 매트릭스 최적화: fail-fast: false로 설정하면 하나의 조합이 실패해도 나머지 결과를 확인할 수 있어 디버깅에 유리합니다.

마무리

GitHub Actions의 고급 기능들을 활용하면 단순한 CI/CD를 넘어 전체 개발 라이프사이클을 자동화할 수 있습니다. 재사용 가능한 워크플로우로 조직 전체의 표준을 정립하고, 환경 보호 규칙으로 배포 안전성을 확보하세요. 잘 설계된 워크플로우는 팀의 개발 속도와 코드 품질을 동시에 높여줍니다.