可执行决策矩阵(按行抄进 Runbook)
下列表格把「选型—参数—阈值」压成一行决策:默认以 Node 22+ 与 darwin arm64 为基线;若你的池子混跑 x64 Rosetta,请在缓存键中追加 arch 片段以免错命中。
若你是带着「Bun.lockb 能替代 package-lock 吗」「混仓先 bun 还是先 npm ci」「镜像环境变量怎么双写」「GitHub Actions 缓存键 hashFiles 怎么拼」这类长尾问句打开本文,可直接以表格最后一列「混仓推荐动作」为验收清单:每一项都应对应一条流水线日志或合并请求模板字段,避免口头约定。
| 维度 | Bun.lockb(二进制锁) | package-lock.json(npm v3 锁) | 混仓推荐动作 |
|---|---|---|---|
| 真相源与 CI 门禁 | bun install --frozen-lockfile;锁变更只能通过本地 bun install 再提交 |
npm ci 或 npm install --package-lock-only 后 diff 门禁 |
在 ADR 写死「先跑哪条锁」;另一条锁的更新必须附带合并说明与双跑计时 |
| registry 镜像(跨境) | bunfig.toml 的 install.registry 或环境变量 BUN_CONFIG_REGISTRY |
NPM_CONFIG_REGISTRY 与 .npmrc 的 registry= |
同一镜像根双写;步骤开头 echo 打印两处解析结果 |
| 作用域与私库 | 在 bunfig.toml 使用 [install.scopes] 将 @org 绑定到私库根;与 npm 的 @org:registry= 成对核对 |
//registry.npmjs.org/:_authToken 等(建议仅 CI 注入) |
令牌只读、短 TTL;轮换后各跑一次 frozen / ci |
| 并发安装 | 控制脚本并行度;避免与 bun install 同时再跑全量 npm ci 打双份流量 |
NPM_CONFIG_MAXSOCKETS=12 起评,429 降到 6 |
同一 Job 内串行化「锁安装」阶段,测试分片后置 |
| 缓存键命名(示例片段) | bun-{{ hashFiles('Bun.lockb') }}-{{ runner.os }}-arm64-bun-$(bun --version) |
npm-{{ hashFiles('package-lock.json') }}-node-${{ env.NODE_VERSION }} |
混仓用拼接:bunlock+plock+arch+bunVer+nodeVer,任一锁变则全量 miss |
| 失败重试阈值 | 网络类:2s / 4s / 8s 指数退避,最多 3 轮;仍失败则降级为单线程重装 | NPM_CONFIG_FETCH_RETRIES=3,NPM_CONFIG_FETCH_RETRY_MINTIMEOUT=2000,NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT=8000 |
429 与 TLS reset 共用退避表;每轮记录 registry 主机名 |
可复制环境变量与命令骨架
将镜像域名替换为企业可审计端点;勿把长期 PAT 写进仓库。Apple Silicon runner 上建议显式限制旧空间占用:export NODE_OPTIONS=--max-old-space-size=8192 仍适用于跑在 Node 下的测试进程。
若子包目录单独维护锁文件,把 hashFiles 模式改为 **/Bun.lockb、**/package-lock.json 或在矩阵 Job 里按 workspace 分键,避免「子锁已变、根键未变」的假命中。
lockfile 一致性验收(不写 SPM、不写 Docker)
Bun.lockb 为二进制,合并冲突时肉眼 diff 困难:请在 CI 增加「锁文件存在性 + frozen 安装」即可验证可复现性;代码评审依赖 bun lockfile 迁移工具或团队约定的 lock 导出流程。package-lock.json 适合在合并请求展示 npm ls --package-lock-only 的摘要。混仓反模式是本地用 Bun 改依赖却未更新 npm 锁,或反之;建议在 package.json 的 packageManager 字段声明主安装器,并在 pre-commit 或 CI 首步校验声明与真实命令一致。
精简 FAQ
能否只缓存 node_modules 不缓存 Bun 目录?
不推荐跨 Job 直接 tarball 整个 node_modules(路径与可选依赖平台片段易碎)。更稳的是缓存 BUN_INSTALL_CACHE_DIR 与 npm 的 cache root,再每次 frozen/ci 重放。
镜像返回的 tarball 与上游哈希不一致怎么办?
立即切换镜像线路或改透传代理;不要把「跳过完整性校验」写进默认流水线,远程共享机上的 supply-chain 风险会被放大。
总结:二零二六年要在远程 Mac CI上把 Bun 与 npm 混仓跑稳,先把双锁与双 registry 环境变量对齐,再用缓存键把「锁 + 架构 + 运行时版本」绑死,最后用三轮指数退避兜住跨境抖动。需要可预期出口与独占算力时,可打开 https://macpull.com/zh/index.html 了解方案,并直接访问 定价、帮助中心、购买页(均无需登录即可浏览)。