查看管道中的多个存储库

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020

管道通常依赖于多个存储库,它们包含生成代码所需的源、工具、脚本或其他项。 通过在管道中使用多个 checkout 步骤,可以将其他存储库提取并签出到用于存储 YAML 管道之外的存储库。

指定多个存储库

存储库可以指定为存储库资源,也可以与 checkout 步骤内联。

支持以下存储库类型。


  • Azure DevOps Server(仅限于同一组织中的存储库)
  • Azure DevOps Services

GitHub (github)

  • Azure DevOps Services

GitHubEnterprise (githubenterprise)

  • Azure DevOps Services

Bitbucket 云 (bitbucket)

  • Azure DevOps Services

重要

Azure DevOps Server 中的多存储库签出仅支持与管道位于同一组织中的 Azure Repos Git (git) 存储库。

注意

Azure Pipelines 为 Azure Repos Git 存储库提供“限制作业范围”设置。 若要签出托管在另一个项目中的 Azure Repos Git 存储库,必须将“限制作业范围”配置为允许访问。 有关详细信息,请参阅限制作业授权范围

支持以下 checkout 步骤组合。


checkout 步骤

默认行为就好像 checkout: self 是第一步,并且当前存储库已签出。


一个 checkout: none 步骤

不会同步或签出任何存储库。


一个 checkout: self 步骤

当前存储库已签出。


一个不是 selfnonecheckout 步骤

指定的存储库已签出,而不是 self


多个 checkout 步骤

除非在 checkout 步骤中指定了其他 path,否则每个指定的存储库都会签出到以该存储库命名的文件夹。 要签出 self 作为存储库之一,请使用 checkout: self 作为 checkout 步骤之一。


注意

当你签出包含管道的存储库以外的 Azure Repos Git 存储库时,系统可能会提示你在管道首次运行之前授予对该资源的访问权限。 有关详细信息,请参阅常见问题解答部分中的当我首次尝试签出一个不同的存储库时,为何系统提示我对资源进行授权?

存储库资源定义

如果存储库类型需要服务连接或其他扩展资源字段,则必须使用存储库资源。 以下存储库类型需要服务连接。

存储库类型 服务连接
Bitbucket 云 Bitbucket 云
GitHub GitHub
GitHub Enterprise Server GitHub Enterprise Server
Azure Repos Git 存储库位于与管道不同的组织中 Azure Repos/Team Foundation Server

即使存储库类型不需要服务连接,也可以使用存储库资源,例如,如果已为不同存储库中的模板定义了存储库资源。

在下面的示例中,三个存储库声明为存储库资源。 另一个组织中的 Azure Repos Git 存储库GitHubBitbucket 云存储库资源需要服务连接,这些连接被指定为这些存储库资源的 endpoint。 此示例包含四个 checkout 步骤,用于签出声明为存储库资源的三个存储库以及包含管道 YAML 的当前 self 存储库。

resources:
  repositories:
  - repository: MyGitHubRepo # The name used to reference this repository in the checkout step
    type: github
    endpoint: MyGitHubServiceConnection
    name: MyGitHubOrgOrUser/MyGitHubRepo
  - repository: MyBitbucketRepo
    type: bitbucket
    endpoint: MyBitbucketServiceConnection
    name: MyBitbucketOrgOrUser/MyBitbucketRepo
  - repository: MyAzureReposGitRepository # In a different organization
    endpoint: MyAzureReposGitServiceConnection
    type: git
    name: OtherProject/MyAzureReposGitRepo

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- checkout: self
- checkout: MyGitHubRepo
- checkout: MyBitbucketRepo
- checkout: MyAzureReposGitRepository

- script: dir $(Build.SourcesDirectory)

如果 self 存储库名为 CurrentReposcript 命令将生成以下输出:CurrentRepo MyAzureReposGitRepo MyBitbucketRepo MyGitHubRepo。 在本示例中,由于签出步骤中未指定 path,因此对文件夹使用存储库名称(由存储库资源中的 name 属性指定)。 有关存储库文件夹名称和位置的详细信息,请参阅下面的签出路径部分。

