Skip to content

优化 vcpkg-workspace action 的缓存快照策略 #1

Open

Description

@CrSjimo

当前 actions/vcpkg-workspace 使用以下规则管理 GitHub Actions 缓存:

  • 缓存前缀由操作系统、架构和可选的 cache-key 输入组成。
  • 恢复和保存的完整 key 均在前缀后追加 github.sha。
  • 恢复未精确命中时,通过前缀恢复已有快照。
  • 依赖安装成功后,只要 cache 开启,就尝试保存整个二进制缓存目录。

因此,即使依赖和构建环境没有变化,本次安装没有新增任何 ABI 归档,只要源码提交发生变化,也会保存一份新的完整快照。这些快照持续占用仓库缓存额度,并可能导致其他有用缓存被自动淘汰。

下游项目 DiffScope 在 2026 年 11 月 7 日调查时,三个平台、两个提交对应的 vcpkg 缓存共有六份,合计约 1.69 GiB。保存频率与应用源码提交绑定,使没有依赖变化的提交也产生额外快照。

此外,恢复的二进制缓存目录会包含历史 ABI 归档。即使限制 GitHub 上的快照数量,单份快照内部仍可能持续积累已经不再使用的依赖版本。

建议将快照标识、保存条件和归档保留范围调整为以下规则。

  1. 增加独立的保存开关。

    保留 cache 总开关,增加默认值为 true 的 cache-save 输入。

    cache cache-save 行为
    false 任意值 关闭缓存恢复和保存。
    true false 恢复缓存,照常安装依赖,不上传新快照。
    true true 恢复缓存,仅在归档集合变化时保存新快照。

    当前 cache: false 会设置 VCPKG_BINARY_SOURCES=clear,无法用于实现只恢复缓存。独立开关可以让调用方配置 PR 只恢复缓存,主分支的 push、定时构建和 nightly 构建允许更新缓存。具体写入策略由调用方决定。

  2. 使用环境前缀恢复最新快照。

    沿用当前的环境分组方式:

    vcpkg-<操作系统>-<架构>-<cache-key>-
    

    cache-key 为空时省略该段。恢复时使用该前缀,移除对 github.sha 的依赖。

    调用方可以通过已有的 cache-key 区分实际 triplet、外部 Qt 版本等环境。例如:

    vcpkg-Windows-X64-x64-windows-qt6.11.2-
    

    当前脚本通过 VCPKG_KEEP_ENV_VARS 传递外部 Qt 路径,而这些变量的值不参与 vcpkg ABI 计算,因此需要保留调用方显式区分外部 SDK 环境的能力。相关文档

    同一环境下的 dev 和 nightly 可以共享缓存前缀。

  3. 在安装前记录实际归档集合。

    缓存恢复完成后、依赖安装之前,记录二进制缓存目录中所有 ABI ZIP 归档的相对路径,作为安装前的集合。

    比较对象应为实际归档集合,而非 manifest、sources 文件或应用源码的哈希。

  4. 安装成功后按已安装 ABI 裁剪归档。

    从 action 已输出的 installed-dir 下读取 vcpkg/status,收集状态为 install ok installed 且 Abi 非空的记录,形成保留集合。

    该集合需要包含全部已安装的目标依赖、间接依赖和 host 工具依赖,不应只筛选目标 triplet。

    vcpkg 文件缓存中的归档路径为:

    <缓存目录>/<ABI前两位>/<ABI>.zip
    

    删除不属于保留集合的归档,使快照仅携带当前安装使用的 ABI 包。该步骤应位于 action 内部的依赖安装步骤之后、缓存保存步骤之前。

  5. 根据裁剪后的归档集合决定保存条件和完整 key。

    处理顺序为:

    before = 恢复完成后的归档集合
    安装依赖
    按已安装 ABI 裁剪归档
    after = 裁剪后的归档集合
    
    cache-changed = before != after
    

    集合相同则跳过保存。集合不同且允许保存时,对按固定顺序排列的归档相对路径列表计算 SHA-256,并使用以下完整 key:

    <环境前缀><归档集合摘要>
    

    摘要只计算归档路径列表,无需读取全部 ZIP 内容。新增包和移除历史包都会触发快照更新。相同归档集合生成相同 key,不因源码提交或运行时间变化而生成不同标识。

  6. 输出缓存信息并补充使用文档。

    建议增加以下输出:

    • cache-prefix:缓存恢复和清理使用的环境前缀。
    • cache-key:安装及裁剪后计算的完整快照 key。
    • cache-changed:最终归档集合是否相对于恢复后的集合发生变化。

    文档需要说明输入、输出、保存条件,以及 PR 只恢复、主分支允许保存的配置示例。

GitHub 上旧快照的删除由调用项目的独立 workflow 负责。调用方确认新快照存在后,按“环境前缀 + Git ref”分组保留最新一份,并清理已停用的环境分组。安装 action 提供必要信息,删除所需的 actions: write 权限集中在调用方的清理 job 中。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions