借助 Azure DevOps 并使用 vcpkg 来测试自定义注册表端口

设置 vcpkg 端口的自定义注册表后,可能需添加连续集成来验证是否可成功生成所有依赖项。

Microsoft/vcpkg 的主要 vcpkg 注册表会由 vcpkg 团队借助 Azure DevOps 并使用持续集成 (CI) 管道来进行测试。 此举可确保添加新包或更新现有包时不会中断使用者。

本文介绍如何设置 CI 环境以测试自己注册表中的 vcpkg 端口。

本文内容:

  • 为 Azure DevOps 管道设置二进制缓存和资产缓存
  • 设置管道以测试注册表的端口

先决条件

为 Azure DevOps 管道设置二进制缓存和资产缓存

就时间和算力而言,构建大量端口是一项高成本任务。 强烈建议在为端口使用 CI 之前,为 Azure DevOps 管道出资设置二进制缓存和资产缓存。

二进制缓存可通过确保在每次 CI 运行时不重新生成未修改的包,从而为 CI 场景提供最大好处。 资产缓存可镜像运行期间为包下载的项目,并在后续运行中使用缓存的项目。 此外,它还有助于缓解上游存储库的不可靠问题;例如,损坏的下载 URL。

有关如何设置这些缓存的详细说明,请阅读我们的二进制缓存资产缓存文章。

示例:在 Azure DevOps 管道中启用资产与二进制缓存

steps: 
- task: NuGetAuthenticate@1

- script: $(Build.Repository.LocalPath)/vcpkg/vcpkg install --triplet=x64-windows
  displayName: some vcpkg task
  env:
    X_VCPKG_ASSET_SOURCES: "clear;x-azurl,https://my.domain.com/container,$(VcpkgAssetCache),readwrite"
    VCPKG_BINARY_SOURCES: "clear;nuget,https://my.domain.com/vcpkgBinaryCache/nuget/v3/index.json,readwrite"

此示例演示如何在 Azure DevOps 管道中设置二进制缓存和资产缓存。 应调整此代码片段,以将其用于自己的管道的 YAML 文件。

分解此代码片段:

X_VCPKG_ASSET_SOURCES 为用于在 vcpkg 中配置资产缓存的环境变量。 在本示例中,它会被设为 x-azurl,https://my.domain.com/container,$(VcpkgAssetCache),readwritex-azurl 后端会指示 vcpkg 使用 Azure 存储容器以作为存储提供程序。 x-azurl 后跟三个用逗号 (,) 分隔的参数。

  • https://my.domain.com/container 为存储容器 URL。
  • $(VcpkgAssetCache) 是一个管道密钥变量,其中包含用于向存储容器进行身份验证的 SAS 令牌。
  • readwrite 会为资产缓存设置读取和写入权限。 这意味着,此资产缓存可用于存储项目以及从中还原项目。

VCPKG_BINARY_SOURCES 为用于在 vcpkg 中配置二进制缓存的环境变量。 在本示例中,它会被设为 clear;nuget,https://my.domain.com/vcpkgBinaryCache/nuget/v3/index.json,readwrite。 它将使用位于 https://my.domain.com/vcpkgBinaryCache/nuget/v3/index.json 的 NuGet 源来启用二进制缓存的 NuGet 后端。 可能需执行某些其他步骤才能向 NuGet 源进行身份验证,请阅读此教程,了解如何使用 ADO 设置 NuGet 身份验证。

应在管道中按原样添加以下任务,以便向 Azure Artifacts NuGet 源进行身份验证。 此任务还应在涉及 vcpkg 的所有任务之前运行。

- task: NuGetAuthenticate@1

如果为 NuGet 源使用了其他主机,则请阅读有关如何对 NuGet 进行身份验证的文档。

阅读有关资产缓存二进制缓存功能的文档,详细了解所有这些功能的工作原理。

设置管道以测试注册表的端口

为 CI 环境设置二进制缓存和资产缓存后,下一步便是设置管道以测试注册表的所有端口。 可决定此管道是按计划运行,还是由新的提交或拉取请求来触发。

主 vcpkg 注册表会使用 vcpkg ci 命令,而该命令已根据 vcpkg 项目的需求进行定制,且不应持续保留或供 vcpkg 使用者使用。 因此,它不适用于测试自己的 vcpkg 注册表。 建议改为按照本文中所述的步骤进行操作。

使用清单文件以包含所有端口

建议使用清单文件来创建依赖于注册表中所有包的生成,而不是使用 vcpkg ci 命令。

以下示例将创建一个清单文件来测试假想 vcpkg 注册表中的所有端口。 替换依赖项列表以包含注册表中的所有端口,并将其置于存储库的根目录中。