内联语法签出

如果存储库不需要服务连接,则可按照 checkout 步骤声明它。

注意

只有同一组织中的 Azure Repos Git 存储库才能使用内联语法。 不同组织中的 Azure Repos Git 存储库和其他受支持的存储库类型需要服务连接并且必须声明为存储库资源

steps:
- checkout: self
- checkout: git://MyProject/MyRepo # Azure Repos Git repository in the same organization

注意

在前面的示例中,指定了 self 签出存储库,以便签出与管道关联的存储库的源。

如果使用默认的 Azure Repos Git 存储库(与项目同名),请使用格式 - checkout: git://MyProject/MyRepo

签出路径

除非在 checkout 步骤中指定了 path,否则源代码将放置在默认目录中。 此目录会有所不同,具体取决于你签出的是一个存储库还是多个存储库。

  • 一个存储库:如果作业中只有一个 checkout 步骤,或者没有等效于 checkout: self 的签出步骤,则源代码将签出到名为 s 的目录中,该目录作为 (Agent.BuildDirectory) 的子文件夹存在。 如果 (Agent.BuildDirectory)C:\agent\_work\1,代码将签出到 C:\agent\_work\1\s

  • 多个存储库:如果作业中有多个 checkout 步骤,源代码将作为 (Agent.BuildDirectory)s 的子文件夹签出到以存储库命名的目录中。 如果 (Agent.BuildDirectory)C:\agent\_work\1 并且存储库命名为 toolscode,则代码将签出到 C:\agent\_work\1\s\toolsC:\agent\_work\1\s\code

    注意

    如果在 checkout 步骤中未指定 path,则将存储库的名称(而不是用于在 checkout 步骤中引用存储库的 repository 值)用于文件夹。

如果为 checkout 步骤指定了 path,则使用该路径(相对于 (Agent.BuildDirectory))。

注意

如果使用默认路径,添加第二个存储库 checkout 步骤将更改第一个存储库的代码的默认路径。 例如,如果 tools 是唯一的存储库,名为 tools 的存储库的代码将签出到 C:\agent\_work\1\s,但如果添加了第二个存储库,tools 将签出到 C:\agent\_work\1\s\tools。 如果有任何步骤依赖于原始位置中的源代码,则必须更新这些步骤。

签出特定引用

除非指定特定的引用,否则将签出默认分支。

如果使用内联语法,请通过追加 @<ref> 来指定引用。 例如:

- checkout: git://MyProject/MyRepo@features/tools # checks out the features/tools branch
- checkout: git://MyProject/MyRepo@refs/heads/features/tools # also checks out the features/tools branch
- checkout: git://MyProject/MyRepo@refs/tags/MyTag # checks out the commit referenced by MyTag.

使用存储库资源时,请使用 ref 属性指定引用。 以下示例签出指定存储库的 features/tools/ 分支。

resources:
  repositories:
  - repository: MyGitHubRepo
    type: github
    endpoint: MyGitHubServiceConnection
    name: MyGitHubOrgOrUser/MyGitHubRepo
    ref: features/tools

steps:
- checkout: MyGitHubRepo

以下示例使用标记签出 MyTag 引用的提交。

resources:
  repositories:
  - repository: MyGitHubRepo
    type: github
    endpoint: MyGitHubServiceConnection
    name: MyGitHubOrgOrUser/MyGitHubRepo
    ref: refs/tags/MyTag

steps:
- checkout: MyGitHubRepo

触发器

在将更新推送到 self 存储库或声明为资源的任何存储库时,可以触发管道。 这在以下场景中很有用:

  • 你使用不同存储库中的工具或库。 每当更新工具或库时,你都希望为应用程序运行测试。
  • 你将 YAML 文件保存在与应用程序代码不同的存储库中。 每次将更新推送到应用程序存储库时,你都希望触发管道。

重要

存储库资源触发器仅适用于同一组织中的 Azure Repos Git 存储库,并且仅在 self 存储库类型为 Azure Repos Git 时适用。 它们不适用于 GitHub 或 Bitbucket 存储库资源。

存储库资源触发器不支持 batch

