007.Gitlab CICD缓存与附件

发布于:2025-04-15 ⋅ 阅读:(22) ⋅ 点赞:(0)

缓存与产物

缓存与产物概述

缓存是一种 临时存储机制,用于在流水线的不同运行之间保留可复用的中间文件或依赖项(如第三方库、编译中间产物)。
其核心目标是 减少重复性任务的执行时间,通过重用已生成的内容来提升作业执行效率。

缓存是作业下载和保存的一个或多个文件。
使用相同缓存的后续作业不必再次下载文件,因此可以加快作业的执行。
缓存主要有如下特性:

  • 使用 cache 关键字定义每个作业的缓存。否则它被禁用。
  • 后续流水线可以复用缓存。
  • 如果依赖项相同,同一流水线中的后续作业可以使用缓存。
  • 不同的项目不能共享缓存。
  • 默认情况下,受保护和非受保护分支不会共享缓存,除非人为改变此行为。

产物主要有如下特性:

  • 定义每个作业的产物。
  • 同一流水线后期的后续作业可以使用产物。
  • 不同的项目不能共享产物。
  • 默认情况下,产物会在 30 天后过期,除非人为自定义到期时间。
  • 如果启用了保留最新产物,则最新的产物不会过期。
  • 使用依赖来控制哪些作业获取工件

缓存通常存储在Runner本地,可以被同一流水线的不同作业重用,但不同 Runner 之间无法共享。
而产物上传到GitLab服务器,可以在不同作业和阶段之间传递,甚至可以保留一段时间供下载。

总结如下:

维度 缓存(Cache) 产物(Artifacts)
存储目的 加速重复性任务 传递构建结果
数据性质 临时性、可丢弃 持久性、需保留
共享方向 向后传递(供未来作业复用) 向前传递(供后续阶段使用)
依赖管理 隐式依赖(通过 key 匹配) 显式依赖(通过 dependencies 声明)

同分支不同job数据共享

默认数据共享

在没有配置数据共享之前,默认流水线中,不同 job 之间的数据是无法共享的。

  • 创建流水线
    如下创建一个项目背景,创建两个阶段,一个编译 compile ,一个构建 build ,在 compile 阶段对文件进行追加内容,然后在 build 模拟查看文件,观察文件是否实现更改。

首先在 back/demo.txt 文件写入原始内容,如 hello world 。

[root@gitclient myapp]# echo 'hello world' >> back/demo.txt

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile
  - build

compile_back:
  stage: compile
  only:
    - main
  script:
    - cat back/demo.txt
    - echo "do compile back" >> back/demo.txt
    - cat back/demo.txt
  tags:
    - study-runner

build_back:
  stage: build
  only:
    - main
  script:
    - cat back/demo.txt
  tags:
    - study-runner
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Test job share file"

[root@gitclient myapp]# git push origin main

观察流水线作业。
106

查看 compile 的作业:
107

查看 build 的作业:
108

结论:如上所示,默认情况下在 compile 阶段对文件内容的操作,并不会传递到 build 阶段。

不同 Job 数据共享

对于研发日常工作,经常存在后续的不同 job ,需要使用前一个阶段对文件的修改或者所产生的新文件。
当需要在流水线中不同的 job 之间实现数据共享时,需要使用缓存技术,通过关键字 cache 实现。

提示:不同runner之间的数据是无法共享的,因此需要在流水线不同 job 之间指定 runner 。

在编译和构建等不同 job 中都使用 cache 关键字,两个 job 之间通过 key 关键字实现数据共享。
key 关键字通过指定一个预定义的变量,即 CI_COMMIT_REF_SLUG ,在同一个分支中, CI_COMMIT_REF_SLUG 变量是相同的。

[root@gitclient myapp]# cat back/demo.txt

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile
  - build

compile_back:
  stage: compile
  only:
    - main
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - back/
  script:
    - cat back/demo.txt
    - echo "do compile back" >> back/demo.txt
    - cat back/demo.txt
  tags:
    - study-runner

build_back:
  stage: build
  only:
    - main
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - back/
  script:
    - cat back/demo.txt
  tags:
    - study-runner
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Test two job share file"

