Article

🚦 GitHub Actionsのconcurrencyで二重デプロイを防ぐ

githubactions, ci, devops, github

GitHub Actionsでmainへのpushごとにデプロイしていると、短時間に複数コミットが入ったときに複数のデプロイが同時進行することがあります。

この問題を抑えるために使えるのがconcurrencyです。

concurrencyとは

concurrencyは「同じグループに属するWorkflowやJobを同時に何個まで動かすか」を制御する仕組みです。

例えばデプロイWorkflowに次を追加します。

concurrency:
  group: production-deploy
  cancel-in-progress: true

これで同じproduction-deployグループの実行が重なった場合、古い実行をキャンセルして新しい実行を優先できます。

ブランチごとに分ける

Preview環境などでブランチごとに独立させたい場合は、式を使います。

concurrency:
  group: deploy-${{ github.ref }}
  cancel-in-progress: true

mainとfeatureブランチが別グループになるため、互いの実行を止めません。

本番デプロイでは注意する

cancel-in-progress: trueは便利ですが、途中キャンセルが安全でないデプロイ処理には向きません。

例えばDBマイグレーションの途中でWorkflowがキャンセルされると危険な場合があります。

その場合は、

concurrency:
  group: production-deploy
  cancel-in-progress: false

として、前の実行が終わるまで次を待たせる方が安全です。

よくある用途

  • FirebaseやAWSへの本番デプロイ
  • 同じ環境に対するTerraform apply
  • バージョン番号を更新するRelease Workflow
  • 同じファイルへ書き戻す自動コミット
  • E2Eテスト環境を共有しているWorkflow

まとめ

GitHub Actionsでデプロイが重なる可能性があるなら、Workflowの処理内容だけでなく「同時実行された場合」を設計しておく必要があります。

concurrencyを使うことで、古いデプロイを止めるか、順番待ちさせるかを明示できます。

参考