Azure pipelinesのトリガー条件はやばい

# はじめに
こんにちは！masa-asaです。Azure pipelinesを触っているときにパイプラインがトリガーされる条件で混乱したのでまとめました。

# なにがおこったか
以下のようなパイプラインを作成し、CIを行おうとしていました。
このとき、CIのパイプラインはソースブランチからdevブランチをターゲットブランチにしてPRが作成されたとき、またはdevブランチへのPRが開かれている状態でソースブランチにプッシュがあった場合に行われることを期待していました。
```yaml
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」ブランチにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/2f28778e-4758-fda2-1fd5-4d8bd5b802c5.png)



ブランチ設定画面に遷移すると「Build Validation」を選択すると設定ウィンドウが開きます。
対象となるパイプラインを設定し、Trigger設定をAutomaticに設定します。
こうすることでこのブランチ（「dev」ブランチ）に対してPRが開かれた際、またはこのブランチへのPRが開かれている状態でソースブランチにプッシュがあった場合に、選択したパイプラインが実行されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/84b98497-4dec-3689-db05-01a95d0c854e.png)


リポジトリの設定をしましたので、yamlファイルを修正しますprトリガーを削除してCIトリガー（trigger）を追加しました。CIトリガーの条件ですべてのブランチを除外しています。これにより、PRが出ていない際のソースブランチへのプッシュではトリガーされなくなります。
奇妙に見えてしまうのですが、yaml上ではパイプラインがトリガーされないような書き方になっていても前述の設定によりPRが出された場合などにはパイプラインが実行されます。


```yaml
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時のトリガーはブランチポリシーの設定を変更することで実現

以上です。お読みいただきありがとうございました！

# 参考文献

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/repos/azure-repos-git?view=azure-devops&tabs=yaml

https://stackoverflow.com/questions/76421984/azure-pipelines-individual-ci-triggered-for-pipelines-despite-trigger-none

# おまけ
### CIトリガーのオーバーライド設定
図のように「Pipelines」設定から「Edit」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/880e992c-cfb9-3512-56fc-492b6d15cc41.png)

画面左上の「⋮」から「Triggers」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/34c5755a-62de-372d-20cf-19acc24274e3.png)

「Triggers」の設定画面で、CIトリガーのオーバーライド設定が行えます。この例では、yamlに書かれたCIトリガー（trigger）の条件を上書きして、トリガーが実行されないように無効化をしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942439/08d12643-4b2d-c3ce-3292-5c98dde3e06d.png)

この設定に気が付かず、yamlに書かれたトリガー条件と実際のパイプラインの動きがずれてしまい、ハマってしまうことがありそうだという印象です。