2018BazelCICircleCIプロジェクト構成CIと連携する上で実現したいことCircleCIのDockerイメージにbazelをインストールするパッケージ内のコードに修正が入ればパッケージのテストとバイナリビルドを実行したいlocal_resourcesのフラッグを指定するパッケージ内のコードに修正が入りコンテナビルドのタスクがあればレジストリへプッシュを行いたいcommon_goに修正が入れば依存している全てのパッケージのテストからバイナリビルド、コンテナビルドとレジストリへのプッシュを行いたいまとめコード今回のエントリではBazelでビルドしたマルチプロジェクトとCircleCIの連携をまとめていく。マルチプロジェクトとCIを連携する際の実運用の課題を洗い出して解決方法を考えた。プロジェクト構成CIと連携させるマルチプロジェクトは次のような構成である。greet.protoCIと連携する上で実現したいことpkg以下にはcommon_goとpublic_goのパッケージが配置されている。public_goはcommon_goに依存している。CIと連携する上で実現したいことを一覧にする。パッケージ内のコードに修正が入ればパッケージのテストを実行したいパッケージ内のコードに修正が入ればパッケージのバイナリビルドを実行したいパッケージ内のコードに修正が入りコンテナビルドのタスクがあればレジストリへプッシュを行いたいcommon_goに修正が入れば依存している全てのパッケージのテストからバイナリビルド、コンテナビルドとレジストリへのプッシュを行いたいここから1つずつ実現方法をまとめていく。CircleCIのDockerイメージにbazelをインストールするCircleCIのDockerイメージにはbazelは標準でセットアップされていないのでインストールする必要がある。Bazelをインストールするジョブは次のようになった。Bazel公式ドキュメントに載っているとおりのインストール手順をCI上で実行する。パッケージ内のコードに修正が入ればパッケージのテストとバイナリビルドを実行したいテストとバイナリビルドの方法をまとめていく。方法としてはCI上にチェックアウトされたコードとmasterまたはHEADとの差分をとり修正されたコードのパスを取得する。そのパスからbazelコマンドに必要な文字列を抜き出せば良い。先人の知恵を借りてBazel連携を実現した。2.0完成したシェルスクリプトは次のようになった。check.tmpcommon_goとpublic_goに修正が入ればcheck.tmpには次のような文字列が格納される。queryを使いテストとバイナリビルドに合致するビルドタスクを抽出して実行している。//pkg/...のようにして全体をビルドせずに更新のあったパッケージのみビルドすることができた。local_resourcesのフラッグを指定するprotobufが含まれるプロジェクトのためビルドに必要なメモリを確保する必要がある。Dockerイメージ内でBazelを動かしているのでlocal_resourcesのフラッグを指定してメモリ調整をしている。1--local_resources=4096,2.0,1.0これを指定しないとOOMが発生してしまうので注意が必要である。queryで抽出することで更新のあったパッケージのみがレジストリにプッシュされるようにした。IMAGE_TAG=${IMAGE_TAG}doneまたcontainer_pushのタスクは次のように定義してある。"$(IMAGE_TAG)",)tagに”$(IMAGE_TAG)”を指定することでビルド時のオプションを参照できるようにした。IMAGE_TAG=${IMAGE_TAG}を加えることでブランチごとのDockerイメージがプッシュできる。使えば変数をファイルで管理できる。Bazelcommon_goに修正が入れば依存している全てのパッケージのテストからバイナリビルド、コンテナビルドとレジストリへのプッシュを行いたい最後に共通パッケージに修正が入れば依存するパッケージすべてにビルドタスクを実行するための実現方法をまとめる。1つ目はrdepを使って依存するパッケージをqueryで抽出する方法である。packagepkg/common_go/utilpkg/public_gopkg以下でpkg/common_goが利用されているパッケージが抽出できる。//pkg/...を実行してしまう方法である。共通パッケージに依存が多ければビルド時間が長くなっていくのでCIで自動化するべきかはプロジェクト規模による。自動化せずにChatOpsなどで特定のパッケージをビルドするインターフェースを用意したほうが効率が良いかもしれない。まとめBazelでビルドするマルチプロジェクトとCircleCIを連携する方法をまとめた。CIのDockerイメージ内のメモリ調整にlocal_resourcesのフラッグを指定する知見が溜まった。queryを駆使して実行したいタスクを抽出すればCI連携も見通しよく整理できそうな感触を得た。Whiteplain。