在 GitLab CI 包构建中缓存 gem

Posted

技术标签:

【中文标题】在 GitLab CI 包构建中缓存 gem【英文标题】:Cache gems in GitLab CI bundle build 【发布时间】:2016-08-27 06:02:18 【问题描述】:

我正在使用 docker 映像对一堆存储库进行测试。每个存储库都有自己的测试,当然还有自己的 Gemfile。所以,基本上,每当我对这些存储库做出承诺时,就会开始一个新的构建。在此版本中,GitLab:

    下载 docker 镜像。 安装所有需要的 gem。 运行测试。

docker 镜像有一些预安装的包,比如 ruby​​ 或 gcc,所以我不会浪费任何时间在每个构建中重新安装这些包,但我仍然必须安装所有的 gem,因为每个存储库都有自己的 Gemfile,它们有点不同。

问题是,我可以做些什么来缩短构建时间?我在 build install 命令上浪费了很多时间,而且大部分时间它一遍又一遍地为每个存储库安装相同的包。

【问题讨论】:

你能发布你的 .gitlab-ci.yml 的样子吗? 【参考方案1】:

根据doc,例如gitlab-ci.yml

image: ruby:2.5.1

cache:
  key: $CI_PROJECT_NAME
  paths:
  - vendor/ruby

test:
  script:
  - bundle install -j $(nproc) --path vendor
  - gem install rubocop --no-ri --no-rdoc
  - rubocop

staging:
  type: deploy
  script:
  - gem install dpl
  - dpl --provider=heroku --app=apmcheck-admin-dev --api-key=$HEROKU_API_KEY
  only:
  - develop

production:
  type: deploy
  script:
  - gem install dpl
  - dpl --provider=heroku --app=apmcheck-admin --api-key=$HEROKU_API_KEY
  only:
  - master

这会将您的 gem 添加到缓存中,并在另一个构建中重新使用它。但是,当 build 将在另一个 executor 上运行时,它可能不会被使用。

【讨论】:

【参考方案2】:

我对 ruby​​ 不是很熟悉,但在某些语言中,您可以为已安装的库提供本地缓存。如果你可以用 ruby​​ 做到这一点,我相信你可以。您可以将此缓存存储在主机(或数据容器)上,并将通过卷缓存的挂载存储到每个容器中。

这就是它的工作原理。

您创建缓存并将其安装在容器中,然后在安装 gems 时将您的 ruby​​ 应用程序指定为使用此缓存。如果 gem 在缓存中,它将在本地获取它,如果没有,则需要下载它。现在它将在下次本地提供。本地缓存应该更快(不下载)。由于您在项目之间共享缓存,因此应该可以减少构建时间。

选项 2:您创建一个包含所有常见 gem 的基础映像,并将其用于您的测试。这很难保持同步并导致图像臃肿。

【讨论】:

其实问题是关于如何配置 GitLab CI 来缓存 ruby​​ gems,参考文档 — docs.gitlab.com/ee/ci/caching/#caching-ruby-dependencies

以上是关于在 GitLab CI 包构建中缓存 gem的主要内容,如果未能解决你的问题,请参考以下文章

Gitlab CI 中缓存/工件的正确用法是啥?

Artifactory & GitLab CI持续集成实践

Artifactory & GitLab CI持续集成实践

如何为 GitLab CI 运行器启用 Maven 工件缓存?

Gitlab CI gradle依赖缓存

【Gitlab ci】 缓存