Azure DevOps Services

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

Bitbucket 和 Azure Pipelines 是两个独立的服务,可以很好地集成在一起。 Bitbucket Cloud 用户不会自动获得对 Azure Pipelines 的访问权限。 必须将它们显式添加到 Azure Pipelines。

访问 Bitbucket 存储库

通过首先选择 Bitbucket 云存储库,然后在该存储库中选择一个 YAML 文件来创建新管道。 YAML 文件所在的存储库称为 self 存储库。 默认情况下,这是管道生成的存储库。

稍后可将管道配置为检查不同的存储库或多个存储库。 若要了解如何执行此操作,请参阅 多存储库签出

通过首先为存储库类型选择 Bitbucket Cloud ,然后选择有权访问的存储库之一来创建新管道。

必须向 Azure Pipelines 授予对存储库的访问权限,才能在生成期间提取代码。 此外,设置管道的用户必须具有 Bitbucket 的管理员访问权限,因为该标识用于在 Bitbucket 中注册 Webhook。

有 2 种身份验证类型可用于在创建管道时向 Azure Pipelines 授予对 Bitbucket 云存储库的访问权限。

身份验证类型 管道使用 运行

OAuth 身份验证

对于 Bitbucket 帐户中的存储库,OAuth 是最简单的身份验证类型。 Bitbucket 状态更新将代表你的个人 Bitbucket 标识执行。 若要使管道正常工作,存储库访问必须保持活动状态。

若要使用 OAuth,请在创建管道期间出现提示时登录到 Bitbucket。 然后,单击“ 授权 ”以使用 OAuth 进行授权。 OAuth 连接将保存在 Azure DevOps 项目中供以后使用,并在创建的管道中使用。

Azure DevOps Services用户界面可以加载的最大 Bitbucket 存储库数为 2,000。

生成和 Bitbucket 状态更新将代表你的个人标识执行。 要使内部版本正常工作,存储库访问权限必须保持活动状态。

若要创建密码连接,请访问 Azure DevOps 项目设置中的 服务连接 。 创建新的 Bitbucket 服务连接,并提供用于连接到 Bitbucket 云存储库的用户名和密码。

CI 触发器

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

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

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

# specific branch build
trigger:
  branches:
    include:
    - main
    - 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:
    - main

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

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

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

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

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

指定路径时,如果使用的是 Azure DevOps Server 2019.1 或更低版本,则必须显式指定要触发的分支。 不能仅使用路径筛选器触发管道;还必须具有分支筛选器,并且与路径筛选器匹配的已更改文件必须来自与分支筛选器匹配的分支。 如果使用 Azure DevOps Server 2020 或更高版本,可以省略branches以将路径筛选器与所有分支结合使用进行筛选。

