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

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

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

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

本文内容:

  • 为 GitHub Actions 工作流设置二进制缓存和资产缓存
  • 设置工作流以测试注册表的端口

先决条件

为 GitHub Actions 工作流设置二进制缓存和资产缓存

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

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

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

示例:在 GitHub Actions 工作流中启用资产与二进制缓存

steps:
  - name: Enable GitHub Actions Cache backend
    uses: actions/github-script@v7
    with:
      script: |
        core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
        core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');

  - name: some vcpkg task
    run: "${{ github.workspace }}/vcpkg/vcpkg install"
    env: 
      X_VCPKG_ASSET_SOURCES: "clear;x-azurl,https://my.domain.com/container,{{ secrets.SAS }},readwrite"
      VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"

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

分解此代码片段:

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

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

VCPKG_BINARY_SOURCES 为用于在 vcpkg 中配置二进制缓存的环境变量。 在本示例中,它会被设为 clear;x-gha,readwrite。 它将为二进制缓存启用 GitHub Actions 缓存后端。 工作流中需引入一个额外步骤才能成功启用此后端。

以下步骤应按原样包含在 GitHub Action 工作流步骤中。 此步骤会导出 x-gha 后端正常工作所需的两个环境变量,且应在涉及 vcpkg 的所有任务之前运行。

- name: Enable GitHub Actions Cache backend
  uses: actions/github-script@v7
  with:
  script: |
    core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
    core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');

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

设置工作流以测试注册表的端口

为 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 参考文章以了解详细信息。 同时,阅读清单模式文档以了解它们如何协同工作。

在 GitHub Actions 工作流中获取 vcpkg

接下来,需要获取 vcpkg 才能在工作流中使用它。 添加以下步骤以安装 vcpkg。

steps:
- uses: actions/checkout@v4
  with:
    repository: "https://github.com/Microsoft/vcpkg"
    path: "vcpkg"

- name: Bootstrap vcpkg
  run: "${{ github.workspace }}/vcpkg/bootstrap-vcpkg.sh"
  shell: bash

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

运行 vcpkg 安装以生成端口

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

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

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

  - name: some vcpkg task
    run: "${{ github.workspace }}/vcpkg/vcpkg install"
    env: 
      X_VCPKG_ASSET_SOURCES: "clear;x-azurl,https://my.domain.com/container,{{ secrets.SAS }},readwrite"
      VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
      VCPKG_OVERLAY_PORTS: "${{ github.workspace }}/ports"

在此示例中,我们假定 vcpkg.json 文件是在注册表存储库的根目录中创建的。

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

.github/workflows/test-ports.yml

name: Test vcpkg ports

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    
    - name: Acquire vcpkg
      uses: actions/checkout@v4
      with:
        repository: "Microsoft/vcpkg"
        path: vcpkg

    - name: Bootstrap vcpkg
      run: "${{ github.workspace }}/vcpkg/bootstrap-vcpkg.sh"
      shell: bash

    - name: Enable GitHub Actions Cache backend
      uses: actions/github-script@v7
      with:
        script: |
          core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
          core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');

    - name: Build ports
      run: ${{ github.workspace }}/vcpkg/vcpkg install
      env:
        X_VCPKG_ASSET_SOURCES: "clear;x-azurl,https://your.domain.com/container,${{ secrets.SAS }},readwrite"
        VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
        VCPKG_OVERLAY_PORTS: "${{ github.workspace }}/ports"
      shell: bash

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

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

后续步骤

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