본문으로 건너뛰기
개발 머꼬
개발 노트GitHub Actions
hohyeon.dev23

5개 앱마다 거의 똑같은 워크플로우를 복붙하다가 reusable workflow로 바꾼 이유

  • #CI/CD
  • #Engineering Note
  • #GitHub Actions

문제 발생

모노레포의 여러 앱마다 거의 동일한 빌드/테스트 단계를 가진 워크플로우 파일을 하나씩 복사해서 만들었는데, 공통 로직(예: 캐시 키 전략)을 하나 바꿀 때마다 모든 파일을 일일이 찾아 고쳐야 했고, 그 과정에서 몇 개는 놓쳐 서로 미묘하게 어긋난 상태가 됐습니다.

원인 분석

GitHub Actions 워크플로우 파일을 복사-붙여넣기로 관리하면, 코드에서 함수로 추출하지 않고 로직을 복붙하는 것과 똑같은 문제가 생깁니다 — 공통 로직이 여러 곳에 흩어져 하나의 진실 소스(single source of truth)가 없어지고, 시간이 지날수록 조금씩 어긋납니다.

해결 방안

Reusable workflow(workflow_call 트리거)로 공통 단계를 한 곳에 정의하고, 각 앱의 워크플로우는 그것을 "호출"만 하도록 만듭니다 — 함수를 추출해 여러 곳에서 재사용하는 것과 같은 개념입니다.

# .github/workflows/_reusable-app-ci.yml
on:
  workflow_call:
    inputs:
      app-name:
        required: true
        type: string

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pnpm --filter ${{ inputs.app-name }} build
# .github/workflows/ci-web.yml
jobs:
  call-ci:
    uses: ./.github/workflows/_reusable-app-ci.yml
    with:
      app-name: "@meokko/web"
  1. workflow_call을 트리거로 지정한 워크플로우 파일은 다른 워크플로우가 uses:로 호출할 수 있는 재사용 단위가 됩니다 — inputs로 매개변수를, secrets로 필요한 비밀값을 전달받을 수 있습니다.
  2. 같은 저장소 안의 워크플로우뿐 아니라, 다른 저장소에 있는 reusable workflow도 owner/repo/.github/workflows/file.yml@ref 형태로 참조해 쓸 수 있습니다 — 여러 저장소에 걸쳐 CI 정책을 통일하고 싶을 때 유용합니다.
  3. Reusable workflow와 비슷한 목적의 Composite action도 있는데, 차이는 규모입니다 — composite action은 "여러 step을 하나의 action처럼 묶는" 더 작은 단위이고, reusable workflow는 "job 전체(여러 step, 여러 job)"를 재사용하는 더 큰 단위입니다. 재사용하려는 범위가 job 수준이면 reusable workflow, step 몇 개 수준이면 composite action이 더 적합합니다.
  4. 모노레포처럼 앱마다 거의 동일한 CI 흐름이 반복되는 구조에서는, matrix 전략(하나의 job을 여러 값으로 병렬 실행)과 reusable workflow 중 어느 쪽이 더 적합한지도 함께 검토할 만합니다 — 앱마다 완전히 동일한 단계라면 matrix가 더 단순할 수 있고, 앱마다 미묘하게 다른 단계가 있다면 reusable workflow의 inputs로 그 차이를 표현하는 것이 낫습니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.