CodeBuild + GitHub Webhook連携で特定のブランチ間イベントではビルドしないように制御する

CodeBuildのウェブフックイベントフィルタリングの機能を使うと、特定のブランチ間のプルリクエストはビルドしないなどの柔軟なトリガー制御を行えます。
2022.08.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

現在、自分はProfllyというプロフィールビュアーサービスの開発を行っています。

Profllyでは、CI/CDの一部にAWS CodeBuild(以下、CodeBuild)を採用しており、連携されたGitHubリポジトリでプルリクエストが作成・更新されたタイミングで、自動でCodeBuild上でビルドやテストを実行させるような仕組みになっています。

この仕組みでは、元々連携されたリポジトリの全てのPRに対してCIが走るように設定していましたが、特定のブランチ間でのPRにおけるCIは不要なので実行しないようにしたい、というニーズがありました。
このエントリでは、CodeBuildのウェブフックイベントフィルタリングの機能を使って、特定のブランチ間でのイベントをトリガーしないようにする方法をご紹介します。

プロジェクトにおけるGitブランチモデル

まず、前提としてProfllyではブランチ戦略として GitLab Flow をベースにしたものを採用しています。

  • main(master): メインのブランチ。開発環境にデプロイされる
  • feature/xyz: 開発完了後、プルリクエストによりmainブランチにマージ
  • staging: ステージング環境(pre-production)にデプロイされる
  • production: プロダクション環境にデプロイされる

通常の開発時には、mainブランチから切ったfeature系のブランチをmainへ取り込みますが、それぞれの環境へのデプロイ時には main -> staging -> production に対してそれぞれPRを起こして、マージする形になります。

このようなモデルにおいては、CIについては以下のようにしたいニーズがあります。

  • main -> staging, あるいは staging -> production のPR作成時にはCIは不要
  • ただし、緊急対応などでstagingproductionから直接切ったhotfix系ブランチを取り込むこともあるので、stagingproductionに対して起こしたPRは一律でCIを止めたいわけではない

上記の条件でCIのトリガーを制御できないか、CodeBuild側で設定してみます。

CodeBuildのWebhook event設定

CIを実行するCodeBuildビルドプロジェクトでは、GitHubをソースプロバイダとしてWebhook連携をおこなっています。

CIはPRの作成時や更新時にトリガーしたいため、イベントタイプは以下を指定しています。

  • PULL_REQUEST_CREATED
  • PULL_REQUEST_UPDATED
  • PULL_REQUEST_REOPENED

ただし、この設定だとブランチ関係なくPRが作成されるとCIが走ってしまいます。

ブランチ単位や更新されるファイル単位などでトリガーを制御したい場合は、Webhookイベントのフィルタリング機能 を使うことで実現できます。

プライマリソースのウェブフックイベントの「編集」をクリックして、フィルター条件を設定してみます。

今回は

  • main -> staging へのPR(ステージングへのデプロイ)
  • staging -> production へのPR(プロダクションへのデプロイ)

の場合にCIを実行しないようにしたいので、ウェブフックイベントフィルタグループの 「これらの条件でビルドを開始しない」 に以下を入力します。
なお、フィルター条件には正規表現のパターンが利用可能です。

  • BASE_REF: ^refs/heads/(staging|production)$

この設定のみだと、stagingproduction から直接切った hotfix 系のPRでCIが走らなくなってしまうため、そのための条件も追加してみます。
「フィルターグループの追加」をクリックして、別条件のフィルターを追加します。

イベントタイプは同様にPR系のイベントを選択し、 「これらの条件でビルドを開始する」 に以下を入力します。

  • HEAD_REF: ^refs/heads/hotfix.*$

これで、hotfix/* ブランチの場合は、マージ先のブランチに関係なくビルドが開始されるようになります。
なおフィルタグループを複数設定した場合、それぞれのグループに対しては ANDではなくOR条件の判定 となるようです。

入力後「ソースの更新」をクリックし、CodeBuild側の設定は完了です。

実際にプルリクエスト作ってみる

CodeBuild側の設定ができたので、実際にPRを作成してCIのトリガーがどうなるのか確認してみます。

まずは、feature/xyz -> main へのPRを作成し、これまで通りCIが実行されるかを確認します。

CIはBuild-で始まるCodeBuildのビルドプロジェクトなので、問題なくCIが実行されています。

次に、main -> staging へのPRを作成し、CIがトリガーされないことを確認してみます。

GitHub上でもCodeBuild上でも特にはトリガーはされておらず、不要なCI実行がなくなりました。やったー

さらに、hotfix/xyz -> staging へのPRを作成し、hotfix系のCIはトリガーされることも確認してみます。

こちらはうまくCIが動いてくれています!

おわりに

CodeBuild + GitHub Webhook連携下において、特定のブランチ間イベントでのビルドを避けるためウェブフックイベントフィルタリングの機能を設定してみました。
今回指定したフィルター以外にも、コミットメッセージやGitで更新されるファイルパスも指定できたりするので、色々な条件でトリガーする/しないの制御ができそうですね。

どなたかの参考になれば幸いです。