[root@gitclient myapp]# git push origin main

观察流水线作业。
109
查看 compile 的作业:
110

查看 build 的作业:
111

结论:如上所示,通过 cache 实现在 compile 阶段对文件内容的操作,传递到 build 阶段。即在 cache 中使用相同的 key 的 job 之间是数据共享的。

不同分支相同job数据共享

跨分支同job数据共享

数据共享的本质是 key 值相同,因此若需要在不同分支的相同的 job 之间实现数据共享,只需要保证 key 值在不同的分支相同的 job 中保持一致,在相同的分支不同的 job 之间 key 又保持不同。
即不同分支,相同 job 保持一直,相同分支,不同 job 保持不同。
因此直接把 key 值定义采用 job 名称的变量名即可。

key 值等于 job 名称,就实现了相同分支不同 job 数据不共享,不同分支,相同 job 数据共享。

通常对于 main 分支的编译阶段和 dev 分支的编译阶段的数据共享非常实用。

  • 创建流水线
[root@gitclient myapp]# git checkout -b test

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile
  - build

compile_web:
  stage: compile
  only:
    - test
    - dev
  cache:
    key: $CI_JOB_NAME
    policy: pull-push
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do compile web tow branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner

build_web:
  stage: build
  only:
    - test
    - dev
  cache:
    key: $CI_JOB_NAME
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do build web tow branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Test two branch share file for test"

[root@gitclient myapp]# git push origin test

观察流水线作业。
112
查看 compile 的作业:
113

查看 build 的作业:
114

结论:如上所示,基于 cache 中的 key 实现数据共享,但 key 是使用了作业名变量,因此 compile 作业和 build 作业名不同,因此数据没有实现共享。

  • 切换分支推送
[root@gitclient myapp]# git checkout dev

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile
  - build

compile_web:
  stage: compile
  only:
    - test
    - dev
  cache:
    key: $CI_JOB_NAME
    policy: pull-push
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do compile web tow branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner

build_web:
  stage: build
  only:
    - test
    - dev
  cache:
    key: $CI_JOB_NAME
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do build web tow branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Test two branch share file for dev"

[root@gitclient myapp]# git push origin dev

观察流水线作业。
115
查看 compile 的作业:
116

查看 build 的作业:
117

查看两个分支的提交。
117

结论:如上所示,基于 cache 中的 key 实现数据共享, key 是使用了作业名变量,因此即使不同分支,其跨分支的相同 compile 作业内容都实现了共享,跨内置 相同的 build 也一样实现了数据共享。

不同分支不同job数据共享

跨分支跨job数据共享

数据共享的本质是 key 值相同,因此若需要在不同分支的不相同的 job 之间实现数据共享,本质上就是所有场景下都能共享数据,值只需要保证 key 值在不同的分支不同 job 中保持一致,设置一个固定的 key 即可。

  • 创建流水线
[root@gitclient myapp]# git checkout test

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile
  - build

compile_web:
  stage: compile
  only:
    - test
    - dev
  cache:
    key: all_share_file
    policy: pull-push
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do compile web all branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner

build_web:
  stage: build
  only:
    - test
    - dev
  cache:
    key: all_share_file
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do build web all branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Test all branch share file for test"

[root@gitclient myapp]# git push origin test

观察流水线作业。
119

查看 compile 的作业:
120

查看 build 的作业:
121

结论:如上所示,基于 cache 中的固定 key 实现数据共享,因此 compile 作业和 build 作业名都会共享数据,build 的内容包括了 compile 。

  • 切换分支推送
[root@gitclient myapp]# git checkout dev

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile
  - build

compile_web:
  stage: compile
  only:
    - test
    - dev
  cache:
    key: all_share_file
    policy: pull-push
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do compile web tow branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner

build_web:
  stage: build
  only:
    - test
    - dev
  cache:
    key: all_share_file
    paths:
      - web/
  script:
    - mkdir -p web/
    - echo "do build web tow branch" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Test all branch share file for dev"

[root@gitclient myapp]# git push origin dev

观察流水线作业。
115

查看 compile 的作业:
116

查看 build 的作业:
117

