(Azure Pipelines) 複数リポジトリのチェックアウトステップを試してみた
Azure Pipelines では、yamlファイルが含まれているリポジトリとは異なるリポジトリをチェックアウトすることができます。
あるリポジトリが別のリポジトリに依存するような仕組みの場合、この機能を使う必要性があります。
私自身、この機能を使ったことがなかったので使い方をまとめます。
使い方
基本的には上記リンクを参照するのが良いです。 これを書いている時点では以下の Git ホスティングサービスに対応しているようです。(ただし、Azure DevOps Server の場合は Azure Repos のみ対応) Azure Repos の場合、別 Project や別 Organization のリポジトリについても認証さえできればチェックアウトすることができるようです。
- Azure Repos
- GitHub
- GitHubEnterprise
- Bitbucket Cloud
基本的な構文
複数リポジトリを利用する上で必要な定義がいくつかあります。
ひとつはresources、もうひとつはcheckoutです。
複数リポジトリをチェックアウトする上で必須なのがcheckoutで、それを利用するためにresourcesのリポジトリ定義が必要になるイメージです。
スキーマはそれぞれこちらを読めばわかります。
resourcesは、複数定義することもできてそれぞれ別サービスからリポジトリをチェックアウトすることもできるようです。
resources:
repositories:
- repository: <yaml で参照するための名称>
type: <Azure Repos の場合は`git`。他にも`github`も指定することができる>
name: <リポジトリの名称。`プロジェクト名/リポジトリ名`で指定する>
ref: <ブランチ名。`refs/heads/main`のように指定する>
endpoint: <異なる Organization の場合はここに接続サービスの名称を記載する>
trigger: <CI トリガーが必要な場合はここに定義する>
基本的なresourcesの構文としては、これで事足りそうです。
repositoryに指定する名称にはアルファベット大文字・小文字、数字とアンダースコア_のみ使用できます。
nameに指定するリポジトリ名は空白スペースが含まれていても問題ありません。プロジェクト名も同様です。
次にcheckoutです。
checkoutはstepsごとに指定することができます。
-checkout: selfの場合は、自分自身、つまりyamlファイルのあるリポジトリを指定することになります。
別リポジトリを指定する場合は、resourcesの- repository:で指定した名称を設定します。
チェックアウトパス
チェックアウト後にリポジトリがどこにクローンされるかについては以下のページに記載されています。
挙動としては、リポジトリが単体か複数かによって異なります。
単体か複数かの判断基準はyamlに定義されたcheckoutに定義したリポジトリの数に依存するようです。
単体リポジトリ構成では変数の$(Agent.BuildDirectory)のサブフォルダであるC:\agent\_work\1\sにチェックアウトされます。
複数リポジトリ構成の場合は、$(Agent.BuildDirectory)のサブフォルダにC:\agent\_work\1\<リポジトリ名>というフォルダが作られ、その配下にチェックアウトされます。
ここの<リポジトリ名>はresourcesの- repository:で指定した名称が使われます。
複数リポジトリ構成でチェックアウトパスがデフォルトのままでは都合が悪い場合、pathを指定することで別フォルダへチェックアウトすることができます。
初回のリポジトリチェックアウトの認証
別リポジトリをチェックアウトする際に CI を初めて実行すると、チェックアウトするための承認が必要になります。 詳細は以下のリンクを参照してください。
初回だけの操作にはなりますが、手動で実施しなければならないため注意してください。
PR トリガーの挙動
PR(Pull Request) トリガーをブランチに指定していた場合、PR が作成されるとブランチの source と target を merge した結果が使用されます。
チェックアウトステップを使用した場合でも、PR トリガーを指定したリポジトリが merge した結果を使用するかどうか確認してみました。 イメージとしては以下のような構成です。

PR トリガーを指定するのが Repos1 リポジトリで、yamlファイルは Repos2 で管理しているような構成です。
master ブランチに対して feature/xxx のようなブランチを作り、Pull Request を作成するようにしています。
この場合でも、Repos1 PR トリガー実行時には feature/xxx と master を merge していました。

試してみた結果、システム全体で複数のリポジトリを使用する場合に想定されそうな運用パターンは結構網羅できていそうです。 具体的な挙動については実際に動かして確認するしかありませんが、すでにあるリポジトリに後から CI を構成するような場合は重宝しそうです。