如何在 GitHub Actions 中缓存纱线包
Posted
技术标签:
【中文标题】如何在 GitHub Actions 中缓存纱线包【英文标题】:How to cache yarn packages in GitHub Actions 【发布时间】:2020-07-15 12:41:47 【问题描述】:我正在使用 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
但构建时间仍然相同。
【问题讨论】:
【参考方案1】: - 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-
上面的缓存代码只缓存和恢复yarn缓存目录,不缓存node_modules
目录。因此,如果您使用此代码(@Edric 的回答),
- name: Install project dependencies
if: steps.yarn-cache.outputs.cache-hit != 'true' # Over here!
run: yarn
node_modules
未创建,您将收到未找到依赖项的错误。
相反,你可以使用这个:
- name: Install project dependencies
run: yarn --prefer-offline
这告诉yarn
始终运行,但尽可能使用缓存下载(在上述缓存目录中),而不是从服务器下载。
您也可以直接缓存node_modules
目录,当缓存可用时跳过安装步骤。这实际上是不推荐的(见 cmets)。示例:
- 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'
【讨论】:
另外,yarn
本身几乎能够检测依赖项是否必须更新。例如,当第二次在本地运行yarn
install 时,它会在不到 1 秒的时间内完成。我认为在任何情况下都不应跳过yarn
步骤。
谢谢你们的cmets,伙计们!我完全同意。我已经更新了答案以使其更清晰。
现在我们还检查了最后一个代码示例中缓存的 yarn.lock,其他任何人都可以澄清“不推荐”的适合使用吗?我已经测试了添加/删除软件包,并且似乎对我来说可靠地捕捉到了这些差异。谢谢
为什么不推荐缓存node_modules??
@Penguin @racemic 你可以缓存node_modules,它会工作得很好。但是node_modules
可能已损坏。每次重新运行yarn
并让yarn
决定是否从缓存中获取文件会更安全(假设yarn
在使用之前会尝试验证缓存)。【参考方案2】:
我不知道为什么其他答案没有提到使用内置的actions/setup-node@v2缓存npm和yarn依赖项的简单方法,所以我只添加文档,这更简单。
正如github package 的readme 所说:
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
cache: 'npm' # or yarn
- run: npm install
- run: npm test
【讨论】:
其他答案要么不使用 setup-node 要么使用 v1。缓存是在 v2 中添加的。这应该是现在公认的答案。【参考方案3】:正如缓存步骤的 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
附:您可能应该使用另外为您设置 Yarn 的 Setup NodeJS GitHub Action:
- uses: actions/setup-node@v1
with:
node-version: '10.x' # The version spec of the version to use.
有关有效输入的完整列表,请参阅action.yml
file。
编辑:事实证明,Yarn 包含在 software installed on the GitHub-hosted Ubuntu 18.04.4 LTS (ubuntu-latest
/ubuntu-18.04
) runner 列表中,因此无需包含全局安装 Yarn 的步骤。
【讨论】:
这是我的配置:pastebin.com/CCgFjEW0我已经在使用actions/setup-node@v1
,所以我不需要安装yarn?
遗憾的是,条件“如果”没有帮助。
对于第一条评论,请参阅我对答案所做的编辑。至于第二条评论,您能否指出 如何 条件 if
属性没有帮助?
谢谢,这行得通。但是在运行笑话时操作失败。 jest --config=jest.config.js /bin/sh: 1: jest: not found error Command failed with exit code 127
另外,禁用缓存的操作成功。【参考方案4】:
这是专为 Yarn 设计的 1 行缓存:https://github.com/c-hive/gha-yarn-cache
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12.x
- uses: c-hive/gha-yarn-cache@v1
- name: Install JS dependencies
run: yarn install
- name: Test
run: yarn test
它按照 GitHub 的建议进行缓存。支持 Yarn v1 和 v2。
【讨论】:
对于那些投反对票的人,请添加一些 cmets 为什么你投反对票:) 我猜这是现在内置的:github.com/actions/cache/blob/main/examples.md#node---yarn 在示例中这仍然是 1-liner vs 10 行。 是的,我也不认为这应该被否决。问题是“如何在 GitHub Actions 中缓存纱线包”,它回答了它。我相信其他答案提供了更多的深度,但这对于寻求快速解决方案的人来说真的很有帮助。出于好奇,您是否测试过这一班轮的性能?它是更快、更慢还是和更长的一样? 它在后台执行相同的命令。以上是关于如何在 GitHub Actions 中缓存纱线包的主要内容,如果未能解决你的问题,请参考以下文章
在 GitHub Actions 工作流程中缓存 APT 包
如何在 Github Actions 工作流中从 Github 包访问 Maven 依赖项?
在 Windows 上的 GitHub Actions 中缓存依赖项
在 github 上的 Dependabot 警报后升级特定包纱线锁