31

我正在使用带有gitlab-ci-multi-runner 0.6.0的Gitlab CI 8.0 。我有一个类似于以下的文件:.gitlab-ci.yml

before_script:
  - npm install

server_tests:
  script: mocha

client_tests:
  script: karma start karma.conf.js

这可行,但这意味着在每个测试作业之前独立安装依赖项。对于具有许多依赖项的大型项目,这会增加相当大的开销。

在 Jenkins 中,我会使用一个作业来安装依赖项,然后将它们 TAR 并创建一个构建工件,然后将其复制到下游作业。Gitlab CI 会做类似的事情吗?有推荐的方法吗?

4

7 回答 7

17

更新:我现在建议使用artifacts简短的expire_in. 这优于cache因为它只需要在每个管道中写入一次工件,而在每个作业之后更新缓存。此外,缓存是每个运行器的,因此如果您在多个运行器上并行运行作业,则不能保证填充它,这与集中存储的工件不同。


Gitlab CI 8.2 添加了运行器缓存,可让您在构建之间重用文件。但是我发现这非常慢。

相反,我使用一些 shell 脚本实现了我自己的缓存系统:

before_script:
  # unique hash of required dependencies
  - PACKAGE_HASH=($(md5sum package.json))
  # path to cache file
  - DEPS_CACHE=/tmp/dependencies_${PACKAGE_HASH}.tar.gz
  # Check if cache file exists and if not, create it
  - if [ -f $DEPS_CACHE ];
    then
      tar zxf $DEPS_CACHE;
    else
      npm install --quiet;
      tar zcf - ./node_modules > $DEPS_CACHE;
    fi

这将在您的每个作业之前运行,.gitlab-ci.yml并且仅在package.json已更改或缓存文件丢失(例如第一次运行或文件被手动删除)时安装您的依赖项。请注意,如果您在不同的服务器上有多个运行器,它们每个都有自己的缓存文件。

您可能需要定期清除缓存文件以获取最新的依赖项。我们使用以下 cron 条目执行此操作:

@daily               find /tmp/dependencies_* -mtime +1 -type f -delete
于 2015-12-03T17:33:45.653 回答
9

编辑:此解决方案在 2016 年被推荐。在 2021 年,您可能会考虑使用缓存文档

如今,一种更好的方法是利用工件

在以下示例中,一旦阶段成功完成,该node_modules/目录立即可供lint作业使用。build

build:
  stage: build
  script:
    - npm install -q
    - npm run build
  artifacts:
    paths:
      - node_modules/
  expire_in: 1 week

lint:
  stage: test
  script:
    - npm run lint
于 2016-09-27T07:35:00.520 回答
7

来自文档

  • cache用于项目依赖项的临时存储。对于保留中间构建结果(如jarapk文件)没有用处。缓存旨在用于加速给定作业的后续运行的调用,通过保留依赖项(例如,npm 包、Go 供应商包等),因此不必从公共重新获取它们互联网。虽然可以滥用缓存在阶段之间传递中间构建结果,但在某些情况下可能更适合工件。

  • artifacts用于将在阶段之间传递的阶段结果。Artifacts 旨在上传构建的一些已编译/生成的位,并且它们可以由任意数量的并发 Runners 获取。它们保证可用,并且可以在作业之间传递数据。它们也可以从 UI 下载。工件只能存在于与构建目录相关的目录中,并且指定不符合此规则的路径会触发不直观且不合逻辑的错误消息(在https://gitlab.com/gitlab-org/gitlab-ce讨论了增强/问题/15530)。工件需要在下一个阶段作业开始之前上传到 GitLab 实例(不仅是 GitLab 运行器),因此您需要在投入时间之前仔细评估您的带宽是否允许您从阶段和共享工件的并行化中获利在更改设置。

所以,我用cache. 当不需要更新缓存时(例如,在测试作业中构建文件夹),我使用policy: pull(见这里)。

于 2019-06-21T16:03:25.430 回答
3

我更喜欢使用缓存,因为管道完成时会删除文件。

例子

image: node

stages:
 - install
 - test
 - compile

cache:
 key: modules
 paths:
  - node_modules/

install:modules:
 stage: install
 cache:
  key: modules
  paths:
    - node_modules/
  after_script:
   - node -v && npm -v
  script:
  - npm i

test:
 stage: test
 cache:
   key: modules
   paths:
     - node_modules/
   policy: pull
 before_script:
  - node -v && npm -v
 script:
- npm run test

compile:
 stage: compile
 cache:
 key: modules
 paths:
   - node_modules/
 policy: pull
 script:
  - npm run build
于 2018-08-14T20:16:49.850 回答
1

我认为不建议这样做,因为同一阶段的所有作业都可以并行执行。

  1. 首先,构建的所有作业都是并行执行的。
  2. 如果构建的所有作业都成功,​​则并行执行测试作业。
  3. 如果测试的所有作业都成功,​​则部署作业并行执行。
  4. 如果部署的所有作业都成功,​​则提交标记为成功。
  5. 如果任何先前的作业失败,则提交被标记为失败并且不执行进一步阶段的作业。

我在这里读过:

http://doc.gitlab.com/ci/yaml/README.html

于 2015-11-04T16:10:19.770 回答
1

解决了指向工作目录外文件夹的符号链接的问题。解决方案如下所示:

//.gitlab-ci.yml
before_script:
  - New-Item -ItemType SymbolicLink -Path ".\node_modules" -Target "C:\GitLab-Runner\cache\node_modules"
  - yarn

after_script:
  - (Get-Item ".\node_modules").Delete()

我知道这是一个足够肮脏的解决方案,但它为构建过程节省了大量时间并延长了存储寿命。

于 2021-06-08T02:46:35.143 回答
0

GitLab 引入了缓存以避免重新下载每个作业的依赖项。

以下 Node.js 示例的灵感来自缓存文档

image: node:latest

# Cache modules in between jobs
cache:
  key: $CI_COMMIT_REF_SLUG
  paths:
    - .npm/

before_script:
  - npm ci --cache .npm --prefer-offline

server_tests:
  script: mocha

client_tests:
  script: karma start karma.conf.js

请注意,该示例使用npm ci. 此命令类似于npm install,但设计用于自动化环境。npm ci您可以在文档中阅读更多信息以及可以传递的命令行参数。

有关更多信息,请查看GitLab CI/CD中的缓存和缓存关键字参考

于 2021-12-20T13:15:39.817 回答