适用于 Git 存储库的管道选项

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

编辑使用 Git 存储库的管道期间(在 Azure DevOps 项目、GitHub、GitHub Enterprise Server、Bitbucket Cloud 或其他 Git 存储库中),可以使用以下选项。

功能 Azure Pipelines Azure DevOps Server 2019 及更高版本 TFS 2018
分支
clean
标记或标签源 项目;仅限经典 团队项目 团队项目
报表生成状态
签出子模块
从 LFS 签出文件
克隆第二个存储库
不同步源
浅提取

注意

单击“获取源”任务中的“高级设置”,以查看上面的一些选项。

分支

这是你希望在手动将此生成排队时作为默认分支的分支。 如果为生成设置计划触发器,则生成将从中获取最新源的分支。 通过持续集成 (CI) 触发生成时,默认分支没有任何影响。 通常会将此设置为与存储库默认分支相同(例如“主分支”)。

清理代理上的本地存储库

在生成运行之前,可以对自托管代理的工作目录执行不同形式的清理。

一般情况下,为了提高自托管代理的性能,请不要清理存储库。 在这种情况下,若要获得最佳性能,请确保同时以增量方式生成,方法是禁用用于生成的任务或工具的任何“清理”选项。

如果你确实需要清理存储库(例如,为了避免上次生成残留的文件造成问题),请使用以下选项。

注意

如果使用 Microsoft 托管代理,则清理无效,因为每次都会获得一个新代理。 使用自托管代理时,根据代理池的配置方式,你可能会在后续管道运行(或同一管道中的阶段或作业)中获得新代理,因此不清理不能保证后续运行、作业或阶段能够访问以前运行、作业或阶段的输出。

注意

使用自托管代理时,根据代理池的配置方式,你可能会在后续管道运行(或同一管道中的阶段或作业)中获得新代理,因此不清理不能保证后续运行、作业或阶段能够访问以前运行、作业或阶段的输出。 可以使用生成项目与后续运行、阶段或作业共享管道运行、阶段或作业的输出。

Azure Pipelines、Azure DevOps Server 2019 及更高版本

YAML 管道有几个不同的清理选项可用。

  • checkout 步骤有一个 clean 选项。 设置为 true 时,管道在提取存储库之前运行 execute git clean -ffdx && git reset --hard HEAD。 有关详细信息,请参阅签出
  • jobworkspace 设置具有多个清理选项(输出、资源、所有)。 有关详细信息,请参阅工作区
  • 管道设置 UI 具有“清理”设置,设置为 true 时,相当于为管道中的每个 checkout 步骤指定 clean: true配置“清理”设置:
    1. 编辑管道,选择 ...,然后选择触发器

      编辑触发器。

    2. 选择 YAML获取源,并配置所需的清理设置。 默认值为 true

      “清理”设置。

若要在手动运行管道时替代“清理”设置,可以使用运行时参数。 在以下示例中,运行时参数用于配置签出清理设置。

parameters:
- name: clean
  displayName: Checkout clean
  type: boolean
  default: true
  values:
  - false
  - true

trigger:
- main

pool: FabrikamPool
#  vmImage: 'ubuntu-latest'

steps:
- checkout: self
  clean: ${{ parameters.clean }}

默认情况下,clean 设置为 true,但可以在手动运行管道时重写,方法是通过取消选中为运行时参数添加的“签出清理”复选框。

标记源

你可能想要标记源代码文件,使团队能够轻松确定每个文件的哪个版本包含在已完成的生成中。 还可以选择指定是应为所有生成标记源代码,还是仅为成功的生成标记源代码。

注意

仅当生成的源存储库是 GitHub 存储库或项目中的 Git 或 TFVC 存储库时,才能使用此功能。

在“标签格式”中,可以使用范围为“全部”的用户定义变量和预定义变量。例如:

$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)_$(My.Variable)

前四个变量是预定义变量。 My.Variable 可以是你在“变量”选项卡上定义的变量。

生成管道使用 Git 标记标记源。

某些生成变量可能会生成不是有效标签的值。 例如,$(Build.RequestedFor)$(Build.DefinitionName) 等变量可以包含空格。 如果值包含空格,则不会创建标记。

