ci: adopt pnpm/action-setup for symmetric pnpm store caching

Convert the hand-rolled corepack + store-path + actions/cache pnpm setups
to pnpm/action-setup@v4 + setup-node cache: pnpm (the landlock-run.yml
pattern) in e2e.yml, docs-pages.yml, pi-ai-provider-e2e.yml,
build-exe-for-python-sdk.yml, and ci.yml's node-compat and benchmark
jobs. The enterprise restore-only PR jobs and the Windows job keep their
documented asymmetries; serial-linux keeps its hand-rolled store cache
because it produces the exact key those restore-only jobs consume, and
only swaps corepack for the action.

Implements and moves the CI-caching Agent Note from PR #667 to
implemented/, recording the serial-linux producer exception and the
exact-key (no restore-keys prefix) behavior of setup-node's cache.
This commit is contained in:
Tianyi Cui
2026-07-26 22:55:05 +08:00
parent c9dc097749
commit cb3a1302ee
10 changed files with 102 additions and 175 deletions
@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-26-pnpm-action-setup-for-symmetric-ci-caching.md: 0cc0a09dfe1019d80b08599a245ce4bb044d81c5
2026-07-26-pnpm-action-setup-for-symmetric-ci-caching.zh.md: 477f8eed61579eb9c4f18701a39307daf098407d
@@ -0,0 +1,32 @@
# Agent Note: Use pnpm/action-setup for symmetric CI pnpm caching
Status: implemented
English | [中文](2026-07-26-pnpm-action-setup-for-symmetric-ci-caching.zh.md)
## Problem
Five workflows repeated a hand-rolled three-step pnpm setup — `corepack enable`, `pnpm store path --silent >> $GITHUB_OUTPUT`, then `actions/cache@v4` keyed on `pnpm-lock.yaml`: `e2e.yml`, `docs-pages.yml`, `pi-ai-provider-e2e.yml`, `build-exe-for-python-sdk.yml`, and the node-compat, serial-linux, and benchmark jobs of `ci.yml` (~4060 YAML lines total). The maintained equivalent — `pnpm/action-setup@v4` (reads `packageManager` from package.json) plus `actions/setup-node` with `cache: pnpm` — was already proven in-repo in `landlock-run.yml`, and also insulates against corepack's removal from newer Node distributions.
## Decision
The symmetric-cache setups use `pnpm/action-setup@v4` followed by `actions/setup-node` with `cache: pnpm`, the `landlock-run.yml` pattern: `e2e.yml`, `docs-pages.yml`, `pi-ai-provider-e2e.yml`, `build-exe-for-python-sdk.yml`, and the node-compat and two benchmark jobs of `ci.yml`. The larger-runner benchmark keeps its store cache Linux-only through a conditional `cache:` input, mirroring the required Windows job's deliberate skip; the consolidated benchmark caches on both platforms as before.
Explicitly NOT converted:
- the three enterprise-runner PR jobs in `ci.yml` — they deliberately use `actions/cache/restore` only, keeping cache compression/upload off the paid latency-critical path, an asymmetry `setup-node`'s cache cannot express;
- the Windows job, which deliberately skips the store cache;
- the store-cache step of `ci.yml`'s serial-linux job — the job swaps `corepack enable` for `pnpm/action-setup@v4`, but its `pnpm store path` + `actions/cache@v4` steps stay hand-rolled because the master-push serial-linux run is the save side that populates the exact key and path the enterprise restore-only jobs consume; converting the producer to `setup-node`'s own key format would silently starve their restores.
## Alternatives considered
- **Keep the hand-rolled steps.** They work, but they are five drifting copies of setup boilerplate, and the corepack dependency is a known future break.
- **Convert everything including the enterprise jobs.** Rejected: the restore-only asymmetry is a documented latency decision in `ci.yml`'s comments; erasing it to unify tooling inverts the priority.
- **Convert serial-linux's store cache too.** Rejected during implementation: the proposal counted serial-linux among the symmetric setups, but its cache step is the producer half of the enterprise jobs' restore-only pairing — moving it to `setup-node`'s key format is the enterprise conversion by another route.
## Consequences
- The corepack dependency is gone from every converted workflow; pnpm arrives via the pnpm team's official action, already trusted in-repo (`landlock-run.yml`).
- The cache-key format changed once; one cold run per converted lane repopulates it, after which hit rates match the old steps. The built-in key spans platform, arch, and the lockfile hash but not the Node version, so the node-compat matrix legs share one store entry — safe, because the pnpm store is Node-version-independent.
- `setup-node`'s built-in pnpm cache restores by exact key only, with no `restore-keys` prefix fallback: a `pnpm-lock.yaml` change starts a converted lane from a cold store instead of seeding from the previous entry.
- About 75 net lines of workflow YAML removed; the enterprise-runner PR jobs and the Windows job are byte-identical, and serial-linux keeps producing the key they restore.
@@ -0,0 +1,32 @@
# Agent Note: 用 pnpm/action-setup 实现对称的 CI pnpm 缓存
Status: implemented
[English](2026-07-26-pnpm-action-setup-for-symmetric-ci-caching.md) | 中文
## 问题
五个工作流曾重复着同一套手写(hand-rolled)的三步 pnpm 设置——`corepack enable``pnpm store path --silent >> $GITHUB_OUTPUT`、再加以 `pnpm-lock.yaml` 为缓存键的 `actions/cache@v4``e2e.yml``docs-pages.yml``pi-ai-provider-e2e.yml``build-exe-for-python-sdk.yml`,以及 `ci.yml` 的 node-compat、serial-linux 与 benchmark 作业(合计约 40–60 行 YAML)。与之等价、由官方维护的做法——`pnpm/action-setup@v4`(从 package.json 读取 `packageManager`)加带 `cache: pnpm``actions/setup-node`——当时已在仓库内的 `landlock-run.yml` 中得到验证,同时还能隔绝 corepack 被从较新 Node 发行版中移除的影响。
## 决策
各对称缓存设置现采用 `pnpm/action-setup@v4` 后接带 `cache: pnpm``actions/setup-node`,即 `landlock-run.yml` 的模式:`e2e.yml``docs-pages.yml``pi-ai-provider-e2e.yml``build-exe-for-python-sdk.yml`,以及 `ci.yml` 的 node-compat 与两个 benchmark 作业。larger-runner benchmark 通过条件化的 `cache:` 输入让 store 缓存仅限 Linux,与必需 Windows 作业刻意跳过缓存的做法保持一致;consolidated benchmark 与之前一样在两个平台上都启用缓存。
以下明确未做转换:
- `ci.yml` 中运行在企业 runner 上的三个 PRPull Request)作业——它们刻意只用 `actions/cache/restore`,把缓存压缩/上传挡在付费且延迟敏感的关键路径之外,这种不对称是 `setup-node` 的缓存无法表达的;
- Windows 作业,它刻意跳过 store 缓存;
- `ci.yml` 中 serial-linux 作业的 store 缓存步骤——该作业把 `corepack enable` 换成了 `pnpm/action-setup@v4`,但其 `pnpm store path` + `actions/cache@v4` 步骤仍保持手写,因为 master 推送触发的 serial-linux 运行正是写入侧,负责填充企业只恢复不上传(restore-only)作业所消费的那个精确缓存键与路径;把生产者改成 `setup-node` 自有的键格式,会悄然断供它们的恢复。
## 曾考虑的替代方案
- **保留手写步骤。** 它们能用,但那是五份会各自漂移的设置样板副本,而且对 corepack 的依赖是已知的未来失效点。
- **连企业作业在内全部转换。** 否决:只恢复不上传的不对称是 `ci.yml` 注释中有记录的延迟决策;为统一工具而抹掉它,属于颠倒优先级。
- **连 serial-linux 的 store 缓存也转换。** 实现期间否决:提案曾把 serial-linux 计入对称设置,但其缓存步骤是企业作业只恢复不上传配对中的生产者一半——把它改成 `setup-node` 的键格式,等于换条路径做了企业作业的转换。
## 后果
- 每个已转换的工作流都不再依赖 corepack;pnpm 经由 pnpm 团队的官方 action 提供,该 action 已在仓库内获得信任(`landlock-run.yml`)。
- 缓存键格式变更了一次;每条已转换泳道各跑一次冷运行以重建缓存,此后命中率与旧步骤持平。内建缓存键涵盖平台、架构与锁文件哈希,但不含 Node 版本,因此 node-compat 矩阵的各条腿共享同一条 store 缓存记录——这是安全的,因为 pnpm store 与 Node 版本无关。
- `setup-node` 内建的 pnpm 缓存只按精确键恢复,没有 `restore-keys` 前缀回退:`pnpm-lock.yaml` 一旦变更,已转换泳道会从冷 store 起步,而不是从上一条缓存记录播种。
- 净删除约 75 行工作流 YAML;企业 runner 上的 PR 作业与 Windows 作业逐字节未动,serial-linux 继续生产它们所恢复的缓存键。