はじめに
こんにちは!masa-asaです。Azure pipelinesを触っているときにパイプラインがトリガーされる条件で混乱したのでまとめました。
なにがおこったか
以下のようなパイプラインを作成し、CIを行おうとしていました。
このとき、CIのパイプラインはソースブランチからdevブランチをターゲットブランチにしてPRが作成されたとき、またはdevブランチへのPRが開かれている状態でソースブランチにプッシュがあった場合に行われることを期待していました。
pr:
branches:
include:
- dev
resources:
- repo: self
stages:
- stage: LintAndUnitTestStage
displayName: Run Lint and Unit Test stage
jobs:
- job: LintAndUnitTestJob
pool:
vmImage: 'ubuntu-latest'
steps:
- script: |
version=$(grep python .tool-versions | cut -d" " -f2)
echo "##vso[task.setvariable variable=pythonVersion]$version"
echo "Python version set to: $version"
displayName: 'Read Python version from .tool-versions'
- task: UsePythonVersion@0
displayName: 'Install dependencies for Python'
inputs:
versionSpec: '$(pythonVersion)'
addToPath: true
architecture: 'x64'
- task: Cache@2
inputs:
key: '"$(Agent.OS)" | $(Build.SourcesDirectory)/poetry.lock'
path: ./venv
displayName: 'Cache Packages'
- script: |
python -m pip install --upgrade pip
python -m venv venv
. venv/bin/activate
pip install poetry
poetry install
displayName: 'Install dependencies for Python'
- script: |
. venv/bin/activate
ruff check
displayName: 'Run Lint ruff'
- script: |
. venv/bin/activate
pytest --cov=app --cov-report=term-missing
displayName: 'Run unit tests'
期待通りに動いた!と思いきや...ブランチの発行時やPRが開いていないときのプッシュでもパイプラインがトリガーされてしまう!
なぜ?
このとき、パイプラインと関連付けていたリポジトリはAzure Repos Gitでした。そしてprトリガーはAzure Repos Gitでは機能しないようなのです。prトリガーをyamlで記述して用いることができるのは、リポジトリがGitHubとBitbucket Cloudの場合だけのようです。
解決方法
コンソールのリポジトリ設定を変えることで解決できました。
設定から「Repositories」を選び、対象のリポジトリの「Policies」を選択します。その中の「Branch Policies」で設定したいブランチを選択します。ここでは「dev」ブランチにします。
ブランチ設定画面に遷移すると「Build Validation」を選択すると設定ウィンドウが開きます。
対象となるパイプラインを設定し、Trigger設定をAutomaticに設定します。
こうすることでこのブランチ(「dev」ブランチ)に対してPRが開かれた際、またはこのブランチへのPRが開かれている状態でソースブランチにプッシュがあった場合に、選択したパイプラインが実行されるようになります。
リポジトリの設定をしましたので、yamlファイルを修正しますprトリガーを削除してCIトリガー(trigger)を追加しました。CIトリガーの条件ですべてのブランチを除外しています。これにより、PRが出ていない際のソースブランチへのプッシュではトリガーされなくなります。
奇妙に見えてしまうのですが、yaml上ではパイプラインがトリガーされないような書き方になっていても前述の設定によりPRが出された場合などにはパイプラインが実行されます。
trigger:
branches:
exclude:
- '*'
resources:
- repo: self
stages:
- stage: LintAndUnitTestStage
displayName: Run Lint and Unit Test stage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
まとめ
- Azure Repos Gitを使っている場合にはprトリガーは使えない(機能しない)
- prトリガーを使えるのはGitHubとBitbucket Cloudのみ
- Azure Repos Gitでのpr時のトリガーはブランチポリシーの設定を変更することで実現
以上です。お読みいただきありがとうございました!
参考文献
おまけ
CIトリガーのオーバーライド設定
図のように「Pipelines」設定から「Edit」を選びます。
「Triggers」の設定画面で、CIトリガーのオーバーライド設定が行えます。この例では、yamlに書かれたCIトリガー(trigger)の条件を上書きして、トリガーが実行されないように無効化をしています。
この設定に気が付かず、yamlに書かれたトリガー条件と実際のパイプラインの動きがずれてしまい、ハマってしまうことがありそうだという印象です。