如果未在存储库资源中指定 trigger 部分,则对该存储库的更改不会触发管道。 如果指定了 trigger 部分,则触发行为类似于 CI 触发器在自存储库中的工作方式。

如果为多个存储库资源指定了一个 trigger 部分,则对其中任一资源的更改将启动新运行。

触发管道时,Azure Pipelines 必须确定应使用的 YAML 文件的版本以及应签出的每个存储库的版本。如果对 self 存储库的更改触发了管道,则触发管道的提交将用于确定 YAML 文件的版本。 如果对任何其他存储库资源的更改触发了管道,则使用 self 存储库的默认分支的最新版本的 YAML。

当对其中一个存储库的更新触发管道时,将根据触发存储库设置以下变量:

  • Build.Repository.ID
  • Build.Repository.Name
  • Build.Repository.Provider
  • Build.Repository.Uri
  • Build.SourceBranch
  • Build.SourceBranchName
  • Build.SourceVersion
  • Build.SourceVersionMessage

对于触发存储库,触发管道的提交将确定签出的代码的版本。对于其他存储库,YAML 中为该存储库资源定义的 ref 将确定签出的默认版本。

请考虑以下示例,其中 self 存储库包含 YAML 文件,存储库 AB 包含其他源代码。

trigger:
- main
- feature

resources:
  repositories:
  - repository: A
    type: git
    name: MyProject/A
    ref: main
    trigger:
    - main

  - repository: B
    type: git
    name: MyProject/B
    ref: release
    trigger:
    - main
    - release
steps:
- checkout: self
- checkout: A
- checkout: B

下表显示了使用上述 YAML 文件的管道为每个存储库签出的版本。

对下列项目所做的更改 是否管道触发 YAML 的版本 版本self 版本A 版本B
self 中的 main 从触发管道的 main 提交 从触发管道的 main 提交 最新,来自 main 最新,来自 release
self 中的 feature 从触发管道的 feature 提交 从触发管道的 feature 提交 最新,来自 main 最新,来自 release
A 中的 main 最新,来自 main 最新,来自 main 从触发管道的 main 提交 最新,来自 release
B 中的 main 最新,来自 main 最新,来自 main 最新,来自 main 从触发管道的 main 提交
B 中的 release 最新,来自 main 最新,来自 main 最新,来自 main 从触发管道的 release 提交

还可以在任何存储库中创建或更新拉取请求时触发管道。 为此,请在 YAML 文件中声明存储库资源(如上例所示),并在存储库(仅 Azure Repos)中配置分支策略。

存储库详细信息

签出多个存储库时,有关 self 存储库的一些详细信息以变量的形式提供。 使用多存储库触发器时,其中一些变量包含有关触发存储库的信息。 有关作业使用的所有存储库的详细信息可作为称为 resources.repositories模板上下文对象提供。

例如,若要获取非 self 存储库的引用,可以按照如下命令编写管道:

resources:
  repositories:
  - repository: other
    type: git
    name: MyProject/OtherTools

variables:
  tools.ref: $[ resources.repositories['other'].ref ]

steps:
- checkout: self
- checkout: other
- bash: |
    echo "Tools version: $TOOLS_REF"

常见问题解答

为什么我无法从另一个项目签出存储库? 这在过去可以。

Azure Pipelines 提供“将作业授权范围限制为当前项目”设置,如果启用该设置,则不允许管道访问包含管道的项目外部的资源。 可以在组织或项目级别设置此设置。 如果启用此设置,则无法检查另一项目中的存储库,除非显式授予访问权限。 有关详细信息,请参阅作业授权范围

当我首次尝试签出一个不同的存储库时,为何系统提示我对资源进行授权?

当你签出包含管道的存储库以外的 Azure Repos Git 存储库时,系统可能会提示你在管道首次运行之前授予对该资源的访问权限。 这些提示显示在管道运行摘要页上。

此管道需要访问资源的权限

对资源进行授权

选择“查看”或“对资源进行授权”,然后按照提示对资源进行授权。

正在等待审阅

允许访问

有关详细信息,请参阅 YAML 管道的授权故障排除