モノレポETLのための4つのGitHub Actionsパターン

1つのモノレポから3つのサイトを運用すると、問題が発生します。3つの個別のETLジョブ、3つのコンテンツ再ビルド、そして3つのデプロイパイプラインに直面することになります。これらを調整しないと、衝突が起こります。

このセットアップを安定させるために、6週間かけてスケジュールをテストしました。私が使用している4つのパターンを紹介します。

1. Cronジョブにタイムオフセットを使用する

すべてのETLジョブを同時に実行すると、失敗の原因となります。ジョブがAPIのレート制限を奪い合うからです。HuggingFaceやGitHubが429エラーを返すと、実行は失敗します。

これを防ぐために、30分のオフセットを使用しています。

  • ジョブ1は02:00に開始
  • ジョブ2は02:30に開始
  • ジョブ3は03:00に開始

30分あれば、次のジョブが始まる前に重いプル処理を完了させるのに十分な時間があります。これにより、ログが整理され、APIの衝突を防ぐことができます。

2. スキップフラグを使用して不要な再ビルドを停止する

すべてのETLジョブはVercelへのデプロイで終了します。問題は、記事のコミットも再ビルドをトリガーしてしまうことです。計画がないと、記事を更新するたびに3つのサイトすべてが再ビルドを強制されます。これはビルド時間の無駄です。

私はETLのコミットメッセージに [skip publish-articles] タグを使用しています。

ワークフローにこのフラグを確認するステップを追加しました。タグが存在する場合、ワークフローはビルドとデプロイのステップをスキップします。これにより、ETLパイプラインを記事のパイプラインから切り離すことができます。

3. パスフィルターを使用して特定のサイトを対象にする

1つのサイトの更新が3つのデプロイをトリガーすることは望ましくありません。各サイトのワークフローを、そのサイト自身のフォルダと共有パッケージのフォルダのみを監視するように設定しています。

ロジックの例:

  • AIツールサイトは apps/ai-tools/ のみを監視
  • OSSサイトは apps/oss-alternatives/ のみを監視

共有ディレクトリのコードを変更すると、すべてのサイトが再ビルドされます。共有コードの変更は稀であるため、このトレードオフは許容しています。

4. コントロールのためにManual Dispatchを追加する

Cronは日々のルーチンを処理します。Manual dispatch(手動実行)はそれ以外のすべてを処理します。workflow_dispatch を使用することで、以下のことが可能になります:

  • 失敗したETLジョブの再実行
  • データ追加後の強制リフレッシュ
  • データベースに書き込まずにデータをテストするためのドライランの実行

GitHubのUIには、これらの選択肢のためのドロップダウンメニューが表示されます。これにより、タイポを防ぎ、デバッグが容易になります。

まとめ

これらのパターンは複雑ではありません。明示的です。新しいワークフローを追加したときにシステムを壊さないよう、リポジトリ内にこれらのルールを記録したシンプルなMarkdownファイルを保持しています。

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