构建 GitHub 存储库

Azure Pipelines

Azure Pipelines 可以自动生成并验证每个拉取请求并提交到 GitHub 存储库。 本文介绍如何配置 GitHub 和 Azure Pipelines 之间的集成。

如果你不熟悉 Azure Pipelines 与 GitHub 的集成,请按照创建第一个管道中的步骤,使你的第一个管道使用 GitHub 存储库,然后返回到本文,详细了解如何配置和自定义 GitHub 与 Azure Pipelines 之间的集成。

组织和用户

GitHub 和 Azure Pipelines 是两个独立的服务,可以很好地集成在一起。 每个用户都有自己的组织和用户管理。 本部分对如何将组织和用户从 GitHub 复制到 Azure Pipelines 提出建议。

组织

GitHub 的结构包含了包含存储库组织和用户帐户。 请参阅GitHub 的文档

GitHub organization structure

Azure DevOps "结构包含包含项目组织。 请参阅 规划组织结构

Azure DevOps organization structure

Azure DevOps 可以通过以下方式反映 GitHub 结构:

  • GitHub组织或用户帐户的 Azure DevOps组织
  • Azure DevOps GitHub存储库项目

GitHub structure mapped to Azure DevOps

若要在 Azure DevOps 中设置相同的结构:

  1. 创建一个名为 GitHub 组织或用户帐户的 Azure DevOps 组织。 它将具有类似的 URL https://dev.azure.com/your-organization
  2. 在 Azure DevOps 组织中,创建名为的项目存储库。 它们的 Url 类似于 https://dev.azure.com/your-organization/your-repository
  3. 在 Azure DevOps Project 中,创建在其生成的 GitHub 组织和存储库之后命名的管道,例如 your-organization.your-repository 。 然后,可以清楚地了解这些存储库。

按照此模式,你的 GitHub 存储库和 Azure DevOps 项目将具有匹配的 URL 路径。 例如:

服务 URL
GitHub https://github.com/python/cpython
Azure DevOps https://dev.azure.com/python/cpython

用户

GitHub 用户不会自动访问 Azure Pipelines。 Azure Pipelines 不知道 GitHub 标识。 出于此原因,无法将 Azure Pipelines 配置为使用其 GitHub 标识和电子邮件地址自动通知用户生成失败或 PR 验证失败。 你必须在 Azure Pipelines 中显式创建新用户以复制 GitHub 用户。 创建新用户后,你可以在 Azure DevOps 中配置其权限,以反映其在 GitHub 中的权限。 你还可以使用 Azure DevOps 中的 Azure DevOps 标识配置通知。

GitHub 组织角色

GitHub 组织成员角色可在 https://github.com/orgs/your-organization/people (replace your-organization) 找到。

(replace) Azure DevOps 组织成员权限 https://dev.azure.com/your-organization/_settings/securityyour-organization

GitHub 组织中的角色和 Azure DevOps 组织中的等效角色如下所示。

GitHub 组织角色 Azure DevOps 组织等效项
“所有者” 成员 Project Collection Administrators
账单管理员 成员 Project Collection Administrators
成员 的成员 Project Collection Valid Users 。 默认情况下,此组无权创建新项目。 若要更改此设置,请将组的 Create new projects 权限设置为 Allow ,或创建具有所需权限的新组。

GitHub 用户帐户角色

GitHub 用户帐户具有一个角色,该角色是帐户的所有权。

(replace) Azure DevOps 组织成员权限 https://dev.azure.com/your-organization/_settings/securityyour-organization

GitHub 用户帐户角色映射到 Azure DevOps 组织权限,如下所示。

GitHub 用户帐户角色 Azure DevOps 组织等效项
“所有者” 成员 Project Collection Administrators

GitHub 存储库权限

GitHub 存储库权限,请参阅 https://github.com/your-organization/your-repository/settings/collaboration (replace your-organization and your-repository) 。

Azure DevOps 项目权限位于 https://dev.azure.com/your-organization/your-project/_settings/security (replace your-organization and your-project) 。

GitHub 存储库和 Azure DevOps 项目之间的等效权限如下所示。

GitHub 存储库权限 Azure DevOps 项目等效项
管理员 成员 Project Administrators
写入 成员 Contributors
读取 成员 Readers

如果你的 GitHub 存储库授予团队权限,你可以在 Azure DevOps 项目设置的部分中创建匹配的团队 Teams 。 然后,将团队添加到上述安全组,就像用户一样。

特定于管道的权限

