GitLab CI缓存键应结合CI_COMMIT_REF_SLUG与依赖文件哈希(如files: [package-lock.json])实现分支隔离与内容感知,推荐写法:key: {files: [package-lock.json], prefix: ${CI_COMMIT_REF_SLUG}},确保分支独立且依赖更新时自动刷新缓存。

关键在于让 cache key 同时体现“分支身份”和“依赖内容变化”,避免不同分支共用缓存导致构建错乱或失效。
用 CI_COMMIT_REF_SLUG 做基础分支隔离
这是最直接的方式,每个分支(包括 main、dev、feat/xxx)都会生成唯一 slug(如 main、dev、feat-add-login),天然隔离缓存:
- 配置示例:
key: ${CI_COMMIT_REF_SLUG} - 效果:main 分支的 node_modules 缓存在 key=main 下,dev 分支走 key=dev,互不干扰
- 注意:tag 构建会生成类似 v1-0-0 的 slug,也自动独立,适合发布流程
结合 files + prefix 防止缓存长期 stale
仅靠分支名会导致缓存“永远不更新”——即使 package-lock.json 已改,只要还在同一分支,就一直复用旧缓存。解决方法是把依赖文件哈希融入 key:
- 推荐写法:
key: files: [package-lock.json] prefix: ${CI_COMMIT_REF_SLUG} - GitLab 会计算 package-lock.json 的 SHA,再拼上前缀,最终 key 类似
main-8a3f2c1... - 只要该文件没变,key 不变,缓存复用;一旦提交了新依赖,key 自动刷新,触发重新安装
- 最多支持指定两个文件(如同时监控
package-lock.json和pnpm-lock.yaml)
按 job 类型进一步细分(可选)
如果同一分支下多个 job(如 lint、test、build)需要各自独立缓存(比如 test 要缓存测试工具,build 要缓存编译产物),可在 prefix 中加入 job 名:
- 示例:
key: files: [package-lock.json] prefix: ${CI_COMMIT_REF_SLUG}-${CI_JOB_NAME} - 这样 lint 和 build 即使在 dev 分支,也会使用不同的 key,避免相互覆盖
- 适用于多阶段、多语言混合项目,或对缓存一致性要求极高的场景
缓存路径与容错设计
cache key 再精准,也要配合合理的 paths 和健壮逻辑:
-
paths明确限定只缓存必要目录,例如:- node_modules/ - .pnpm-store/,避免污染 - 始终保留安装命令(如
npm ci或pnpm install),即使缓存命中失败也能兜底构建 - 不要依赖
untracked: true来缓存构建产物(如 dist/),这类内容更适合用 artifacts 传递


















