CodeBuild + GitHub Webhook連携で特定のブランチ間イベントではビルドしないように制御する
現在、自分は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は不要- ただし、緊急対応などで
staging
やproduction
から直接切ったhotfix
系ブランチを取り込むこともあるので、staging
やproduction
に対して起こした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)$
この設定のみだと、staging
や production
から直接切った 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で更新されるファイルパスも指定できたりするので、色々な条件でトリガーする/しないの制御ができそうですね。
どなたかの参考になれば幸いです。