生成管道标记源后,带有 Git 引用 refs/tags/{tag} 的项目会自动添加到已完成的生成中。 这为团队提供了额外的可跟踪性,并提供更加用户友好的方式来从生成导航到生成的代码。 标记被视为生成项目,因为它是由生成创建的。 手动或通过保留策略删除生成时,也会删除标记。

报表生成状态(Azure Pipelines、TFS 2018 及更高版本)

可以选择向团队提供远程源存储库中生成状态的视图。

如果源位于项目中的 Azure Repos Git 存储库中,则此选项会在“代码”页上显示一个锁屏提醒,以指示生成是通过还是失败。 生成状态显示在以下选项卡中:

  • 文件:指示所选分支的最新生成状态。
  • 提交:指示每个提交的生成状态(这需要为生成启用持续集成 (CI) 触发器)。
  • 分支:指示每个分支的最新生成状态。

如果在项目中对同一存储库使用多个生成管道,则可以选择为一个或多个管道启用此选项。 在多个管道上启用此选项的情况下,“代码”页上的锁屏提醒指示所有管道中最新生成的状态。 团队成员可以单击生成状态锁屏提醒,以查看每个生成管道的最新生成状态。

GitHub

如果源位于 GitHub 中,则此选项使用 GitHub 检查状态 API 将生成状态发布到 GitHub。 如果生成是从 GitHub 拉取请求触发的,则可以在 GitHub 拉取请求页上查看状态。 这还允许你在 GitHub 中设置状态策略并自动执行合并。 如果生成是由持续集成 (CI) 触发的,则可以在 GitHub 中的提交或分支上查看生成状态。

其他类型的 Git 远程存储库

如果源位于任何其他类型的远程存储库中,则无法使用 Azure Pipelines 或 TFS 自动将生成状态发布到该存储库。 但是,可以使用生成锁屏提醒在版本控制体验中集成和显示生成状态。

签出路径

如果要签出单个存储库,默认情况下,源代码将签出到名为 s 的目录中。 对于 YAML 管道,可以通过使用 path 指定 checkout 来更改此设置。 指定的路径是 $(Agent.BuildDirectory) 的相对路径。 例如:如果签出路径值为 mycustompath$(Agent.BuildDirectory)C:\agent\_work\1,则源代码将签出到 C:\agent\_work\1\mycustompath 中。

如果使用多个 checkout 步骤并签出多个存储库,并且未使用 path 显式指定文件夹,则每个存储库都放置在以存储库命名的 s 的子文件夹中。 例如,如果签出两个名为 toolscode 的存储库,则源代码将签出到 C:\agent\_work\1\s\toolsC:\agent\_work\1\s\code 中。

请注意,签出路径值不能设置为高于 $(Agent.BuildDirectory) 的任何目录级别,因此 path\..\anotherpath 将会产生有效的签出路径(即 C:\agent\_work\1\anotherpath),但 ..\invalidpath 这样的值则不会产生有效的签出路径(即 C:\agent\_work\invalidpath)。

如果使用多个 checkout 步骤并签出多个存储库,并且想要使用 path 显式指定文件夹,请考虑避免将路径设置为另一个签出步骤的路径的子文件夹(即 C:\agent\_work\1\s\repo1C:\agent\_work\1\s\repo1\repo2),否则,签出步骤的子文件夹将由另一个存储库的清理清除。 请注意,如果“清理”选项对于 repo1 为 true,则此情况有效)

注意

只能为 YAML 管道指定签出路径。 有关详细信息,请参阅 YAML 架构中的签出

签出子模块

选择是否要从子模块下载文件。 可以选择获取即时子模块或嵌套到任何递归深度的所有子模块。 如果要将 LFS 与子模块一起使用,请务必查看有关将 LFS 与子模块配合使用的说明

注意

有关用于签出子模块的 YAML 语法的详细信息,请参阅在 YAML 架构中签出

生成管道将签出 Git 子模块,只要它们是:

  • 未经身份验证:一个未经身份验证的公共存储库,无需凭据即可克隆或提取。

  • 已经过身份验证:

    • 包含在上面指定的 Git 存储库所在的同一项目、GitHub 组织或 Bitbucket 云帐户中。

    • 通过使用相对于主存储库的 URL 添加。 例如,将签出子模块:git submodule add /../../submodule.git mymodule;不会签出子模块:git submodule add https://dev.azure.com/fabrikamfiber/_git/ConsoleApp mymodule

