모노레포 ETL을 위한 4가지 GitHub Actions 패턴

하나의 모노레포에서 세 개의 사이트를 운영하면 여러 문제가 발생합니다. 세 개의 별도 ETL 작업, 세 번의 콘텐츠 재빌드, 그리고 세 개의 배포 파이프라인을 마주하게 됩니다. 이를 조율하지 않으면 작업들이 서로 충돌하게 됩니다.

저는 이 설정을 안정화하기 위해 6주 동안 스케줄을 테스트했습니다. 제가 사용하는 네 가지 패턴은 다음과 같습니다.

  1. Cron 작업에 시간 오프셋(Time Offsets) 사용하기

모든 ETL 작업을 동시에 실행하면 오류가 발생합니다. 작업들이 API 호출 제한(rate limits)을 두고 경쟁하기 때문입니다. HuggingFace나 GitHub에서 429 에러를 반환하면 실행이 실패합니다.

저는 이를 방지하기 위해 30분의 오프셋을 사용합니다.

  • 첫 번째 작업은 02:00에 시작
  • 두 번째 작업은 02:30에 시작
  • 세 번째 작업은 03:00에 시작

30분이면 다음 작업이 시작되기 전에 무거운 데이터 풀(pull) 작업을 완료하기에 충분한 시간입니다. 이를 통해 로그를 깔끔하게 유지하고 API 충돌을 방지할 수 있습니다.

  1. 불필요한 재빌드를 중단하기 위해 Skip Flag 사용하기

모든 ETL 작업은 Vercel 배포로 마무리됩니다. 문제는 아티클 커밋이 재빌드를 트리거할 때 발생합니다. 계획이 없다면, 모든 아티클 업데이트마다 세 개의 사이트가 모두 재빌드되어 빌드 시간을 낭비하게 됩니다.

저는 ETL 커밋 메시지에 [skip publish-articles] 태그를 사용합니다.

워크플로우에 이 플래그를 확인하는 단계를 추가했습니다. 태그가 존재하면 워크플로우는 빌드 및 배포 단계를 건너뜁니다. 이를 통해 ETL 파이프라인과 아티클 파이프라인을 분리할 수 있습니다.

  1. 특정 사이트를 타겟팅하기 위해 Path Filter 사용하기

한 사이트의 업데이트가 세 번의 배포를 트리거하는 것을 원치 않을 것입니다. 저는 각 사이트의 워크플로우가 자신의 폴더와 공유 패키지(shared packages) 폴더만 감시하도록 설정합니다.

예시 로직:

  • AI tools 사이트는 apps/ai-tools/만 감시
  • OSS 사이트는 apps/oss-alternatives/만 감시

공유 디렉토리의 코드를 변경하면 모든 사이트가 재빌드됩니다. 공유 코드 변경은 드물기 때문에 저는 이러한 트레이드오프(trade-off)를 수용합니다.

  1. 제어를 위한 Manual Dispatch 추가하기

Cron은 일상적인 루틴을 처리합니다. Manual dispatch는 그 외의 모든 것을 처리합니다. 저는 다음과 같은 작업을 수행할 수 있도록 workflow_dispatch를 사용합니다.

  • 실패한 ETL 작업 재실행
  • 데이터 추가 후 강제 새로고침
  • 데이터베이스에 쓰지 않고 데이터를 테스트하기 위한 드라이 런(dry run) 실행

GitHub UI에서 이러한 선택을 위한 드롭다운 메뉴가 표시됩니다. 이를 통해 오타를 방지하고 디버깅을 쉽게 할 수 있습니다.

Summary

이 패턴들은 복잡하지 않습니다. 명시적일 뿐입니다. 저는 이러한 규칙을 문서화하기 위해 저장소에 간단한 마크다운 파일을 유지합니다. 이를 통해 새로운 워크플로우를 추가할 때 시스템을 망가뜨리지 않도록 합니다.

Source: https://dev.to/morinaga/four-github-actions-patterns-that-schedule-etl-across-a-three-site-monorepo-12oo