自分が携わっているとある案件ではCircleCIで全てのpushに対してテストを実行、featureブランチへのpushはテストが通ったらそのfeatureの評価用の環境に自動デプロイという流れにしている。これはSPAの結構込み入ったUIのアプリケーションのために、開発メンバーだけでなくプロダクトオーナーからできるだけ早く動作についてフィードバックを受けるため。
しかし最近、この運用で少し問題が出てきた。それは
- 評価用環境にデプロイするにはテストが必須だが、テストが通る前のアプリケーションをプロダクトオーナーに見て貰いたい場合がある。
- 例えばUIのルック&フィールやインタラクションの使い勝手を部分的に確認して貰って方向性が正しいかコンセンサスを取るのに、その観点で不要なテストまで通すと手間がかかりすぎる事がある。
- 一方で、正式にレビューを出す場合はプルリクエストを作成するので、プルリクエストを作成した後からはテストまで全て通してほしい。
- feature以外のブランチ(現状はgithub flowなのでメインしかないが)へは、常にtestも実行してよい。
というものだった。テストの作り方の問題も勿論あるが、フィードバックのサイクルを可能な限り早くしたいというこれまでの進め方とは少々そぐわない。
というわけでCircleCIで、プルリクエストが作成されていなかったらテストを実行しない方法について調べたが、どうもCircleCIのwhen statementではできないようだ。(参考:https://discuss.circleci.com/t/using-environment-variables-inside-a-conditional/39152/4)
仕方がないので、環境変数を見てrunの中で制御することにした。以下は抜粋。
test:
steps:
- attach_workspace:
at: /tmp/build-workspace
- run:
name: Test
command: |
cd /tmp/build-workspace
if [[ "$CIRCLE_BRANCH" =~ feature/.* ]]; then if [[ -n "$CIRCLE_PULL_REQUEST" ]]; then yarn test --run; fi; else yarn test --run
さて問題は全てのpushとプルリクエストに対してパイプラインを実行する設定だが、CircleCIの設定を見る限り、「全てのpushに対して実行」「プルリクエスト及びデフォルトブランチに対して実行」の2つのみのようだ。これでは困るなと思ったが、以下の機能がリリースされていた。
https://discuss.circleci.com/t/only-build-pull-requests/48073
この方法を使うと、Only build pull requestsで常にビルドを実行するデフォルトブランチのカスタマイズができるようだ。これによって、featureへのpushも常にビルドできるようになるようだ。コードはリンク先にサンプルがあるので、それを元にすれば問題なく動作した。
追記
上記の設定を行った場合、使っているGitのホスティングサービスのCircleCIとの連携の設定によっては、プルリクエストの更新とリポジトリへのpushで二重にパイプラインが動いてしまう。これを避けるには、Gitのホスティングサービス側でプルリクエストの作成の時のみCircleCIに通知するように設定する必要がある。