vcpkg.json

{
  "dependencies": [
    "beicode",
    "beison"
  ]
}

你自己的端口可能存在依赖于主 vcpkg 注册表或其他第三方注册表的依赖项;在此情况下,需在 vcpkg-configuration.json 文件中添加这些注册表。 虽然 vcpkg 可从主注册表解析包而无需其他配置,但强烈建议将其显式添加到注册表列表中,以便进行版本控制。 此举可确保你能控制基础端口版本集。 查看vcpkg x-update-baseline命令以帮助管理注册表的基线。

vcpkg-configuration.json

{
  "default-registry": null,
  "registries": [
    {
      "kind": "git",
      "repository": "https://github.com/Microsoft/vcpkg",
      "baseline": "42bb0d9e8d4cf33485afb9ee2229150f79f61a1f",
      "packages": "*"
    }
  ]
}

阅读 vcpkg.jsonvcpkg-configuration.json 参考文章以了解详细信息。 同时,阅读清单模式文档以了解它们如何协同工作。

在 Azure DevOps 管道中获取 vcpkg

如果将 vcpkg 用作项目中的子模块,则可在此步骤中获取 vcpkg 存储库从而签出自己的项目,如下所示。

steps:
- checkout: self
  submodules: true

否则,需获取 vcpkg 才能在管道中使用它。 添加以下步骤以克隆 vcpkg 存储库。

resources:
  repositories:
    - repository: vcpkgRepo
      type: github
      name: Microsoft/vcpkg
      endpoint: MyGitHubServiceConnection

steps:
  - checkout: vcpkgRepo

若要克隆 vcpkg 存储库,则需为管道定义存储库资源。 以下代码片段演示如何将 vcpkg 存储库添加为资源,同时还需设置服务连接以将管道连接到 GitHub。

作为子模块或通过从 GitHub 克隆 vcpkg 存储库以将此存储库签出后,需运行 vcpkg 的启动脚本。

steps:
  - script: vcpkg/bootstrap-vcpkg.sh

完成这些步骤后,应存在要使用的 vcpkg 可执行文件。

运行 vcpkg 安装以生成端口

最后一步是告知 vcpkg 生成所有端口。 你可能已注意到,自己的注册表中缺少在上面几个步骤中创建的 vcpkg-configuration.json。 其原因在于,你想测试当前位于工作目录中的端口版本,而不是存储库中已发布的版本。

为达到此目的,需通过将 VCPKG_OVERLAY_PORTS 环境变量设为注册表的 ports 目录,从而将注册表的端口添加为覆盖端口

以下代码片段演示如何将注册表的端口设为覆盖端口,并在清单模式下运行 vcpkg install 以安装所有自定义端口。

steps:
- script: $(Build.Repository.LocalPath)/vcpkg/vcpkg install
  env:
    X_VCPKG_ASSET_SOURCES: "clear;x-azurl,https://my.domain.com/container,$(VcpkgAssetCache),readwrite"
    VCPKG_BINARY_SOURCES: "clear;nuget,https://my.domain.com/demoBinaries/nuget/v3/index.json,readwrite"
    VCPKG_OVERLAY_PORTS: "$(Build.Repository.LocalPath)/ports"

在此示例中,我们假定 vcpkg.json 文件是在注册表存储库的根目录中创建的,且 vcpkg 存储库将添加为一个子模块。

将所有这些放在一起后,管道的 YAML 文件应如下所示:

.azure-pipelines/test-ports.yml

trigger:
- main

pool:
  vmImage: windows-latest

steps:
- checkout: self
  submodules: true

- task: NuGetAuthenticate@1

- script: $(Build.Repository.LocalPath)/vcpkg/bootstrap-vcpkg.bat
  displayName: Bootstrap vcpkg

- script: $(Build.Repository.LocalPath)/vcpkg/vcpkg install --triplet=x64-windows
  env:
    X_VCPKG_ASSET_SOURCES: "clear;x-azurl,https://my.domain.com/container,$(VcpkgAssetCache),readwrite"
    VCPKG_BINARY_SOURCES: "clear;nuget,https://my.domain.com/demoBinaries/nuget/v3/index.json,readwrite"
    VCPKG_OVERLAY_PORTS: "$(Build.Repository.LocalPath)/ports"

它是 CI 管道用于测试注册表端口的基本结构。 可能需要执行某些额外工作才能对专用存储库进行身份验证或对 NuGet 源进行身份验证。

你可能还想添加若干步骤来自动生成 vcpkg.json 文件,或是添加一个步骤来确保新添加到注册表的端口未被排除在测试之外。

后续步骤

设置 CI 环境时,以下文章可能有用。