生成 Bitbucket 云存储库

Azure DevOps Services

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

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

访问 Bitbucket 存储库

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

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

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

创建管道时,有两种身份验证用于授予 Azure Pipelines 对 Bitbucket 云存储库的访问权限。

身份验证类型 管道运行使用的身份
1. OAuth 个人 Bitbucket 身份
2. 用户名和密码 个人 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 管道都会配置 CI 触发器,除非 Azure DevOps sprint 227 中的“禁用默示的 YAML CI 触发器”已启用。 可以在组织级别或项目级别配置“禁用默示的 YAML CI 触发器”设置。 启用“禁用默示的 YAML CI 触发器”设置后,如果 YAML 管道没有 trigger 部分,则不会启用 YAML 管道的 CI 触发器。 默认情况下,不用启用“禁用默示的 YAML CI 触发器”

分支

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

trigger:
- main
- releases/*

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

注意

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

注意

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

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

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

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

如果指定 exclude 子句而不包含 include 子句,则等同于在 include 子句中指定 *

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

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

如果未指定任何触发器,并且未启用“禁用默示的 YAML CI 触发器”设置,则默认情况会与你编写以下内容时相同:

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

重要

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

批处理 CI 运行

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

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

注意

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

为了阐明此示例,我们假设对 main 的推送 A 导致上述管道运行。 当该管道正在运行时,会向存储库进行额外的推送 BC。 这些更新不会立即启动新的独立运行。 但是,在完成第一次运行后,在该时间点之前的所有推送将一起进行批处理,然后启动新的运行。

注意

如果管道有多个作业和阶段,则通过完成或跳过其所有作业和阶段,第一次运行仍应达到终端状态,然后才能启动第二次运行。 因此,在具有多个阶段或审批的管道中使用此功能时,必须小心谨慎。 如果希望在这种情况下批处理生成,建议将 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 云存储库,使用 branches 语法是指定标记触发器的唯一方法。 Bitbucket 不支持 tags: 语法。

选择退出 CI

禁用 CI 触发器

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

# A pipeline with no CI trigger
trigger: none

重要

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

跳过单个提交的 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 触发器。

pr:
- main
- releases/*

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

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

注意

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

注意

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

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

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

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

重要

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

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

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

路径

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

# specific path
pr:
  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
pr:
  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 将运行管道。

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

Screenshot of an informational pipeline run.

可根据以下属性识别信息性运行:

  • 状态为 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 错误
  • 无阶段/作业/步骤

详细了解信息性运行

限制

Azure Pipelines 最多将存储库中的 2000 个分支加载到 Azure Devops 门户的下拉列表中,例如加载到“手动和计划生成的默认分支”设置中,或者在手动运行管道的情况下在选择分支时这样做。 如果在列表中没有看到所需的分支,请手动键入所需的分支名称。

常见问题解答

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

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

触发器失败

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

按照以下各步骤对失败的触发器进行故障排除:

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

    Pipeline settings UI.

    针对你的存储库可用的触发器类型(“持续集成”或“拉取请求验证”)选中“从此处替代 YAML 触发器”设置。

    Override YAML trigger from here.

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

  • 是否已在正确的分支中更新 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 触发器。

版本错误

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

  • 对于 CI 触发器,你所推送的分支中的 YAML 文件将受到评估,以了解是否应运行 CI 生成。
  • 对于 PR 触发器,因合并 PR 的源分支和目标分支而产生的 YAML 文件将受到评估,以了解是否应运行 PR 生成。