👋

Azure PipelinesでPull Request時にCIする

2022/07/09に公開

はじめに

継続的インテグレーションのトリガーをPull Request作成時に実施しすることで、CIがパスされた状態でマージしたい。

そんなときのやり方を紹介します。

なお公式のドキュメントはこちらにありますが、一部注意点があるため、本稿にも目を通していただけると、不要なハマりが減らせると思います。

実例

こちらに、ここで紹介した方法を適用したAzure DevOpsのパブリックなプロジェクトを公開していますので、良かったらご覧ください。

手順

つぎの手順で実施します。

  1. CI用のパイプラインを作成する
  2. パイプラインのCIをAzure DevOps上で無効化する
  3. ブランチポリシーを設定する

CI用のパイプラインを作成する

パイプラインは、とくに特殊なことはおこないません。

今回登録しているパイプラインはこちら。

YAML上のtriggerはつぎのようにdevelopブランチを指定していますが、このトリガー自体は、つぎの手順で無効化します。

# 下記のトリガーはAzure DevOps上で無効化されています。
# つぎの理由でtriggerの記述自体は残してあります。
# 1. triggerを削除すると全ブランチへのマージ時にトリガーされる設定となる
# 2. trigger:noneを指定するとPR時のトリガーも動作しない
# 3. どのブランチへのPR時にトリガーされるかの表明程度の意味
trigger:
- develop

パイプラインのCIをAzure DevOps上で無効化する

対象のパイプラインを開き、「Edit」ボタンを押下する。

「Triggers」を押下する。

YAML上のtrigger設定を上書きするようにして、CIを無効化します。

ブランチポリシーを設定する

Pull Requestトリガーを設定するには、ブランチポリシーを利用します。

今回はdevelopブランチへのPR時にCIするため、developブランチのブランチポリシーを設定します。

つづいてブランチポリシー内のBuild Validationの「+」ボタンから新しく追加します。

新しく開かれたペインで必要な情報を入力します。

各設定はつぎのとおりです。

項目 説明
Build pipeline 実行するパイプラインを選択します。
Path filter git上の指定のパスのリソースが更新された場合にCIを実行するように指定します。
上図ではPipelinesとSourceフォルダーの下が更新されたときに実行するように指定しています。
下記に注意してください。
- パス区切りは「/」(スラッシュ)
- トップレベルのフォルダーなどを指定する場合は先頭にスラッシュをつける
- 複数指定する場合は「;」(セミコロン)で区切る
Trigger 自動的にCIを実行するか、手動で実行するかを選択します。
AutomaticにしておくとPR作成後に再度pushされた場合などにもパイプラインが実行されます。
パイプラインの実行回数を制限したい場合はManualにするのが良いかもしれません。
Policy requirement パイプラインの実行が失敗したときに、PRのマージを許可するかどうかを決定します。
Optionを選択すると、パイプラインが失敗してもマージできます。
Build expiration マージ先のブランチが更新されたときに、パイプラインを再実行するかどうか選択します。
「Immediately when」が選択された場合、マージ先ブランチが更新される都度、パイプラインを再実行します。
マージ先ブランチの変更が少ない場合には、こちらが推奨されます。
「After~」はPR作成後に、指定時間経過した後にマージ先ブランチが更新された場合に、パイプラインを再実行します。
ビルド回数を抑止できます。
「Never」はマージ先が更新されても再実行しません。
Display name 表示名を入力します。

Build expirationの設定に注意が必要です。

もっとも安全なのは「Immediately when」を選択することですが、これは実運用上パイプラインが実行されすぎてしまう懸念があります。

「After~」はPull Request上がグリーンでも、実際マージするとビルドできない状態になる可能性があります。

この原稿執筆時の私的には、つぎの理由から「After~」を設定しようと思っています。

  1. developは頻繁に更新されるため「Immediately when」は避ける
  2. developが頻繁に更新されるということは、頻繁にPRが作成されるわけで、かりにビルドできない状態となってしまっても、つぎのPRが作成されたタイミングで判明する
  3. 念のため夜間にデイリーでCIを実行する

利用してみる

では実際に利用してみましょう。

適当なブランチを作成し、つぎのようにビルドが必ずエラーとなるようにソースを変更した上で、コミットしてブランチを発行します。

error

using System;
using System.Collections.Generic;
...

この状態でPull Requestを作成すると、自動的にパイプラインが実行されます。

しばらく待つと、エラーとなりつぎのように表示されます。

右上の「Set auto-complete」ボタンを見てください。通常、マージできるときには「Complete」と表示されますが、条件が満たされた場合にマージすることを許可する「Set auto-complete」が表示されており、パイプラインのエラーを解消しないとマージできないことが見て取れます。

では先ほどのコードを修正してpushしてください。このとき、単純にコードをもとに戻してしまうと、マージ先との差分が無くてパイプラインが実行されないので、何らかの差分がでるように(改行を増やすとか減らすとか)変更してください。

すると再度自動的にパイプラインが実行されます。今度は正常にビルドされて、ボタンが「Complete」に変更されたことが見て取れます。

Pull Requestの運用スタイルとして、作業開始時にPRを作成しておく場合があるかと思います。その場合、pushするつどビルドされるとパイプラインの実行回数が増えすぎるかもしれません。

そんな場合はパイプラインをdraft状態にしておけばパイプレインの実行は抑止できます。

以上。

Discussion