Bli*_*air 8 caching gitlab-ci npm-install
我在 gitlab 中有一个带有角度前端和 nestjs 后端的 monorepo。我每个人都有 package.json ,根中有 1 个。我的管道由多个阶段组成,如下所示:
stages:
- build
- verify
- test
- deploy
Run Code Online (Sandbox Code Playgroud)
我在.pre安装依赖项的阶段有一份工作。我想在作业之间和分支之间缓存那些,如果有任何package-lock.json更改,但如果node_modules当前没有缓存。我有一份看起来像这样的工作:
prepare:
stage: .pre
script:
- npm run ci-deps # runs npm ci in each folder
cache:
key: $CI_PROJECT_ID
paths:
- node_modules/
- frontend/node_modules/
- backend/node_modules/
only:
changes:
- '**/package-lock.json'
Run Code Online (Sandbox Code Playgroud)
现在的问题是,如果缓存以某种方式被清除,或者如果我没有package-lock.json在第一次推送时引入更改,我将根本不会运行此作业,因此其他一切都会失败,因为它需要node_modules. 如果我changes:从那里删除,那么它会为每个管道运行作业。当然,我仍然可以在作业之间共享它,但是如果我再次提交并推送它需要近 2 分钟来安装所有依赖项,即使我没有更改任何关于应该存在的内容......我错过了什么吗?如何以某种方式缓存它,以便仅在缓存过时或不存在时才重新安装依赖项?
Rules:Exists 在缓存被拉下之前运行,因此这对我来说不是一个可行的解决方案。
在 GitLab v12.5 中我们现在可以使用cache:key:files
如果我们将其与 Blind Despair 的条件逻辑的一部分结合起来,我们会得到一个很好的解决方案
prepare:
stage: .pre
image: node:12
script:
- if [[ ! -d node_modules ]];
then
npm ci;
fi
cache:
key:
files:
- package-lock.json
prefix: nm-$CI_PROJECT_NAME
paths:
- node_modules/
Run Code Online (Sandbox Code Playgroud)
然后我们可以在后续的构建作业中使用它
# let's keep it dry with templates
.use_cached_node_modules: &use_cached_node_modules
cache:
key:
files:
- package-lock.json
prefix: nm-$CI_PROJECT_NAME
paths:
- node_modules/
policy: pull # don't push unnecessarily
build:
<<: *use_cached_node_modules
stage: build
image: node:12
script:
- npm run build
Run Code Online (Sandbox Code Playgroud)
我们通过共享缓存在多个分支中成功地使用了它。
最后我认为我可以在不依赖 gitlab ci 功能的情况下做到这一点,但我自己进行检查,如下所示:
prepare:
stage: .pre
image: node:12
script:
- if [[ ! -d node_modules ]] || [[ -n `git diff --name-only HEAD~1 HEAD | grep "\package.json\b"` ]];
then
npm ci;
fi
- if [[ ! -d frontend/node_modules ]] || [[ -n `git diff --name-only HEAD~1 HEAD | grep "\frontend/package.json\b"` ]];
then
npm run ci-deps:frontend;
fi
- if [[ ! -d backend/node_modules ]] || [[ -n `git diff --name-only HEAD~1 HEAD | grep "\backend/package.json\b"` ]];
then
npm run ci-deps:backend;
fi
cache:
key: '$CI_COMMIT_REF_SLUG-$CI_PROJECT_DIR'
paths:
- node_modules/
- frontend/node_modules
- backend/node_modules
Run Code Online (Sandbox Code Playgroud)
这样做的好处是,如果项目还没有 node_modules 或 package.json 发生更改,它只会安装项目特定部分的依赖项。然而,如果我推送多个提交并且 package.json 不会在最后一个提交中更改,则这可能是错误的。在这种情况下,我仍然可以手动清除缓存并重新运行管道,但我将尝试进一步改进我的脚本并更新我的答案。
| 归档时间: |
|
| 查看次数: |
1852 次 |
| 最近记录: |