若要向用户或团队授予 Azure DevOps 项目中特定管道的权限,请执行以下步骤:

  1. 请访问项目的 Pipelines 页面 (例如, https://dev.azure.com/your-organization/your-project/_build) 。
  2. 选择要为其设置特定权限的管道。
  3. 从 "..." 上下文菜单中,选择 " 安全性"。
  4. 单击 " 添加 ... " 添加特定的用户、团队或组,并为管道自定义其权限。

访问 GitHub 存储库

首先选择 GitHub 存储库,然后选择该存储库中的 YAML 文件,即可创建新的管道。 存在 YAML 文件的存储库称为 self 存储库。 默认情况下,这是管道生成的存储库。

稍后可将管道配置为查看其他存储库或多个存储库。 若要了解如何执行此操作,请参阅多存储库 结帐

必须授予 Azure Pipelines 访问你的存储库的访问权限,以触发其生成并在生成过程中提取其代码。

创建管道时,有3种身份验证类型可授予对 GitHub 存储库的 Azure Pipelines 访问权限。

身份验证类型 Pipelines 使用运行 GitHub 检查一起工作
1. GitHub 应用 Azure Pipelines 标识
2. OAuth 个人 GitHub 标识
3.PAT (个人) 个人GitHub标识

GitHub应用身份验证

建议Azure Pipelines GitHub集成管道的身份验证类型是应用应用。 通过在你的GitHub或组织中安装 GitHub 应用,管道无需使用个人标识即可GitHub运行。 使用GitHub标识执行生成Azure Pipelines状态更新。 该应用与 GitHub检查一起工作,以在应用程序中显示生成、测试和代码覆盖率GitHub。

若要使用 GitHub 应用,请将其安装在GitHub或用户帐户中,用于某些或所有存储库。 可以从GitHub主页 安装和卸载应用

安装后,GitHub应用Azure Pipelines为存储库创建管道时GitHub (而不是 OAuth) 的默认身份验证方法。

如果为 GitHub 组织的所有存储库安装 GitHub 应用,则无需担心Azure Pipelines批量电子邮件或代表你自动设置管道。 作为为所有存储库安装应用的替代方法,存储库管理员可以为各个存储库一次安装一个应用。 这要求管理员完成更多工作,但没有任何优点和缺点。

管理中所需的GitHub

安装Azure Pipelines GitHub应用需要成为GitHub所有者或存储库管理员。此外,若要为具有持续集成GitHub请求触发器的存储库创建管道,必须配置GitHub权限。 否则 ,创建管道时 ,存储库将不会显示在存储库列表中。 根据存储库的身份验证类型和所有权,确保配置适当的访问权限。

  • 如果存储库位于个人GitHub帐户,Azure Pipelines GitHub个人帐户安装 GitHub 应用。 在 Azure Pipelines 中创建管道时,你将能够列出Azure Pipelines。

  • 如果存储库位于其他人的个人GitHub帐户,则另一个人必须在其个人Azure Pipelines GitHub应用GitHub应用。 必须在存储库设置中的"协作者"下添加为协作者。 使用通过电子邮件发送给你的链接接受邀请,成为协作者。 完成后,可以为此存储库创建管道。

  • 如果存储库位于你拥有GitHub组织中,则Azure Pipelines GitHub组织安装 GitHub 应用。 还必须在存储库的"协作者和团队"下的设置中将你添加为协作者,或者必须添加团队。

  • 如果存储库位于其他人拥有GitHub组织中,GitHub组织所有者或存储库管理员必须在组织中安装 Azure Pipelines GitHub 应用。 必须将你添加为协作者,或者必须将你的团队添加到存储库的"协作者和团队"下的设置中。 使用通过电子邮件发送给你的链接接受邀请,成为协作者。

GitHub应用权限

安装GitHub应用请求以下权限:

权限 Azure Pipelines功能
对代码的写入访问权限 只有在你有意采取Azure Pipelines,用户才能将 YAML 文件提交到存储库的选定分支,从而GitHub管道。
对元数据的读取访问权限 Azure Pipelines检索GitHub元数据,以在生成摘要中显示与生成关联的存储库、分支和问题。
对检查的读取和写入访问权限 Azure Pipelines读取和写入自己的生成、测试和代码覆盖率结果,以在GitHub。
对拉取请求的读取和写入访问权限 只有在你有意Azure Pipelines,用户才能为已提交到存储库的选定分支的 YAML 文件创建拉取请求,从而GitHub管道。 Azure Pipelines检索拉取请求元数据,以显示在与拉取请求关联的生成摘要中。

应用GitHub疑难解答

GitHub可能会显示如下错误:

You do not have permission to modify this app on your-organization. Please contact an Organization Owner.

这意味着,GitHub应用可能已安装在组织中。 为组织中存储库创建管道时,GitHub应用将自动用于连接到 GitHub。

在多个组织与项目中Azure DevOps管道

安装 GitHub 应用后,可以在不同的组织和项目中为组织的存储库Azure DevOps管道。 但是,如果在多个 Azure DevOps 组织中为单个存储库创建管道,则只有第一个组织的管道才能自动触发GitHub或拉取请求。 辅助组织仍可手动或计划Azure DevOps生成。

OAuth 身份验证

OAuth是适用于个人帐户和帐户中存储库的最简单GitHub类型。 GitHub状态更新将代表你的个人标识GitHub更新。 若要使管道保持工作状态,存储库访问必须保持活动状态。 某些GitHub功能(如检查)在 OAuth 中不可用,需要GitHub应用。

若要使用 OAuth, 请在 创建管道时单击存储库列表下面的"选择其他连接"。 然后,单击"授权"登录到GitHub OAuth 进行授权。 OAuth 连接将保存在 Azure DevOps项目中供以后使用,并用于正在创建的管道中。

管理中所需的GitHub

若要为具有持续集成GitHub请求触发器的存储库创建管道,必须配置GitHub权限。 否则 ,创建管道时 ,存储库将不会显示在存储库列表中。 根据存储库的身份验证类型和所有权,确保配置适当的访问权限。

  • 如果存储库位于个人GitHub帐户,请至少GitHub个人帐户凭据通过 OAuth GitHub进行身份验证。 此操作可以在"新建服务连接 > Azure DevOps"下Pipelines"新建 > 服务连接"下GitHub >> 完成。 在此处Azure Pipelines"权限"下授予对存储库的访问权限

  • 如果存储库位于其他人的个人GitHub帐户,则另一人必须至少使用其个人帐户凭据GitHub OAuth GitHub进行身份验证。 此操作可以在"新建服务连接 > Azure DevOps"下Pipelines"新建 > 服务连接"下GitHub >> 完成。 其他人必须在此处的Azure Pipelines权限"下授予对存储库的访问权限。 必须在存储库设置中的"协作者"下添加为协作者。 使用通过电子邮件发送给你的链接接受邀请,成为协作者。

  • 如果存储库位于你拥有GitHub组织中,请至少使用个人帐户凭据GitHub OAuth GitHub进行身份验证。 此操作可以在"新建服务连接 > Azure DevOps"下Pipelines"新建 > 服务连接"下GitHub >> 完成。 在此处Azure Pipelines"组织访问权限"下授予对组织的访问权限。 必须将你添加为协作者,或者必须将你的团队添加到存储库的"协作者和团队"下的设置中。

  • 如果存储库位于其他人拥有GitHub组织中,则 GitHub 组织所有者必须使用其个人 GitHub 帐户凭据通过 OAuth 向 GitHub 进行身份验证。 此操作可以在"新建服务连接 > Azure DevOps"下Pipelines"新建 > 服务连接"下GitHub >> 完成。 组织所有者必须在此处 Azure Pipelines"组织访问权限"下授予对组织的访问权限。 必须将你添加为协作者,或者必须将你的团队添加到存储库的"协作者和团队"下的设置中。 使用通过电子邮件发送给你的链接接受邀请,成为协作者。

撤销 OAuth 访问权限

授权用户Azure Pipelines OAuth 后,若要稍后撤销它并防止其进一步使用,请访问应用程序设置中的OAuth GitHub应用。 还可以将其从项目设置GitHub服务连接Azure DevOps列表中。

PAT 身份验证 (个人) 令牌

PAT实际上与 OAuth 相同,但允许控制向用户授予哪些Azure Pipelines。 生成GitHub状态更新将代表你的个人标识GitHub更新。 若要使生成保持工作状态,存储库访问必须保持活动状态。

若要创建 PAT,请访问用户设置中的个人GitHub令牌。 所需的权限为 repoadmin:repo_hookread:user 、、 和 user:email 。 这些权限与上述使用 OAuth 时所需的权限相同。 将生成的 PAT 复制到剪贴板,并将其粘贴GitHub项目设置中的新 Azure DevOps 服务连接。 对于将来的召回,请为服务连接命名,GitHub用户名。 它将在项目Azure DevOps供以后在创建管道时使用。

管理中所需的GitHub

若要为具有持续集成GitHub请求触发器的存储库创建管道,必须配置GitHub权限。 否则 ,创建管道时 ,存储库将不会显示在存储库列表中。 根据存储库的身份验证类型和所有权,确保配置以下访问权限。

  • 如果存储库位于个人访问GitHub帐户,则 PAT 必须在"个人访问令牌"下具有所需的访问范围:、、 和 admin:repo_hookread:useruser:email

  • 如果存储库位于其他人的个人GitHub帐户,则 PAT 必须在"个人访问令牌"下具有所需的访问范围 :、、 和 admin:repo_hookread:useruser:email 。 必须在存储库设置中的"协作者"下添加为协作者。 使用通过电子邮件发送给你的链接接受邀请,成为协作者。

  • 如果存储库位于你拥有GitHub组织中,则 PAT 必须在"个人访问令牌"下具有所需的访问范围 :、、 和 admin:repo_hookread:useruser:email 。 必须将你添加为协作者,或者必须将你的团队添加到存储库的"协作者和团队"下的设置中。

  • 如果存储库位于其他人拥有GitHub组织中,则 PAT 必须在"个人访问令牌"下具有所需的访问范围 :、、 和 admin:repo_hookread:useruser:email 。 必须将你添加为协作者,或者必须将你的团队添加到存储库的"协作者和团队"下的设置中。 使用通过电子邮件发送给你的链接接受邀请,成为协作者。

撤销 PAT 访问权限

授权Azure Pipelines PAT 后,若要稍后删除它并防止其进一步使用,请访问 GitHub设置中的个人访问令牌。 还可以将其从项目设置GitHub服务连接Azure DevOps列表中。

CI 触发器

每当将 (推送到指定的分支或推送指定的标记时,CI) 触发器的持续集成会导致管道运行。

默认情况下,YAML 管道在所有分支上都配置有 CI 触发器。

分支

可以使用简单的语法控制哪些分支获取 CI 触发器:

trigger:
- master
- releases/*

可以指定分支的全名 (例如,) 或通配符 master (,例如 releases/*) 。 有关 通配符语法 的信息,请参阅通配符。

注意

不能在触发器 使用变量,因为变量在运行时计算 (触发器触发后) 。

注意

如果使用模板 创作 YAML 文件,则只能在管道的主 YAML 文件中指定触发器。 不能在模板文件中指定触发器。

对于使用 或 的更复杂的 exclude 触发器 batch ,必须使用完整语法,如以下示例所示。

# specific branch build
trigger:
  branches:
    include:
    - master
    - releases/*
    exclude:
    - releases/old*

在以上示例中,如果将更改推送到 master 或任何发布分支,将触发管道。 但是,如果对以 开头的发布分支进行了更改,将不会触发它 old

如果指定不带 exclude 子句的 include 子句,则等效于在 子句 * 中指定 include

除了在列表中指定分支名称外,还可使用以下格式基于标记 branches 配置触发器:

trigger:
  branches:
    include:
      - refs/tags/{tagname}
    exclude:
      - refs/tags/{othertagname}

如果未指定任何触发器,则默认值为,就像已编写了:

trigger:
  branches:
    include:
    - '*'  # must quote since "*" is a YAML reserved character; we want a string

重要

指定触发器时,它将替换默认的隐式触发器,并且只有推送到显式配置为包含的分支才能触发管道。 首先处理包含,然后从该列表中删除排除项。

批处理 CI 运行

如果经常有许多团队成员上传更改,可能需要减少启动的运行数。 如果设置为 ,则当管道运行时,系统会等待运行完成,然后启动另一个运行,并生成所有 batchtrue 尚未生成的更改。

# specific branch build with batching
trigger:
  batch: true
  branches:
    include:
    - master

为了阐明此示例,假设推送到 A master 导致上述管道运行。 当该管道正在运行时,其他推送 BC 和将进入存储库。 这些更新不会立即开始新的独立运行。 但是,第一次运行完成后,直到该时间点的所有推送将一起批处理,并启动新的运行。

注意

如果管道具有多个作业和阶段,则第一次运行仍应该通过完成或跳过其所有作业和阶段来达到终端状态,然后第二次运行才能开始。 因此,在具有多个阶段或审批的管道中使用此功能时,必须小心。 如果希望在这种情况下对生成进行批处理,建议将 CI/CD 过程拆分为两个管道 - 一个管道用于生成 (批处理) 一个管道用于部署。

路径

可以指定要包含或排除的文件路径。

# specific path build
trigger:
  branches:
    include:
    - master
    - releases/*
  paths:
    include:
    - docs
    exclude:
    - docs/README.md

指定路径时,必须显式指定要触发的分支。 不能只触发包含路径筛选器的管道;还必须具有分支筛选器,并且与路径筛选器匹配的已更改文件必须来自与分支筛选器匹配的分支。

提示:

  • 始终相对于存储库的根目录指定路径。
  • 如果未设置路径筛选器,则默认情况下隐式包含存储库的根文件夹。
  • 如果排除路径,则也不能包含它,除非将其限定为更深层的文件夹。 例如,如果排除 /tools, 可以包括 /tools/trigger-runs-on-these
  • 路径筛选器的顺序并不重要。
  • Git 中的 路径区分大小写。 请确保使用与实际文件夹相同的大小写。
  • 不能在路径 使用变量,因为变量在运行时计算 (触发器触发后) 。

标记

除了在列表中指定标记(如上一部分所述)外, branches 还可以直接指定要包括或排除的标记:

# specific tag
trigger:
  tags:
    include:
    - v2.*
    exclude:
    - v2.0

如果未指定任何标记触发器,则默认情况下,标记不会触发管道。

重要

如果结合分支筛选器指定标记,则如果满足分支筛选器或满足标记筛选器,则触发器将触发。 例如,如果推送的标记满足分支筛选器,则即使标记被标记筛选器排除,管道也触发,因为推送满足分支筛选器。

选择退出 CI

禁用 CI 触发器

可以通过指定 来完全选择退出 CI 触发器 trigger: none

# A pipeline with no CI trigger
trigger: none

重要

将更改推送到分支时,将评估该分支中的 YAML 文件,以确定是否应启动 CI 运行。

有关详细信息,请参阅YAML架构 中的触发器。

跳过单个提交 CI

还可以告知Azure Pipelines跳过运行提交通常会触发的管道。 只需在提交消息或 HEAD 提交说明中包括 [skip ci] ,Azure Pipelines将跳过运行 CI。 还可使用以下任何变体。

  • [skip ci][ci skip]
  • skip-checks: trueskip-checks:true
  • [skip azurepipelines][azurepipelines skip]
  • [skip azpipelines][azpipelines skip]
  • [skip azp][azp skip]
  • ***NO_CI***

在条件中使用触发器类型

根据启动运行的触发器类型,在管道中运行不同的步骤、作业或阶段是一种常见方案。 可以使用系统变量 来这样做 Build.Reason 。 例如,将以下条件添加到步骤、作业或阶段,以将其从 PR 验证中排除。

condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))

创建新分支时触发器的行为

为同一存储库配置多个管道很常见。 例如,你可能有一个管道为应用生成文档,另一个管道用于生成源代码。 可以使用每个管道中的相应分支筛选器和路径筛选器配置 CI 触发器。 例如,你可能希望一个管道在将更新推送到 文件夹时触发,另一个管道在将更新推送到 docs 应用程序代码时触发。 在这些情况下,你需要了解如何在新建分支时触发管道。

下面是推送与存储库的分支筛选器 (分支筛选器) 的行为:

  • 如果管道具有路径筛选器,则只有在新分支对匹配该路径筛选器的文件进行更改时,才触发该管道。
  • 如果管道没有路径筛选器,则即使新分支中未发生更改,也会触发该筛选器。

通配符

指定分支或标记时,可以使用确切的名称或通配符。 通配符模式允许 * 匹配零个或多个字符以及 ? 匹配单个字符。

  • 如果在 YAML 管道中通过 启动模式,则必须将模式括 * 在引号中,如 "*-releases"
  • 对于分支、标记和路径,通配符可能出现在模式中的任何位置。
trigger:
  branches:
    include:
    - master
    - releases/*
    - feature/*
    exclude:
    - releases/old*
    - feature/*-working
  paths:
    include:
    - docs/*.md

PR 触发器

拉取 (PR) 触发器会导致管道在通过指定的目标分支之一打开拉取请求时或对此类拉取请求进行更新时运行。

分支

验证拉取请求时,可以指定目标分支。 例如,若要验证以 和 为目标的拉取请求 masterreleases/* ,可以使用以下 pr 触发器。

pr:
- master
- releases/*

首次创建新的拉取请求时,以及每次更新拉取请求后,此配置都会启动新的运行。

可以指定分支的全名 (例如,) 或通配符 master (,例如 releases/*) 。

注意

不能在触发器 使用变量,因为变量在运行时计算 (触发器触发后) 。

注意

如果使用模板 创作 YAML 文件,则只能在管道的主 YAML 文件中指定触发器。 不能在模板文件中指定触发器。

GitHub拉取请求时创建新的 ref。 ref 指向 合并提交,这是拉取请求的源分支和目标分支之间的合并代码。 PR 验证管道生成此引用指向的提交。 这意味着用于运行管道的 YAML 文件也是源分支和目标分支之间的合并。 因此,对拉取请求的源分支中的 YAML 文件所做的更改可能会替代目标分支中 YAML 文件定义的行为。

如果 YAML 文件中未显示任何触发器,则会自动针对所有分支启用拉取请求 pr 验证,就像编写了以下 pr 触发器一样。 创建任何拉取请求时,以及提交进入任何活动拉取请求的源分支时,此配置将触发生成。

pr:
  branches:
    include:
    - '*'  # must quote since "*" is a YAML reserved character; we want a string

重要

指定具有分支子集的触发器时,只有在将更新推送到这些分支 pr 时,才触发管道。

对于需要排除某些分支的更复杂的触发器,必须使用完整语法,如以下示例所示。

# specific branch
pr:
  branches:
    include:
    - master
    - releases/*
    exclude:
    - releases/old*

路径

可以指定要包含或排除的文件路径。 例如:

# specific path
pr:
  branches:
    include:
    - master
    - releases/*
  paths:
    include:
    - docs
    exclude:
    - docs/README.md

提示:

  • 路径筛选器不支持通配符。
  • 始终相对于存储库的根目录指定路径。
  • 如果未设置路径筛选器,则默认情况下隐式包含存储库的根文件夹。
  • 如果排除路径,则也不能包含它,除非将其限定为更深层的文件夹。 例如,如果排除 /tools, 可以包括 /tools/trigger-runs-on-these
  • 路径筛选器的顺序并不重要。
  • Git 中的 路径区分大小写。 请确保使用与实际文件夹相同的大小写。
  • 不能在路径 使用变量,因为变量在运行时计算 (触发器触发后) 。

多个 PR 更新

可以指定 PR 的其他更新是否应该取消同一 PR 的正在进行中的验证运行。 默认为 true

# auto cancel false
pr:
  autoCancel: false
  branches:
    include:
    - master

PR 验证草稿

默认情况下,拉取请求触发器在草稿拉取请求以及已准备好审阅的拉取请求时触发。 若要禁用草稿拉取请求的拉取请求触发器,将 drafts 属性设置为 false

pr:
  autoCancel: boolean # indicates whether additional pushes to a PR should cancel in-progress runs for the same PR. Defaults to true
  branches:
    include: [ string ] # branch names which will trigger a build
    exclude: [ string ] # branch names which will not
  paths:
    include: [ string ] # file paths which must match to trigger a build
    exclude: [ string ] # file paths which will not trigger a build
  drafts: boolean # whether to build draft PRs, defaults to true

选择退出 PR 验证

可以通过指定 来完全选择退出拉取请求验证 pr: none

# no PR triggers
pr: none

有关详细信息,请参阅 YAML 架构 中的 PR 触发器

注意

如果 pr 触发器未触发,请按照常见问题解答 中的故障排除 pr

注意

草稿拉取 请求不会触发管道。

受保护的分支

可以使用面向分支的每个提交或拉取请求运行验证生成,甚至可以阻止拉取请求合并,直到验证生成成功。

若要为存储库配置GitHub验证版本,你必须是其所有者、具有管理员角色的协作者或具有"写入GitHub的组织成员。

  1. 首先,为存储库创建一个管道并至少生成一次,以便其状态GitHub,从而GitHub管道的名称。

  2. 接下来,GitHub在存储库设置中配置受保护分支的文档。

    对于状态检查,请在"状态检查"列表中选择 管道 的名称。

    GitHub pipeline status check

重要

如果管道未在此列表中显示,请确保以下各项:

来自外部源的贡献

如果GitHub存储库是开源的,可以将你的 Azure DevOps 项目公开,以便任何人都可以在不登录的情况下查看管道的生成结果、日志和测试结果。 组织外部的用户创建存储库分支并提交拉取请求时,可以查看自动验证这些拉取请求的生成状态。

接受来自外部源的贡献时,在公共Azure Pipelines时,请记住以下注意事项。

访问限制

在公共项目中运行管道时,请注意Azure DevOps限制:

  • 秘密: 默认情况下,与管道关联的机密不可用于请求验证分叉。 请参阅 验证分叉的贡献
  • 跨项目访问:公共项目中的所有Azure DevOps都使用仅限该项目的访问令牌运行。 Pipelines项目中的用户可以访问资源,例如仅在项目中访问生成项目或测试结果,而无法访问组织Azure DevOps项目。
  • Azure Artifacts 包:如果管道需要从 Azure Artifacts 访问包,则必须显式授予Project 生成服务帐户访问包源的权限。

分叉的贡献

重要

这些设置会影响管道的安全性。

创建管道时,会自动为存储库的分支中的拉取请求触发该管道。 您可以更改此行为,仔细考虑它如何影响安全性。 若要启用或禁用此行为:

  1. 中转到 Azure DevOps 项目。 选择Pipelines,找到你的管道,然后选择 "编辑"。
  2. 选择 " 触发器 " 选项卡。启用 拉取请求触发器后,启用或禁用 " 从该存储库的分支生成拉取请求 " 复选框。

默认情况下,对于 GitHub 管道,与生成管道关联的机密不会提供给分叉请求生成。 默认情况下,GitHub Enterprise 服务器管道启用这些机密。 机密包括:

  • 一个安全令牌,可访问你的 GitHub 存储库。
  • 如果管道使用这些项,则这些项:

若要跳过对 GitHub 管道的这一预防措施,请启用 "使机密可用于生成分支" 复选框。 请注意,此设置对安全性的影响。

重要的安全注意事项

GitHub 用户可以分叉你的存储库、对其进行更改,并创建拉取请求来建议对存储库进行更改。 此拉取请求可能包含要作为触发生成的一部分运行的恶意代码。 此类代码可能会导致以下问题:

  • 泄露管道中的机密。 若要缓解这种风险,如果你的存储库是公共的或不受信任的用户可以提交自动触发生成的拉取请求,则不要启用 " 为分叉提供机密 " 复选框。 默认已禁用此选项。

  • 危害运行代理的计算机从其他管道盗取代码或机密。 缓解此操作:

    • 使用 Microsoft 托管的代理池 生成来自分支的拉取请求。 Microsoft 托管的代理计算机在完成构建后会立即被删除,因此,如果这些计算机泄露,就不会产生持久的影响。

    • 如果你必须使用 自承载代理,则不要在同一代理上存储任何机密或执行使用机密的其他生成和发布,除非你的存储库是专用的并且你信任拉取请求创建者。

注释触发器

存储库协作者可以对拉取请求进行注释以手动运行管道。 下面是你可能想要执行此操作的几个常见原因:

  • 你可能不希望从未知用户自动构建拉取请求,直到可以查看其更改。 您希望您的一个团队成员首先查看其代码,然后运行该管道。 在从分叉的存储库生成提供的代码时,这通常用作一种安全措施。
  • 你可能想要运行一个可选的测试套件或其他验证生成。

若要启用注释触发器,必须执行以下两个步骤:

  1. 为管道启用拉取请求触发器,并确保未排除目标分支。
  2. 在 Azure Pipelines web 门户中,编辑管道,然后选择 "更多操作"、"触发器"。 然后,在 " 拉取请求验证" 下,"启用 之前需要团队成员的注释"。
    • 在生成拉取请求之前,选择 "所有拉取请求" 以要求团队成员的注释。 使用此工作流时,团队成员将查看拉取请求,并在拉取请求被视为安全后使用注释触发生成。
    • 仅选择 "仅当非团队 成员的拉取请求" 时才需要团队成员的注释。 在此工作流中,团队成员不需要辅助团队成员的评审来触发生成。

通过这两项更改,将不会自动触发拉取请求验证生成,除非选择了 " 仅对非团队成员的拉取请求 ",并且该请求由团队成员进行。 只有具有 "写入" 权限的存储库所有者和合作者才能通过使用或注释拉取请求来触发 /AzurePipelines run 生成 /AzurePipelines run <pipeline-name>

可以向注释中 Azure Pipelines 以下命令:

命令 结果
/AzurePipelines help 显示所有支持的命令的帮助。
/AzurePipelines help <command-name> 显示指定命令的帮助。
/AzurePipelines run 运行与此存储库关联的所有管道,并且其触发器不排除此拉取请求。
/AzurePipelines run <pipeline-name> 运行指定的管道,除非其触发器排除此拉取请求。

注意

为简洁起见,你可以使用 /azp 而不是进行注释 /AzurePipelines

重要

仅当管道使用Azure Pipelines GitHub 应用时,才会在拉取请求讨论中显示这些命令的响应。

拉取请求注释触发器疑难解答

如果你具有必要的库权限,但你的注释不会触发管道,请确保你的成员身份在存储库的组织中是 公共 的,或者直接将自己添加为存储库协作者。 Azure Pipelines 无法查看私有组织成员,除非这些成员是直接协作者或属于直接协作者的团队。 你可以在此处将 GitHub 组织成员身份从 private 更改为 public (将替换 Your-Organization 为你的组织名称) : https://github.com/orgs/Your-Organization/people

签出

触发管道时,Azure Pipelines 从 Azure Repos Git 存储库中提取源代码。 您可以控制这种情况的各个方面。

注意

在管道中包含签出步骤时,请运行以下命令: git -c fetch --force --tags --prune --prune-tags --progress --no-recurse-submodules origin 。 如果这不能满足您的需要,您可以选择排除内置的签出, checkout: none 然后使用脚本任务来执行您自己的签出。

Git 的首选版本

Windows 代理附带自己的 Git 副本。 如果希望提供自己的 Git,而不是使用所包含的副本,请将设置 System.PreferGitFromPathtrue 。 在非 Windows 代理上,此设置始终为 true。

签出路径

如果你正在签出单个存储库,则默认情况下,你的源代码将签出到名为的目录中 s 。 对于 YAML 管道,你可以通过使用指定来更改此 checkoutpath 。 指定的路径是相对的 $(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) 。

你可以 path 在管道的 " path " 步骤中配置设置。

steps:
- checkout: self  # self represents the repo where the initial Pipelines YAML file was found
  clean: boolean  # whether to fetch clean each time
  fetchDepth: number  # the depth of commits to ask Git to fetch
  lfs: boolean  # whether to download Git-LFS files
  submodules: true | recursive  # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules
  path: string  # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
  persistCredentials: boolean  # set to 'true' to leave the OAuth token in the Git config after the initial fetch

子模块

submodules如果要从子模块下载文件,可以在管道的 "submodules" 步骤中配置设置。

steps:
- checkout: self  # self represents the repo where the initial Pipelines YAML file was found
  clean: boolean  # whether to fetch clean each time
  fetchDepth: number  # the depth of commits to ask Git to fetch
  lfs: boolean  # whether to download Git-LFS files
  submodules: true | recursive  # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules
  path: string  # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
  persistCredentials: boolean  # set to 'true' to leave the OAuth token in the Git config after the initial fetch

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

  • 未经身份验证: 未经过身份验证的公共存储库,不需要任何凭据即可克隆或提取。

  • 身份

    • 与上面指定的 Azure Repos Git 存储库位于同一项目中。 代理用来从主存储库获取源的凭据也用于获取子模块的源。

    • 使用相对于主存储库的 URL 添加的。 例如

      • 此时会签出此复选框: git submodule add ../../../FabrikamFiberProject/_git/FabrikamFiber FabrikamFiber

        此示例中的子模块引用同一 Azure DevOps 组织中位于另一个项目 (FabrikamFiberProject) (FabrikamFiber) 中的存储库) 。 代理用于从主存储库获取源的相同凭据也用于获取子模块的源。 这要求作业访问令牌有权访问第二个项目中的存储库。 如果已根据上述部分所述限制作业访问令牌,则将无法这样做。 可以通过 () 显式授予对第二个项目中的项目生成服务帐户的访问权限,或者使用集合范围访问令牌(而不是整个组织的项目范围令牌) (b) ,允许作业访问令牌访问第二个项目中的存储库。 有关这些选项及其安全影响的详细信息,请参阅 访问存储库、项目和其他资源

      • 不会签出此复选框: git submodule add https://fabrikam-fiber@dev.azure.com/fabrikam-fiber/FabrikamFiberProject/_git/FabrikamFiber FabrikamFiber

使用 Checkout 子模块选项的替代方法

在某些情况下,你无法使用 "签出"子模块 选项。 你可能需要一组不同的凭据才能访问子模块。 例如,如果主存储库和子模块存储库未存储在同一 Azure DevOps 组织中,或者作业访问令牌无法访问其他项目中的存储库,则可能会发生这种情况。

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

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

请务必将 <> "BASE64_ENCODED_STRING"替换为 Base64 编码的"pat:token"字符串。

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

注意

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

浅表提取

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

可以在管道 fetchDepth 的"签出 fetchDepth 步骤中配置设置。

steps:
- checkout: self  # self represents the repo where the initial Pipelines YAML file was found
  clean: boolean  # whether to fetch clean each time
  fetchDepth: number  # the depth of commits to ask Git to fetch
  lfs: boolean  # whether to download Git-LFS files
  submodules: true | recursive  # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules
  path: string  # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
  persistCredentials: boolean  # set to 'true' to leave the OAuth token in the Git config after the initial fetch

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

注意

管道启动后,要构建的分支将解析为提交 ID。 然后,代理提取分支并签出所需的提交。 分支解析为提交 ID 和代理执行签出之间存在一个小窗口。 如果分支快速更新,并且你为浅表提取设置了非常小的值,则代理尝试签出提交时,提交可能不存在。如果发生这种情况,请增加浅表提取深度设置。

不同步源

可能需要跳过提取新提交。 此选项在需要:

  • Git init、config 和 fetch(使用你自己的自定义选项)。

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

可以通过设置在管道的"签出"步骤中配置"不同步源"设置

steps:
- checkout: none  # Don't sync sources

注意

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

清理生成

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

一般情况下,为了加快自承载代理的性能,请不要清理存储库。 在这种情况下,若要获得最佳性能,请确保还通过禁用用于生成的任务或工具的任何 Clean 选项以增量方式生成。

如果需要清理存储库 (例如,避免上一个生成版本的剩余文件) ,选项如下。

注意

如果使用 Microsoft 托管的代理,清理将生效,因为每次都会获得新代理。

可以在管道 clean 的"签出 clean 步骤中配置设置。

steps:
- checkout: self  # self represents the repo where the initial Pipelines YAML file was found
  clean: boolean  # whether to fetch clean each time
  fetchDepth: number  # the depth of commits to ask Git to fetch
  lfs: boolean  # whether to download Git-LFS files
  submodules: true | recursive  # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules
  path: string  # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
  persistCredentials: boolean  # set to 'true' to leave the OAuth token in the Git config after the initial fetch

设置为 cleantrue ,生成管道将撤消 中任何更改 $(Build.SourcesDirectory) 。 更具体地说,以下 Git 命令在提取源之前执行。

git clean -ffdx
git reset --hard HEAD

有关更多选项,可以配置作业 workspaceworkspace

jobs:
- job: string  # name of the job, A-Z, a-z, 0-9, and underscore
  ...
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs

这提供了以下干净选项。

  • 输出:与上一个签出任务中所述的干净设置相同的操作,加上:删除并重新创建 。 请注意, 和 始终在生成之前删除并重新创建,而不 $(Build.ArtifactStagingDirectory)$(Common.TestResultsDirectory) 考虑这些设置。

  • resources:删除并重新创建 。 这导致针对每个生成初始化新的本地 Git 存储库。

  • all:删除并重新创建 。 这导致针对每个生成初始化新的本地 Git 存储库。

标签源

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

目前无法配置 YAML 中的此设置,但可以在经典编辑器中配置此设置。 编辑 YAML 管道时,可以通过从 YAML 编辑器菜单中选择任一触发器来访问经典编辑器。

Configure Git options, YAML.

在经典编辑器中,选择 "YAML",选择" 获取源 "任务,然后配置所需的属性。

From the Classic editor, choose YAML > Get sources.

标记格式 中,可以使用作用域为"All"的用户定义和预定义变量。例如:

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

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

生成管道使用 Git 标记标记

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

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

预定义变量

构建 GitHub 存储库时,大部分预定义的变量可用于你的作业。 但是,由于 Azure Pipelines 无法识别在 GitHub 中进行更新的用户的标识,因此,以下变量将设置为系统标识而不是用户的标识:

  • Build.RequestedFor
  • Build.RequestedForId
  • Build.RequestedForEmail

状态更新

有两种类型的状态 Azure Pipelines 回发到 GitHub 基本状态和 GitHub 检查运行。 GitHub 检查功能仅适用 GitHub 应用。

管道状态显示在 GitHub UI 中的不同位置。

  • 对于 Pr,它们显示在 "PR 会话" 选项卡上。
  • 对于单个提交,在存储库的 "提交" 选项卡上的提交时间之后将鼠标悬停在状态标记上时,将显示它们。

PAT 或 OAuth GitHub 连接

对于使用PATOAuth GitHub 连接的管道,状态将回发到触发运行的提交/PR。 GitHub 状态 API用于发布此类更新。 这些状态包含有限信息:管道状态 (failed、success) 、链接回生成管道的 URL 以及状态的简要说明。

平台连接状态或 OAuth GitHub 连接仅在运行级别发送。 换句话说,您可以为整个运行更新单个状态。 如果在运行中有多个作业,则无法为每个作业发布单独的状态。 但是,多个管道可以将单独的状态发布到同一提交。

GitHub 检查

对于使用 Azure Pipelines GitHub 应用) 设置的管道,状态将以 GitHub 检查的形式回发。 GitHub 检查允许发送有关管道状态以及测试、代码覆盖率和错误的详细信息。 可在此处找到 GitHub 检查 API。

对于使用 GitHub 应用程序的每个管道,会回发检查以获取整体运行以及该运行中的每个作业。

GitHub 允许在一个或多个检查对 PR/commit 运行失败时使用三个选项。 您可以选择 "重新运行" 单独检查、重新运行对该 PR/commit 的所有失败的检查,或重新运行所有检查,无论它们是否成功。

GitHub checks rerun

单击检查运行名称旁边的 "重新运行" 链接将导致 Azure Pipelines 重试生成检查运行的运行。 生成的运行将具有相同的运行号,并将使用与初始生成相同的源代码、配置和 YAML 文件版本。 只有在初始运行中失败的作业和任何相关的下游作业都将再次运行。 单击 "重新运行所有失败的检查" 链接将具有相同的效果。 这与在 Azure Pipelines UI 中单击 "重试运行" 的行为相同。 单击 "重新运行所有检查" 将生成新的运行,其中包含新的运行号,并将在配置或 YAML 文件中提取更改。

常见问题解答

与 GitHub 集成相关的问题分为以下几类:

  • 连接类型我不确定使用哪种连接类型将管道连接到 GitHub。
  • 失败的触发器 将更新推送到存储库时,不会触发管道。
  • 未能签出 正在触发我的管道,但在结帐步骤中失败。
  • 版本错误 我的管道运行,但它使用的是源/YAML 的意外版本。
  • 缺少状态更新我的 GitHub pr 被阻止,因为 Azure Pipelines 未报告状态更新。

连接类型

若要排查触发器问题,如何知道我在管道中使用的 GitHub 连接的类型?

触发器问题的疑难解答非常多取决于在管道中使用的 GitHub 连接的类型。 可以通过两种方式确定连接类型-从 GitHub 和 Azure Pipelines。

  • GitHub:如果将存储库设置为使用 GitHub 应用,则 pr 和提交上的状态将是 "检查运行"。 如果存储库已 Azure Pipelines 设置 OAuth 或 PAT 连接,则状态将是 "旧" 状态样式。 若要确定状态是 "检查运行" 还是 "简单" 状态,请查看 GitHub PR 上的 "会话" 选项卡。

    • 如果 "详细信息" 链接重定向到 "检查" 选项卡,则它是一个检查运行,存储库正在使用该应用。
    • 如果 "详细信息" 链接重定向到 Azure DevOps 管道,则状态为 "旧样式" 状态,并且存储库未使用该应用。
  • 从 Azure Pipelines:还可以通过检查 Azure Pipelines UI 中的管道来确定连接的类型。 打开管道的编辑器。 选择 " 触发器 ",打开管道的经典编辑器。 然后,选择 " YAML " 选项卡,然后选择 " 获取源 " 步骤。 你将注意到一个使用连接进行了授权的横幅:指示用于将管道与 GitHub 进行集成的服务连接。 服务连接的名称为超链接。 选择它以导航到服务连接属性。 服务连接的属性将指示所使用的连接类型:

    • Azure Pipelines 应用指示 GitHub 应用连接
    • oauth 指示 oauth 连接
    • personalaccesstoken 表示 PAT 身份验证

如何实现切换管道以使用 GitHub 应用而不是 OAuth?

使用 GitHub 应用(而不是 OAuth 或 PAT 连接)是 GitHub 和 Azure Pipelines 之间推荐的集成。 若要切换到 GitHub 应用,请执行以下步骤:

  1. 此处导航并在存储库的 GitHub 组织中安装应用。
  2. 在安装过程中,你将被重定向到 Azure DevOps 来选择 Azure DevOps 组织和项目。 选择包含要为其使用应用程序的经典生成管道的组织和项目。 此选择将 GitHub 应用安装与 Azure DevOps 组织相关联。 如果选择不正确,则可以访问此页,从 GitHub 的组织中卸载 GitHub 应用程序,然后重新开始。
  3. 在出现的下一页中,无需继续创建新管道。
  4. 通过访问 Pipelines 页面 (例如, https://dev.azure.com/YOUR_ORG_NAME/YOUR_PROJECT_NAME/_build) 选择你的管道,然后单击 "编辑" 来编辑管道。
  5. 如果这是一个 YAML 管道,请选择 " 触发器 " 菜单以打开经典编辑器。
  6. 选择管道中的 "获取源" 步骤。
  7. 在带有文本 "使用连接授权" 的绿色栏上,单击 "更改",并选择与安装应用的 GitHub 组织名称相同的 GitHub 应用连接。
  8. 在工具栏上,选择 "保存并排队",然后选择 "保存并排队"。 单击已排队的管道运行的链接,以确保成功。
  9. 创建 (或关闭并重新打开 GitHub 存储库中的拉取请求) ,以验证生成在其 "检查" 部分中是否已成功排队。

为什么没有为我显示要在 Azure Pipelines 中选择的 GitHub 存储库?

根据身份验证类型和存储库的所有权,需要特定权限。

在管道创建过程中选择存储库时,出现错误 "存储库 {存储库名称} 与另一个 Azure DevOps 组织中的 Azure Pipelines GitHub 应用程序一起使用。"

这意味着存储库已与另一组织中的管道相关联。 此存储库中的 CI 和 PR 事件将无法工作,因为它们将会传递给其他组织。 下面是在继续创建管道之前,删除映射到另一个组织的步骤。

  1. 在 GitHub 存储库中打开拉取请求,并生成注释 /azp where 。 这会报告存储库所映射到的 Azure DevOps 组织。

  2. 若要更改映射,请从 GitHub 组织中卸载该应用,然后重新安装它。 重新安装它时,请确保在重定向到 Azure DevOps 时选择正确的组织。

触发器失败

我刚刚使用 CI/PR 触发器创建了一个新的 YAML 管道,但没有触发该管道。

按照以下每个步骤来解决失败的触发器:

  • 用户界面中的管道设置是否会重写YAML CI 或 PR 触发器? 编辑管道时,请选择 " ... ",然后单击 " 触发器"。

    Pipeline settings UI.

    选中 "在 此处替代 YAML 触发器" 设置,以查看适用于你的存储库的 (持续集成拉取请求验证) 。

    Override YAML trigger from here.

  • 是否正在使用 GitHub 应用连接将管道连接到 GitHub? 请参阅 连接类型 以确定你的连接类型。 如果你使用的是 GitHub 应用连接,请执行以下步骤:

    • 映射是否在 GitHub 和 Azure DevOps 之间设置正确? 在 GitHub 存储库中打开拉取请求,并生成注释 /azp where 。 这会报告存储库所映射到的 Azure DevOps 组织。

      • 如果未设置任何组织来使用应用生成此存储库,请参阅 https://github.com/<org_name>/<repo_name>/settings/installations 并完成应用的配置。

      • 如果报告了不同的 Azure DevOps 组织,则有人已经在另一个组织中为此存储库建立了管道。 目前,我们只能将 GitHub 存储库映射到单个 DevOps org。只有第一个 Azure DevOps 组织中的管道可以自动触发。 若要更改映射,请从 GitHub 组织中卸载该应用,然后重新安装它。 重新安装它时,请确保在重定向到 Azure DevOps 时选择正确的组织。

  • 使用 OAuth 还是 PAT 将管道连接到 GitHub? 请参阅 连接类型 以确定你的连接类型。 如果使用 GitHub 连接,请执行以下步骤:

    1. OAuth 和 PAT 连接依赖于 webhook 将更新传递到 Azure Pipelines。 在 GitHub 中,导航到存储库的 "设置",然后导航到 "webhook"。 验证 webhook 是否存在。 通常会看到三个 webhook、pull_request 和 issue_comment。 如果不这样做,则必须重新创建服务连接并更新管道以使用新的服务连接。

    2. 在 GitHub 中选择每个 webhook,并验证与用户的提交对应的有效负载是否存在并且是否已成功发送到 Azure DevOps。 如果无法将事件传递到 Azure DevOps,则可能会在此处看到错误。

  • GitHub 可以限制来自 Azure DevOps 的流量。 Azure Pipelines 收到 GitHub 的通知时,它会尝试联系 GitHub 并获取有关存储库和 YAML 文件的详细信息。 如果存储库中的更新和拉取请求数过多,此调用可能会因为此限制而失败。 在这种情况下,请参阅是否可以使用批处理或更严格的路径/分支筛选器降低生成的频率。

  • 管道是暂停还是禁用? 打开管道的编辑器,然后选择 "设置" 进行检查。 如果管道处于暂停或禁用状态,则触发器不起作用。

  • 是否在正确的分支更新了 YAML 文件? 如果将更新推送到分支,则同一分支中的 YAML 文件会控制 CI 行为。 如果将更新推送到源分支,则将源分支与目标分支合并导致的 YAML 文件会控制 PR 行为。 请确保正确分支中的 YAML 文件具有必需的 CI 或 PR 配置。

  • 是否已正确配置触发器? 定义 YAML 触发器时,可以为分支、标记和路径指定 include 和 exclude 子句。 确保 include 子句匹配提交的详细信息,并且 exclude 子句不会将其排除。 检查触发器的语法,并确保其正确无误。

  • 是否在定义触发器或路径时使用了变量? 这不受支持。

  • 是否使用了 YAML 文件的模板? 如果是这样,请确保在主 YAML 文件中定义触发器。 不支持在模板文件中定义的触发器。

  • 你是否已排除你的更改已推送到的分支或路径? 通过将更改推送到包含的分支中的包含路径来进行测试。 请注意,触发器中的路径区分大小写。 在触发器中指定路径时,请确保使用的大小写与真实文件夹的大小写相同。

  • 是否刚刚推送了新的分支? 如果是这样,新分支可能不会启动新的运行。 请参阅 "创建新分支时触发器的行为" 一节。

我的 CI 或 PR 触发器工作正常。 但它们现在已停止工作。

首先完成上一问题的故障排除步骤。 然后,执行以下附加步骤:

  • PR 中是否存在合并冲突? 对于未触发管道的 PR,请将其打开,并检查它是否具有合并冲突。 解决合并冲突。

  • 处理推送事件或 PR 事件时是否遇到延迟? 通常可以通过查看此问题是否特定于单个管道,或在项目中的所有管道或存储库中通用来验证此问题。 如果对任何存储库的推送或 PR 更新展示了此症状,则在处理更新事件时可能会遇到延迟。 如果我们的 状态页上出现服务中断,请检查。 如果 "状态" 页显示问题,则我们的团队必须已开始处理此问题。 请经常检查页面,以获取有关问题的更新。

我不希望用户在更新 YAML 文件时替代触发器的分支列表。 如何执行此操作?

有权提供代码的用户可以更新 YAML 文件并包含/排除其他分支。 因此,用户可以在其 YAML 文件中包含自己的功能或用户分支,并将该更新推送到功能或用户分支。 这可能会导致对该分支的所有更新触发管道。 如果要防止此行为,则可以:

  1. 在 Azure Pipelines UI 中编辑管道。
  2. 导航到 " 触发器 " 菜单。
  3. 选择 "替代此处的 YAML 持续集成触发器"
  4. 为触发器指定要包含或排除的分支。

执行这些步骤时,将忽略 YAML 文件中指定的任何 CI 触发器。

未能签出

在签出步骤中,在日志文件中看到以下错误。 如何解决问题?

remote: Repository not found.
fatal: repository <repo> not found

这可能是由于 GitHub 中断引起的。 尝试在 GitHub 中访问存储库,并确保能够。

版本错误

管道中使用的 YAML 文件版本错误。 为什么会这样?

  • 对于 CI 触发器,将计算正在推送的分支中的 YAML 文件,以查看是否应运行 CI 生成。
  • 对于 PR 触发器,将评估与 PR 的源分支和目标分支合并导致的 YAML 文件,以查看是否应运行 PR 生成。

缺少状态更新

GitHub 中的 PR 被阻止,因为 Azure Pipelines 未更新状态。

这可能是导致 Azure DevOps 无法与 GitHub 通信的暂时性错误。 如果你使用 GitHub 应用,请重试 GitHub 中的检查。 或者,对 PR 进行普通更新,查看是否可以解决此问题。