经过身份验证的子模块

注意

确保已使用 HTTPS(而不是 SSH)注册了子模块。

代理用于从主存储库获取源的凭据也用于获取子模块的源。

如果主存储库和子模块位于 Azure DevOps 项目的 Azure Repos Git 存储库中,则可以选择用于访问源的帐户。 在“选项”选项卡上的“生成作业授权范围”菜单上,选择以下任一项:

  • 使用项目集合生成服务帐户的项目集合

  • 使用项目生成服务帐户的当前项目。

请确保使用的每个帐户都有权访问主存储库和子模块。

如果主存储库和子模块位于同一 GitHub 组织中,则存储在 GitHub 服务连接中的令牌用于访问源。

使用“签出子模块”选项的替代方法

在某些情况下,无法使用“签出子模块”选项。 你可能会遇到这样一种情况:需要一组不同的凭据才能访问子模块。 例如,如果主存储库和子模块存储库不存储在同一个 Azure DevOps 组织或 Git 服务中,则可能会发生这种情况。

如果无法使用“签出子模块”选项,则可以改用自定义脚本步骤来提取子模块。 首先,获取个人访问令牌 (PAT),并添加前缀 pat:。 接下来,对添加前缀后的字符串进行 base64 编码,以创建基本身份验证令牌。 最后,将此脚本添加到管道:

git -c http.https://<url of submodule repository>.extraheader="AUTHORIZATION: basic <BASE64_ENCODED_TOKEN_DESCRIBED_ABOVE>" submodule update --init --recursive

请务必将“<BASIC_AUTH_TOKEN>”替换为 Base64 编码的令牌。

在项目或生成管道中使用机密变量来存储生成的基本身份验证令牌。 使用该变量在上述 Git 命令中填充机密。

注意

问:为什么不能在代理上使用 Git 凭据管理器? 答:在专用生成代理上安装的 Git 凭据管理器中存储子模块凭据通常无效,因为每当更新子模块时,凭据管理器可能会提示你重新输入凭据。 当无法进行用户交互时,在自动生成期间,这是不可取的。

从 LFS 签出文件

选择是否要从大型文件存储 (LFS) 下载文件。

在经典编辑器中,选择复选框来启用此选项。

在 YAML 生成中,添加一个签出步骤,将 lfs 设置为 true

steps:
- checkout: self
  lfs: true

如果使用 TFS,或者将 Azure Pipelines 与自托管代理一起使用,则必须在代理上安装 git-lfs 才能使此选项生效。 如果托管代理使用 Windows,请考虑使用 System.PreferGitFromPath 变量,以确保管道使用计算机上安装的 git 和 git-lfs 版本。 有关详细信息,请参阅我的代理运行哪个版本的 Git?

将 Git LFS 与子模块配合使用

如果子模块包含 LFS 文件,则必须在签出子模块之前配置 Git LFS。 Microsoft 托管的 macOS 和 Linux 代理以这种方式进行预配置。 Windows 代理和自托管 macOS/Linux 代理可能不会。

作为解决方法,如果使用的是 YAML,则可以在 checkout 前面添加以下步骤:

steps:
- script: |
    git config --global --add filter.lfs.required true
    git config --global --add filter.lfs.smudge "git-lfs smudge -- %%f"
    git config --global --add filter.lfs.process "git-lfs filter-process"
    git config --global --add filter.lfs.clean "git-lfs clean -- %%f"
  displayName: Configure LFS for use with submodules
- checkout: self
  lfs: true
  submodules: true
# ... rest of steps ...

克隆第二个存储库

默认情况下,管道与来自 Azure Repos 或外部提供程序的一个存储库关联。 这是可以在提交和拉取请求时触发生成的存储库。

你可能希望在管道中包含来自第二个存储库的源。 可以通过编写脚本来执行此操作。

git clone https://github.com/Microsoft/TypeScript.git

如果存储库不是公共存储库,则需要将身份验证传递给 Git 命令。

Azure Repos

管道已有权访问其项目中的其他存储库,你可以使用脚本命令在管道中克隆它们,如以下示例所示。

