使用 GitHub Action 缓存 npm 依赖项。

17

我希望能够缓存npm依赖项,这样我每次推送时就不必再执行npm install,而是直接从缓存中加载。

我想github action现在支持这个功能了吧?:如何在GitHub Actions中缓存步骤?

以下是几种情况:

  • 如果package.json更改了,则表示yarn.lockpackage-lock.json也会更改,因此需要执行npm install并更新缓存
  • 扩展上述观点,贡献者可能会同时执行yarn installnpm install

根据上述问题,我将我的github action更改为以下内容:

name: Tsc compilation test
on: [push, pull_request]
jobs:
  build:
    name: Build
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Cache NPM dependencies
        uses: actions/cache@v1
        with:
          path: ~/.npm
          key: ${{ runner.OS }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.OS }}-npm-cache-
      - name: Install dependencies
        run: npm install
      - name: Test tsc
        run: npm run ts-compile-check

我仍然执行了npm install,但安装依赖项的计算时间没有减少(所以我不确定这是否正常工作)

然后我执行了yarn install axios,希望更新我的缓存,但在安装后我看到以下内容被记录下来:

Post job cleanup.
Cache hit occurred on the primary key Linux-npm-cache-, not saving cache.

所以这是我的问题,是否有可能实现:

  • 如果 package.json 发生更改,则意味着 yarn.lockpackage-lock.json 也发生了更改,因此执行 npm install 并更新缓存。
  • 扩展我上面的观点,贡献者可以同时执行 yarn installnpm install

还有人能解释一下这个吗?

    with:
      path: ~/.npm
      key: ${{ runner.OS }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.OS }}-npm-cache-

另一个类似于 https://github.com/actions/cache 的操作是否更好?或者像 https://github.com/tinovyatkin/alphabank-pay-node/blob/a4ef58615423a4d6388a4702c3130603136a3ec7/.github/workflows/npmpublish.yml 这样的示例是否显示了一些差异,使您的情况更好地工作? - VonC
有关键的详细信息,请参见https://github.com/ktmud/cached-dependencies#cache-configs。 - VonC
3
你的 package-lock.json 文件是否已经提交到代码仓库了?如果没有,缓存键将无法正确计算,因为锁定文件只会在下一步生成。 - Daniel Hollas
1个回答

16
为了使 GitHub actions 缓存更加高效,需要有一个名为 package-lock.jsonyarn.lock 的文件。这个文件在安装包时会自动生成。如果您想要更多关于 package-lock.json 的信息,请查看文档
现在存在一个问题,就是是否应该在同一项目中使用 npm 和 yarn。关于这个问题的更多信息请看这里
根据问题,我们假设同时存在 package-lock.json 和 yarn.lock 两个文件。如果只使用其中一个,请将另一个删除。以下配置适用于 yarn 版本2,它使用 yarn config get cacheFolder 获取缓存文件夹。对于其他版本的 yarn,请参见文档
name: Tsc compilation test
on: [push, pull_request]
jobs:
  build:
    name: Build
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn config get cacheFolder)"

      - name: Cache yarn dependencies
        uses: actions/cache@v2
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

      - name: Cache npm dependencies
        uses: actions/cache@v2
        with:
          path: '~/.npm'
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install dependencies
        run: npm install # or yarn install

      - name: Test tsc
        run: npm run ts-compile-check

就这样!好了,除了一件事。我们在上面使用~/.npm进行缓存npm依赖项。从性能角度来看,缓存**/node_modules会更快,但在某些情况下,这可能会引起冲突。可以随意尝试,看看哪个适合您。有关更多信息,请参见此处此处


从您的问题中,您还要求解释以下代码:

    with:
      path: ~/.npm
      key: ${{ runner.OS }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.OS }}-npm-cache-

https://github.com/actions/cache#usage:

path - 要缓存和恢复的文件、目录和通配符模式列表。请参阅 @actions/glob 以获取支持的模式。
key - 用于恢复和保存缓存的显式键
restore-keys - 用于在没有与 key 匹配的情况下恢复缓存的键的有序列表

因此,上述代码:

  • path 是将被缓存/恢复(依赖项安装的)文件夹。
  • key 是用于缓存路径的唯一标识符。在这种情况下,它使用 hashFiles 哈希任何 **/package-lock.json 文件的内容。基本上,当 package-lock.json 文件发生更改时,这意味着依赖项已更改,不应该使用缓存。
  • restore-keys 基本上是没有与 key 匹配的情况下使用的默认键。

3
此操作将缓存npm依赖项,但不会跳过npm install。为了实现这一点,您需要在缓存步骤中添加一个id,例如id: cache-npm-deps,然后在安装依赖项步骤中添加if: steps.cache-npm-deps.outputs.cache-hit != 'true' - Marko Francekovic
2
缓存并不意味着您永远不必安装依赖项。相反,它意味着当自上次安装以来未更改的依赖项时,Node.js可以跳过下载和编译步骤。当您运行npm install或npm ci时,Node.js将检查您的node_modules文件夹和package-lock.json文件。如果已安装的软件包版本与package-lock.json中指定的版本匹配,则Node.js可以使用缓存的版本,而无需再次下载和编译它。 - Gökhan Taşkan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接