しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure DevOps で特定のファイルが変更された場合のみ Pipeline を実行させる

Azure Repos を使って Monorepo 構成を採用している場合には、Azure Pipelines はそれぞれのプロジェクト単位で実行させたいので、トリガーの設定でパスを指定して実現します。

例として backend というディレクトリが変更された時だけに Pipeline を実行させたい場合には、以下のように paths にディレクトリ以下のワイルドカードを追加して対応します。

地味に忘れやすいのが Pipeline の定義ファイルも paths に含めることです。backend 以下にある場合は問題ないですが、別ディレクトリに保存していると Pipeline 定義を変更した時に動かなくなります。

trigger:
  branches:
    include:
    - master
  paths:
    include:
    - backend/*
    - .azure-pipelines/build.yml

Azure Pipelines の定義ファイルは Red Hat が公開している VS Code の YAML 拡張をインストールしていると書きやすいです。JSON Schema ベースで入力補完と検証を行ってくれます。

殆どのケースでは以下のように自動的に JSON Schema を検出してくれますが、稀に迷うことがあるので明示的に指定すれば記憶されるので次からは適用されます。

これで master ブランチにプッシュされた時は意図した通りに動くようになったので、Pull Request に対しても Pipeline を実行するように Branch Policy を設定します。

GitHub Actions の場合は YAML 側でトリガー設定を追加するだけで済むのですが、Azure DevOps では Branch Policy の Build Validation を追加しないと動作しません。

Branch Policy の設定が若干分かり難く、Build Validation の設定も挙動不審なことがありますが、以下のように実行する Pipeline を選択すると良いです。

これで保存すると Pull Request の作成や変更時に指定した Pipeline が動くようになりますが、YAML で指定した paths の指定は完全に無視されてしまいます。

以下は README.md を変更した PR の例ですが Pipeline が実行されてしまっています。

Build Validation の場合にも同じように制限したい場合には UI から Path filter を別途指定する必要があるので、以下のようにパスを / 始まりかつセミコロンで区切って追加します。

検証はしていないですが、ドキュメントでは paths は先頭 / は不要なのに対して、Build Validation では / 始まりになっています。ぶっちゃけイマイチです。

追加して保存すると Pull Request からメッセージが消えて、即時反映されていることが確認出来ます。

今度は backend ディレクトリ以下のファイルを変更した PR を作成すると、Build Validation によって Pipeline が実行されることが確認出来ます。

YAML でのトリガー設定は PR を作成すれば誰でも追加できますが、Build Validation は権限を持った人しか設定できないので使い勝手が悪いです。この辺りは GitHub Actions のが後発だけあって使い勝手が良いです。

おまけ : git submodule を使っている時のフィルタ設定

今回 backend はディレクトリでしたが、もし git submodule を使っている場合には少し書き方が変わります。以下のように Azure DevOps 上では submodule はコミットハッシュが入ったファイルとして扱われているので、このファイルの変更をトリガーにしてあげます。

Build Validation のパス指定は /backend; /.azure-pipelines/build.yml のようにファイルとして扱うようにします。同様に YAML でのトリガーも以下のようにファイル扱いにします。

trigger:
  branches:
    include:
    - master
  paths:
    include:
    - backend
    - .azure-pipelines/build.yml

設定を変更した後に submodule を変更した Pull Request を作成すると、以下のように Build Validation によって意図した通りに Pipeline が実行されることが確認出来ます。

もちろん Pull Request をマージした後には通常のトリガー設定に従い Pipeline が実行されます。

最近は GitHub Actions ばかり使っていたので、Build Validation のパス指定と複数指定できることを失念していて少しはまりました。セミコロン指定で複数指定可能とか、一貫性のない記法は止めてほしいです。