- script: | 
    git clone -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" https://organization@dev.azure.com/project/FabrikamFiber/_git/reponame

可以使用多存储库签出在管道所在的同一项目中克隆多个存储库。

如果需要从另一个非公共项目克隆存储库,则需要以有权访问该项目的用户身份进行身份验证。

注意

使用机密变量安全地存储凭据。

机密变量不会自动作为环境变量提供给脚本。 请参阅机密变量,了解如何映射它们。

对于 Azure Repos,可以使用具有“代码(读取)”权限的个人访问令牌。 将此作为密码字段发送到“基本”授权标头中,不带用户名。 (换句话说,对 :<PAT> 的值进行 base64 编码,包括冒号。)

AUTH=$(echo -n ":$REPO_PAT" | openssl base64 | tr -d '\n')
git -c http.<repo URL>.extraheader="AUTHORIZATION: basic $AUTH" clone <repo URL> --no-checkout --branch master

不同步源

非部署作业会自动提取源。 如果要跳过该行为,请使用此选项。 此选项在需要执行以下操作的情况下非常有用:

  • 使用自己的自定义选项进行 Git 初始化、配置和提取。

  • 使用生成管道仅运行不依赖于版本控制中的代码的自动化(例如,某些脚本)。

如果要禁用下载源:

  • Azure Pipelines、TFS 2018 及更高版本:单击“高级设置”,然后选择“不同步源”。

注意

使用此选项时,代理还会跳过运行清理存储库的 Git 命令。

浅提取

如果要限制下载历史记录的时间,请选择此选项。 这实际上会导致 git fetch --depth=n。 如果存储库很大,此选项可能会提高生成管道的效率。 如果存储库已长期使用并且具有相当大的历史记录,则存储库可能很大。 如果添加并随后删除了大型文件,则它也可能很大。

在这些情况下,此选项有助于节省网络和存储资源。 它还可以节省时间。 但它并不是一定会节省时间,原因是,在某些情况下,服务器可能需要花时间计算要为指定深度下载的提交。

注意

将生成排队时,要生成的分支将解析为提交 ID。 然后,代理提取分支并签出所需的提交。 分支解析为提交 ID 和代理执行签出之间有一小段时间。 如果分支快速更新,并且你为浅提取设置非常小的值,则当代理尝试签出提交时,提交可能不存在。如果发生这种情况,请增加浅提取深度设置。

选中复选框启用此选项后,在“深度”框中指定提交数。

提示

下面提到的 Agent.Source.Git.ShallowFetchDepth 变量也有效,并替代复选框控件。 这样,就可以在生成排队时修改设置。

首选路径中的 Git

默认情况下,Windows 代理使用与代理软件捆绑在一起的 Git 版本。 Microsoft 建议使用与代理捆绑在一起的 Git 版本,但有多个选项可以替代此默认行为,并使用代理计算机在路径中安装的 Git 版本。

  • 在管道中将名为 System.PreferGitFromPath 的管道变量设置为 true
  • 在自托管代理上,可以在代理根目录中创建名为 .env 的文件,并在文件中添加 System.PreferGitFromPath=true 行。 有关详细信息,请参阅如何为每个单独的代理设置不同的环境变量?

若要查看管道使用的 Git 版本,可以查看管道中 checkout 步骤的日志,如以下示例所示。

Syncing repository: PathFilter (Git)
Prepending Path environment variable with directory containing 'git.exe'.
git version
git version 2.26.2.windows.1

在非 Windows 代理上,此设置始终为 true。

其他 Git 的触发器选项

指定其他/外部 Git 存储库时,CI 生成要求可以从 Internet 访问该存储库。 如果存储库位于防火墙或代理后面,则只有计划和手动生成才能正常工作。

常见问题解答

生成代理可以将哪些协议与 Git 配合使用?

代理支持 HTTPS。

代理尚不支持 SSH。 请参阅在签出 Git 子模块时允许生成使用 SSH 身份验证

我在本地使用 TFS,但没有看到其中某些功能。 为什么看不到?

其中某些功能仅在 Azure Pipelines 上可用,在本地尚不可用。 如果你已升级到最新版本的 TFS,则可在本地使用这些功能。