如何避免在Gitlab CI中重新安装每个作业的依赖项

时间:2015-11-04 15:54:06

标签: gitlab-ci gitlab-ci-runner

我使用Gitlab CI 8.0与gitlab-ci-multi-runner 0.6.0。我有一个类似于以下内容的getExactSizeIfKnown()文件:

.gitlab-ci.yml

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

在Jenkins中,我会使用一个作业来安装依赖项,然后对它们进行TAR,然后创建一个构建工件,然后将其复制到下游作业。类似的东西可以与Gitlab CI一起使用吗?有推荐的方法吗?

6 个答案:

答案 0 :(得分:11)

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

Gitlab CI 8.2添加runner caching,可让您在构建之间重用文件。但是我发现这很慢。

相反,我使用一些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

答案 1 :(得分:9)

这些天更好的方法是使用artifacts

在以下示例中,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 目录。

    AppDelegate.getInstatnce().nav = self.navigationController as! ScrollingNavigationController
AppDelegate.getInstatnce().nav.scrollingNavbarDelegate = self

答案 2 :(得分:2)

  

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

示例

random shuffle

答案 3 :(得分:2)

来自docs

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

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

  •   

因此,我使用cache。当不需要更新缓存时(例如,在测试作业中生成文件夹),我使用policy: pull(请参见here)。

答案 4 :(得分: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()

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

答案 5 :(得分:0)

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

  1. 首先,所有构建作业都是并行执行的。
  2. 如果构建的所有作业都成功,​​则测试作业将并行执行。
  3. 如果所有测试作业都成功,​​则部署作业将并行执行。
  4. 如果部署的所有作业都成功,​​则提交将标记为成功。
  5. 如果以前的任何作业失败,则提交被标记为失败,并且不会执行更多阶段的作业。
  6. 我在这里读过:

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