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

Posted

技术标签:

【中文标题】Gitlab CI 中缓存/工件的正确用法是啥?【英文标题】:What is the correct usage of cache/artifacts in Gitlab CI?Gitlab CI 中缓存/工件的正确用法是什么? 【发布时间】:2018-02-27 02:41:38 【问题描述】:

当项目构建中未使用缓存文件时,我遇到了一个问题。就我而言,我想在构建阶段下载作曲家依赖项,然后在所有其他阶段成功后将它们添加到最终项目文件夹中。我想如果你将cache 属性设置为.gitlab-ci.yml 文件,它也会被共享并在其他阶段使用。但这有时有效,有时无效。

Gitlab 版本为 9.5.4

这是我的.gitlab-ci.yml 文件:

image: ponk/debian:jessie-ssh

variables:
    WEBSERVER: "user@example.com"
    WEBSERVER_DEPLOY_DIR: "/domains/example.com/web-presentation/deploy/"
    WEBSERVER_CDN_DIR: "/domains/example.com/web-presentation/cdn/"
    TEST_VENDOR: '[ "$(ls -A $WEBSERVER_DEPLOY_DIR$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA/vendor)" ]'

cache:
  key: $CI_PIPELINE_ID
  untracked: true
  paths:
    - vendor/

before_script:


stages:
    - build
    - tests
    - deploy
    - post-deploy

Build sources:
    image: ponk/php5.6
    stage: build
    script:
        # Install composer dependencies
        - composer -n install --no-progress
    only:
        - tags
        - staging


Deploy to Webserver:
    stage: deploy
    script:
        - echo "DEPLOYING TO ... $WEBSERVER_DEPLOY_DIR$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA"
        - ssh $WEBSERVER mkdir -p $WEBSERVER_DEPLOY_DIR$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA
        - rsync -rzha app bin vendor www .htaccess $WEBSERVER:$WEBSERVER_DEPLOY_DIR$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA
        - ssh $WEBSERVER '$TEST_VENDOR && echo "vendor is not empty, build seems ok" || exit 1'
        - ssh $WEBSERVER [ -f $WEBSERVER_DEPLOY_DIR$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA/vendor/autoload.php ] && echo "vendor/autoload.php exists, build seems ok" || exit 1
        - echo "DEPLOYED"
    only:
        - tags
        - staging

Post Deploy Link PRODUCTION to Webserver:
    stage: post-deploy
    script:
        - echo "BINDING PRODUCTION"
        - ssh $WEBSERVER unlink $WEBSERVER_DEPLOY_DIRproduction-latest || true
        - ssh $WEBSERVER ln -s $WEBSERVER_DEPLOY_DIR$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA $WEBSERVER_DEPLOY_DIRproduction-latest
        - echo "BOUNDED  $CI_COMMIT_SHA -> production-latest"
        - ssh $WEBSERVER sudo service php5.6-fpm reload
    environment:
        name: production
        url: http://www.example.com
    only:
        - tags

Post Deploy Link STAGING to Webserver:
    stage: post-deploy
    script:
        - echo "BINDING STAGING"
        - ssh $WEBSERVER unlink $WEBSERVER_DEPLOY_DIRstaging-latest || true
        - ssh $WEBSERVER ln -s $WEBSERVER_DEPLOY_DIR$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA $WEBSERVER_DEPLOY_DIRstaging-latest
        - echo "BOUNDED  $CI_COMMIT_SHA -> staging-latest"
        - ssh $WEBSERVER sudo service php5.6-fpm reload
    environment:
        name: staging
        url: http://staging.example.com
    only:
        - staging

在Gitlab documentation 中显示:cache is used to specify a list of files and directories which should be cached between jobs.

据我了解,我已正确设置缓存 - 我已将 untracked 设置为 true,路径包括供应商文件夹,并且密钥设置为 Pipeline ID,在其他阶段也应该相同。

我见过一些包含Artifacts 的设置,但除非你将它与Dependencies 一起使用,否则它不会有任何效果。

我不知道我做错了什么。我需要先下载 composer 依赖项,这样我可以在下一阶段通过rsync 复制它们。你有什么想法/解决方案吗?谢谢

【问题讨论】:

你永远不应该依赖缓存。如果您想保证文件存在,请使用工件。 @JakubKania 但工件主要用于下载某个阶段的结果......因为我不想下载它们,但要在其他阶段使用它们,我虽然使用缓存是正确的做法 是的,但是只有当作业在没有缓存的情况下也可以正常工作时才应该使用缓存。就像,它可以提取自己的作曲家依赖项,但使用以前工作中下载的那些会更快 @JakubKania 隐藏文件呢?例如 .htaccess 似乎没有被提取或保存 @trainoasis 对不起,我不明白你的意思。或许可以尝试提出一个更详细的新问题? 【参考方案1】:

工件应用于永久提供您在管道末端可能需要的任何文件,例如生成的二进制文件、管道下一阶段所需的文件、覆盖率报告甚至可能是磁盘映像。但是应该使用缓存来加快构建过程,例如,如果您编译 C/C++ 二进制文件,第一次构建通常需要很长时间,但后续构建通常更快,因为它不是从头开始的,所以如果您使用缓存来存储编译器生成的临时文件,这样可以加快跨不同管道的编译速度。

因此,为了回答您,您应该使用工件,因为您似乎需要在每个管道上运行 composer,但又想将文件传递给下一个作业。您不需要在 gitlab-ci.yml 中显式定义依赖项,因为如果未定义,每个作业都会从所有先前的作业中提取所有工件。缓存应该可以工作,但它不可靠,并且对于配置更好但不是必需的配置更好。

【讨论】:

以上是关于Gitlab CI 中缓存/工件的正确用法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从 gitlab-ci dir 中获取所有工件并使其成为工件

如何在 .gitlab-ci.yml 中指定通配符工件子目录?

如何创建一个工件,以便它可以在 .gitlab-ci.yml 中下载

未找到 Gitlab ci 工件

Gitlab ci - 工件应用程序 jar 的差异

gitlab-ci 运行器中具有不同到期时间的多条路径