GitHub Actions 缓存依赖时,key 里记得带 lockfile

10 次浏览3 条回复

CI 每次都重新下载依赖时,可以让缓存键跟 lockfile 的 hash 绑定。Node 项目可以直接这样写:

name: test
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm test

setup-node 会根据 package-lock.json 生成缓存键,锁文件变化后就不会误用旧依赖。环境:GitHub Actions、Node 20、npm,仓库里要提交 package-lock.json。这里缓存的是 npm 下载内容,不是跳过 npm ci。

monorepo 里 lockfile 不在仓库根目录时,建议把路径显式写出来,不然缓存键可能没跟实际锁文件走:

with:
  node-version: 20
  cache: npm
  cache-dependency-path: apps/web/package-lock.json

多个 lockfile 也可以用多行值列出来。npm ci 还是照常执行,这里只是复用 npm 的下载缓存。

MukiLv1#1

monorepo 里 lockfile 不在仓库根目录时,建议把路径显式写出来,不然缓存键可能没跟实际锁文件走:

with:
  node-version: 20
  cache: npm
  cache-dependency-path: apps/web/package-lock.json

多个 lockfile 也可以用多行值列出来。npm ci 还是照常执行,这里只是复用 npm 的下载缓存。

monorepo 这个补充很关键。再提醒一个容易混的点:cache-dependency-path 只负责让缓存跟指定的 lockfile 关联,不会替 npm ci 切换工作目录。如果安装是在 apps/web 里跑,run 步骤也要配对应的 working-directory,不然缓存命中了,安装仍可能读根目录的 lockfile。

雾很大Lv1#2

monorepo 这个补充很关键。再提醒一个容易混的点:cache-dependency-path 只负责让缓存跟指定的 lockfile 关联,不会替 npm ci 切换工作目录。如果安装是在 apps/web 里跑,run 步骤也要配对应的 working-directory,不然缓存命中了,安装仍可能读根目录的 lockfile。

如果是 npm workspaces,这里还要区分一下:通常应在仓库根目录跑 npm ci,并让 cache-dependency-path 指向根目录实际使用的 package-lock.json。只有各应用是独立 npm 项目时,才把安装步骤切到 apps/web。不然缓存和安装目录都配对了,依赖解析范围还是可能不对。