路径筛选器支持通配符。 例如,可以包括与 匹配 src/app/**/myapp*的所有路径。 指定路径筛选器时,可以使用 (***或 的?)卡字符。

  • 始终相对于存储库的根目录指定路径。
  • 如果未设置路径筛选器,则默认情况下会隐式包含存储库的根文件夹。
  • 如果排除路径,则也不能包含该路径,除非将其限定为更深的文件夹。 例如,如果排除 /tools ,则可以包括 /tools/trigger-runs-on-these
  • 路径筛选器的顺序并不重要。
  • Git 中的路径 区分大小写。 请务必使用与真实文件夹相同的大小写。
  • 不能在路径中使用 变量 ,因为触发器触发) 后,会在运行时 (评估变量。
  • 对于 Bitbucket Cloud 存储库,使用 branches 语法是指定标记触发器的唯一方法。 tags: Bitbucket 不支持语法。

    选择退出 CI

    禁用 CI 触发器

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

    # A pipeline with no CI trigger
    trigger: none
    

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

    启用生成过程中的 Batch 更改时,Build.SourceVersionMessage 变量不适用于 Bitbucket 存储库。

    如果希望在用户签入代码时运行生成,请在“触发器”选项卡上选择“启用持续集成”以启用此触发器。

    如果有许多团队成员经常上传更改,并且希望减少正在运行的生成数,请选中此检查框。 如果选择此选项,则当生成正在运行时,系统将等待运行完成,然后将尚未生成的所有更改的另一个运行排队。

    可以批量更改并一起生成它们。

    如果将批处理用于多阶段 YAML 管道,则运行必须达到终端状态,然后才能启动下一个运行。 这通常是不可取的,因为多阶段管道可能会经历审批和长时间运行的部署阶段。 在这些情况下,建议遵循以下解决方案之一:

  • 不使用批处理
  • 将管道拆分为两个单独的管道 - 一个用于 CI,一个用于 CD
  • 在阶段上设置适当的条件以跳过它们并使运行快速终止
  • 分支筛选器

    可以指定要触发生成的分支。 如果要使用通配符,请键入分支规范 (例如, features/modules/*) 然后按 Enter。

    路径筛选器

    如果 Git 存储库位于 Azure Repos 或 TFS 中,则还可以指定路径筛选器来减少要触发生成的文件集。

  • 始终相对于存储库的根目录指定路径。
  • 如果未设置路径筛选器,则默认情况下会隐式包含存储库的根文件夹。
  • 如果排除某个路径,则不能包含该路径,除非将其限定为更深层的文件夹。 例如,如果排除 /tools ,则可以包括 /tools/trigger-runs-on-these
  • 路径筛选器的顺序并不重要。
  • Git 中的路径区分大小写。 请确保使用与实际文件夹相同的大小写。
  • 例如,你希望生成由主分支以及大多数(但不是全部)功能分支的更改触发。 你也不希望通过对 tools 文件夹中文件的更改触发生成。

    跳过单个提交的 CI

    还可以告诉 Azure Pipelines 跳过运行推送通常会触发的管道。 [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"
  • 对于分支和标记:
    • 通配符可能出现在模式中的任意位置。
    • 对于路径:
      • 在 Azure DevOps Server 2022 及更高版本(包括Azure DevOps Services)中,通配符可能出现在路径模式中的任何位置,你可以使用 *?
      • 在 Azure DevOps Server 2020 及更低版本中,可以包含 * 作为最后一个字符,但它与单独指定目录名称没有任何不同。 不能在路径筛选器的中间包含 * ,并且不能使用 ?
      • trigger:
          branches:
            include:
            - main
            - releases/*
            - feature/*
            exclude:
            - releases/old*
            - feature/*-working
          paths:
            include:
            - docs/*.md
        

        PR 触发器

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

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

        - main - releases/*

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

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

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

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

        每次新运行都会从拉取请求的源分支生成最新的提交。 这不同于 Azure Pipelines 在其他存储库中生成拉取请求的方式, (例如,Azure Repos或 GitHub) ,它在其中生成合并提交。 遗憾的是,Bitbucket 不会公开有关合并提交的信息,其中包含拉取请求的源分支和目标分支之间的合并代码。

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

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

        指定 pr 触发器时,它将替换默认的隐式 pr 触发器,并且仅推送到显式配置为包含的分支,才会触发管道。

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

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

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

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

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

        # auto cancel false
          autoCancel: false
          branches:
            include:
            - main
        

        选择退出 PR 验证

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

        # no PR triggers
        pr: none
        

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

        pr如果触发器未触发,请确保未在 UI 中重写 YAML PR 触发器

        选择“拉取请求验证触发器”,检查“启用拉取请求验证检查”框,以启用拉取请求的生成。

        可以指定要包含和排除的分支。 从下拉菜单中选择分支名称,然后根据需要选择“ 包括 ”或“ 排除 ”。 对于包含的分支,每次推送到面向该分支的拉取请求时,都会触发生成。

        信息性运行

        信息运行会告知 Azure DevOps 未能检索 YAML 管道的源代码。 源代码检索是在响应外部事件(例如推送的提交)时进行的。 它还在响应内部触发器时发生,例如,检查是否有代码更改并启动计划运行。 源代码检索可能由于多种原因而失败,其中经常出现 Git 存储库提供程序的请求限制。 信息运行的存在并不一定意味着 Azure DevOps 将运行管道。

        信息性运行如以下屏幕截图所示。

        可以通过以下属性识别信息运行:

      • 状态为 Canceled
      • 持续时间为 < 1s
      • 运行名称包含以下文本之一:
        • Could not retrieve file content for {file_path} from repository {repo_name} hosted on {host} using commit {commit_sha}.
        • Could not retrieve content for object {commit_sha} from repository {repo_name} hosted on {host}.
        • Could not retrieve the tree object {tree_sha} from the repository {repo_name} hosted on {host}.
        • Could not find {file_path} from repository {repo_name} hosted on {host} using version {commit_sha}. One of the directories in the path contains too many files or subdirectories.
        • 运行名称通常包含导致 YAML 管道加载失败的 BitBucket/GitHub 错误
        • 无阶段/作业/步骤
        • 详细了解 信息运行

          常见问题解答

          与 Bitbucket 集成相关的问题分为以下类别:

        • 失败的触发器 将更新推送到存储库时,不会触发管道。
        • 版本错误 我的管道运行,但它使用的是源/YAML 的意外版本。
        • 失败的触发器

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

          请遵循以下每个步骤对失败的触发器进行故障排除:

        • 你的 YAML CI 或 PR 触发器是否 被 UI 中的管道设置覆盖? 编辑管道时,选择 “...” ,然后选择 “触发器”。

          检查“ 从此处替代 YAML 触发器 ”设置,了解可用于存储库的触发器类型 (持续集成拉取请求验证) 。

        • Webhook 用于将更新从 Bitbucket 传达到 Azure Pipelines。 在 Bitbucket 中,导航到存储库的设置,然后导航到 Webhook。 验证 Webhook 是否存在。
        • 管道已暂停还是已禁用? 打开管道的编辑器,然后选择“设置”以检查。 如果管道已暂停或禁用,则触发器不起作用。

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

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

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

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

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

        • 你只是推送了一个新分支吗? 如果是这样,新分支可能不会启动新的运行。 请参阅“创建新分支时触发器的行为”部分。

          我的 CI 或 PR 触发器工作正常。 但是,他们现在停止工作了。

          首先完成上一个问题中的故障排除步骤。 然后,按照以下附加步骤操作:

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

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

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

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

        • 在 Azure Pipelines UI 中编辑管道。
        • 导航到“ 触发器 ”菜单。
        • 从此处选择“替代 YAML 持续集成触发器”。
        • 指定要包含或排除触发器的分支。
        • 执行这些步骤时,将忽略 YAML 文件中指定的任何 CI 触发器。

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

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