查看两个分支的提交。
117

结论:如上所示,基于 cache 中的固定 key 实现数据共享,因此 dev 分支会继续继承 test 分支的所有数据,因此 compile 作业和 build 作业文件都会叠加更新 。

将文件/夹保存为附件

产物介绍

在 gitlab 中作业可以输出文件和目录的存档,此输出称为作业产物,或简称产物。

已创建的产物可以使用 UI 或 API 下载。

产物的主要核心场景:

  1. 跨作业/阶段传递数据
    将当前作业生成的文件传递给后续作业(如下载编译后的二进制文件、测试报告等)。
    例如:编译作业生成 dist/ 目录,部署作业使用该目录中的文件。
  2. 提供用户手动下载
    用户可以直接在 GitLab Pipeline 界面下载产物文件(如发布包、日志等)。
  3. 自动化报告集成
    将产物标记为特定类型的报告(如单元测试报告、覆盖率报告),GitLab 会解析并展示在UI中。

GitLab 中的可以使用 artifacts 关键字来持久化存储作业生成的产物(如构建结果、测试报告、日志等)。

与 cache 的主要区别:

特性 artifacts cache
用途 传递作业生成的最终结果(如二进制文件、报告) 缓存中间依赖(如 node_modules )以加速构建
存储持久性 长期保留(默认30天,可配置 expire_in ) 临时存储(可能被清理,无严格保留时间)
作用范围 同一 Pipeline 的后续作业 同一 Runner 的多个 Pipeline (跨分支、项目)
是否可下载 用户可直接下载 用于自动化构建流程

创建产物

  • 创建流水线
[root@gitclient myapp]# git checkout main

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile

compile_web:
  stage: compile
  only:
    - main
    - dev
  artifacts:
    paths:
      - web
  script:
    - mkdir -p web/
    - echo "do compile web save file" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Do compile web save file"

[root@gitclient myapp]# git push origin main

观察流水线作业。

125

浏览产物,也可以将产物进行下载。

126

  • 定义产物名字
    可以为产物定义名字。
[root@gitclient myapp]# git checkout main

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile

compile_web:
  stage: compile
  only:
    - main
    - dev
  artifacts:
    name: webtest
    paths:
      - web
  script:
    - mkdir -p web/
    - echo "do compile webtest save file" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner

[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Do compile webtest save file to webtest"

[root@gitclient myapp]# git push origin main

观察流水线作业。

127

浏览产物,也可以将产物进行下载。

128

  • 设置产物过期时间
    支持将产物设置特定的过期时间。
[root@gitclient myapp]# git checkout main

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile

compile_web:
  stage: compile
  only:
    - main
    - dev
  artifacts:
    name: webtest
    expire_in: 30 days
    paths:
      - web
  script:
    - mkdir -p web/
    - echo "do compile webtest file expire time" >> web/mytest.txt
    - cat web/mytest.txt
  tags:
    - study-runner

[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Do compile webtest file expire time"

[root@gitclient myapp]# git push origin main

观察流水线作业。

129

浏览产物,也可以将产物进行下载。

130

跨job共享产物

产物可以在两个不同 job 之间共享,后一个 job 使用前一个 job 的产物。

  • 创建流水线
[root@gitclient myapp]# git checkout main

[root@gitclient myapp]# git rm .gitlab-ci.yml

[root@gitclient myapp]# vim .gitlab-ci.yml
stages:
  - compile
  - build

compile_web:
  stage: compile
  only:
    - main
    - dev
  artifacts:
    paths:
      - web
  script:
    - mkdir -p web/
    - echo "do compile first file" >> web/firstest.txt
    - echo "do compile second file" >> web/secondtest.txt
    - echo "do compile third file" >> web/thirdtest.txt
  tags:
    - study-runner

build_web:
  stage: build
  dependencies:
    - compile_web
  only:
    - main
    - dev
  script:
    - ls -l web/
  • 提交流水线
[root@gitclient myapp]# git add .
[root@gitclient myapp]# git commit -m "Do web share file"

[root@gitclient myapp]# git push origin main

观察流水线作业。

131

查看作业,后续job能查看前一个job的产物。

132