如何在 GitHub Actions 中缓存 yarn 包

Bat*_*rka 22 typescript yarnpkg github-actions

我正在使用 GitHub Actions 来构建我的 TypeScript 项目。每次运行操作时,我都会等待 3 分钟以安装所有依赖项。

有没有办法缓存纱线依赖项,所以构建时间会更快?

我试过这个:

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

     - uses: actions/cache@v1
       id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
       with:
         path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
         key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
         restore-keys: |
           ${{ runner.os }}-yarn-

    - name: Install yarn
      run: npm install -g yarn

    - name: Install project dependencies
      run: yarn
Run Code Online (Sandbox Code Playgroud)

但构建时间仍然相同。

Ven*_*sky 42

正如github 包自述文件所说:

steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
  with:
    node-version: '14'
    cache: 'npm' # or yarn
- run: npm install
- run: npm test
Run Code Online (Sandbox Code Playgroud)

编辑:

事实证明,文档的编写方式非常具有误导性,他们进行了更新,以明确它不会缓存node_modules文件夹,而只会缓存全局缓存目录,如本期所述。

也正如 Mrchief 在评论中所说:

...您仍然会遇到npm i time,只需节省从互联网下载的时间(如果模块位于 npm 缓存中)

因此,您仍然应该使用从互联网下载软件包来节省时间,但如果您想缓存node_modules文件夹,请检查使用actions/cache 的其他答案。

您还应该检查Quang Lam 的答案及其关于为什么不应该缓存node_modules文件夹的评论。

  • 其他答案要么不使用 setup-node 要么使用 v1。v2 中添加了缓存。这应该是现在公认的答案。 (4认同)
  • 此方法不缓存“node_modules”,而是全局缓存(在 npm 的情况下为“.npm”)。因此,您仍然会产生“npm i”时间,只需节省从互联网下载的时间(如果模块位于 npm 缓存中)。 (2认同)

Qua*_*Lam 34

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

     - uses: actions/cache@v1
       id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
       with:
         path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
         key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
         restore-keys: |
           ${{ runner.os }}-yarn-
Run Code Online (Sandbox Code Playgroud)

上面的缓存代码只缓存和恢复yarn缓存目录,不缓存node_modules目录。因此,如果您使用此代码(@Edric 的回答),

- name: Install project dependencies
  if: steps.yarn-cache.outputs.cache-hit != 'true' # Over here!
  run: yarn
Run Code Online (Sandbox Code Playgroud)

node_modules 未创建,您将收到未找到依赖项错误。

相反,你可以使用这个:

- name: Install project dependencies
  run: yarn --prefer-offline
Run Code Online (Sandbox Code Playgroud)

这告诉yarn始终运行但尽可能使用缓存下载(在上面提到的缓存目录中)而不是从服务器下载。


您也可以node_modules直接缓存目录,当缓存可用时跳过安装步骤。这实际上是不推荐的(见评论)。例子:

    - name: Get yarn cache directory path
      id: yarn-cache-dir-path
      run: echo "::set-output name=dir::$(yarn cache dir)"
    - name: Cache yarn cache
      uses: actions/cache@v2
      id: cache-yarn-cache
      with:
        path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
        key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
        restore-keys: |
          ${{ runner.os }}-yarn-
    - name: Cache node_modules
      id: cache-node-modules
      uses: actions/cache@v2
      with:
        path: node_modules
        key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules-${{ hashFiles('**/yarn.lock') }}
        restore-keys: |
          ${{ runner.os }}-${{ matrix.node-version }}-nodemodules-
    - run: yarn
      if: |
        steps.cache-yarn-cache.outputs.cache-hit != 'true' ||
        steps.cache-node-modules.outputs.cache-hit != 'true'
Run Code Online (Sandbox Code Playgroud)

  • @Penguin @racemic 你可以缓存node_modules,它会工作得很好。但“node_modules”可能已损坏。每次重新运行“yarn”并让“yarn”决定是否从缓存中获取文件会更安全(假设“yarn”在使用缓存之前会尝试验证缓存)。 (3认同)
  • 此外,“yarn”本身几乎能够检测依赖项是否必须更新。例如,当第二次在本地运行“yarn”安装时,它会在不到 1 秒的时间内完成。我认为在任何情况下都不应该跳过“yarn”步骤。 (2认同)
  • 既然我们还在最后一个代码示例中检查了缓存的yarn.lock,那么其他人是否可以澄清“不推荐”是否适合使用?我已经测试过添加/删除包,并且似乎可以可靠地捕捉到这些差异。谢谢 (2认同)
  • 为什么不推荐缓存node_modules? (2认同)

thi*_*ign 12

actions/setup-node自 v2 起支持缓存并提供多个自定义选项

- uses: actions/checkout@v3

- name: Setup Node.js
  uses: actions/setup-node@v3
  with:
    node-version: '16'
    cache: 'yarn'

- name: Install JS dependencies
  run: yarn install
Run Code Online (Sandbox Code Playgroud)

缓存按照建议进行,仅缓存yarn cache dir和不缓存node_modulesnode_modules不建议使用缓存,因为它可能会导致问题,例如当节点版本更改时。


旧答案:

这是专门用于 Yarn 的 1-liner 缓存:https ://github.com/c-hive/gha-yarn-cache

它按照 GitHub 的建议进行缓存。支持 Yarn v1 和 v2。

NPM 相同:https: //github.com/c-hive/gha-npm-cache

  • 在示例中,这仍然是 1 行与 10 行的比较。 (2认同)
  • 它在幕后执行相同的命令。 (2认同)

Edr*_*ric 11

id缓存步骤字段旁边的评论中所述:

用它来检查cache-hit( steps.yarn-cache.outputs.cache-hit != 'true')

您缺少if确定是否应运行该步骤的条件属性:

- name: Install yarn
  run: npm install -g yarn

- name: Install project dependencies
  if: steps.yarn-cache.outputs.cache-hit != 'true' # Over here!
  run: yarn
Run Code Online (Sandbox Code Playgroud)

PS您可能应该使用Setup NodeJS GitHub Action,它另外为您设置Yarn:

- uses: actions/setup-node@v1
  with:
    node-version: '10.x' # The version spec of the version to use.
Run Code Online (Sandbox Code Playgroud)

有关有效输入的完整列表,请参阅action.yml文件


编辑:事实证明,Yarn 包含在GitHub 托管的 Ubuntu 18.04.4 LTS ( ubuntu-latest/ ubuntu-18.04) runner上安装软件列表中,因此无需包含全局安装 Yarn 的步骤。

  • 谢谢,这有效。但运行笑话时操作失败。`jest --config=jest.config.js /bin/sh: 1: jest: not find error 命令失败,退出代码 127` 此外,禁用缓存的操作成功。 (2认同)