适用于 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
。 有关详细信息,请参阅签出。job
的workspace
设置具有多个清理选项(输出、资源、所有)。 有关详细信息,请参阅工作区。- 管道设置 UI 具有“清理”设置,设置为 true 时,相当于为管道中的每个
checkout
步骤指定clean: true
。 配置“清理”设置:编辑管道,选择 ...,然后选择触发器。
选择 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
的子文件夹中。 例如,如果签出两个名为 tools
和 code
的存储库,则源代码将签出到 C:\agent\_work\1\s\tools
和 C:\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\repo1
和 C:\agent\_work\1\s\repo1\repo2
),否则,签出步骤的子文件夹将由另一个存储库的清理清除。 请注意,如果“清理”选项对于 repo1
为 true,则此情况有效)
签出子模块
选择是否要从子模块下载文件。 可以选择获取即时子模块或嵌套到任何递归深度的所有子模块。 如果要将 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,则可在本地使用这些功能。