GitLab CI 制品(Artifacts)完全指南:从作用到配置实践
- 一、Artifacts 的核心作用
- 1.1 🟢 什么是 Artifacts?
- 1.2 🔵 Artifacts 与 Cache 的本质区别
- 1.3 🟡 Artifacts 的三大应用场景
- 二、Artifacts 基础配置
- 2.1 🟠 基本语法结构
- 2.2 🔴 核心配置字段详解
- 2.3 🟣 高级配置:条件上传与排除
- 三、常见场景配置示例
- 3.1 🟢 Java/Maven 项目
- 3.2 🔵 JavaScript/Node.js 项目
- 3.3 🟡 Python 项目
- 3.4 🟠 二进制/通用项目
- 四、在作业间传递 Artifacts
- 4.1 🔴 使用 `dependencies` 下载特定作业的制品
- 4.2 🟣 使用 `needs` 优化执行顺序
- 五、测试报告与可视化
- 5.1 🟢 JUnit 测试报告
- 5.2 🔵 代码覆盖率报告
- 5.3 🟡 代码质量报告(Code Quality)
- 六、最佳实践
- 6.1 🟠 控制制品大小
- 6.2 🟣 制品命名规范
- 6.3 🔴 敏感信息处理
- 6.4 🟢 制品过期策略
- 七、总结
🌺The Begin🌺点点关注,收藏不迷路🌺 ⬇ ⬇ 底部 ⬇ ⬇ |
📦 在 CI/CD 流水线中,作业之间的数据传递和构建结果的保存是常见需求。GitLab CI 的
artifacts机制正是为此而生——它允许作业在完成后将文件或目录持久化保存,供后续作业使用或供开发者下载查看。本文将全面解析 artifacts 的核心作用、配置方法及最佳实践。
一、Artifacts 的核心作用
1.1 🟢 什么是 Artifacts?
Artifacts(制品)是 GitLab CI 中用于在作业之间传递文件或目录的机制。当一个作业执行完成后,可以通过artifacts关键字将指定的文件或目录上传到 GitLab 服务器,供同一流水线的后续作业下载使用,或通过 GitLab Web 界面直接下载查看。
💡形象理解:可以把 Artifacts 想象成流水线上的"接力棒"——前一阶段(Job)的工作成果(编译好的二进制文件、测试报告等)通过它传递给后一阶段,确保整个流水线可以无缝衔接。
1.2 🔵 Artifacts 与 Cache 的本质区别
理解了 artifacts 和 cache 的区别,才能正确使用两者:
| 对比维度 | 🟡 制品(Artifacts) | 🔴 缓存(Cache) |
|---|---|---|
| 核心用途 | 在阶段间传递构建结果 | 加速依赖下载 |
| 存储位置 | GitLab 服务器 | Runner 本地或 S3 缓存后端 |
| 跨流水线 | ❌ 不跨流水线(默认仅本流水线可见) | ✅ 跨流水线共享 |
| 生命周期 | 默认 30 天(可配置) | 长期存在,按 key 刷新 |
| 缺失影响 | 后续作业无法运行 | 不影响功能,仅速度下降 |
| 典型内容 | 编译产物、测试报告、安装包 | node_modules/、vendor/、pip cache |
💡核心原则:Artifacts 是"必须存在"的结果传递,Cache 是"可有可无"的速度优化。不要用 artifacts 传递依赖缓存,也不要用 cache 传递关键构建结果。
1.3 🟡 Artifacts 的三大应用场景
典型应用示例:
- 编译作业 → 打包作业:前端构建产出
dist/,后续部署作业使用 - 测试作业 → 报告展示:单元测试生成
junit.xml,GitLab 自动渲染为测试报告 - 构建作业 → 手动下载:开发者从 GitLab 下载构建好的 APK 或 JAR 包
二、Artifacts 基础配置
2.1 🟠 基本语法结构
job:artifacts:paths:# 要上传的文件或目录(必须)-target/*.jarname:"my-artifact"# 下载时的压缩包名称expire_in:1 week# 过期时间reports:# 特殊报告类型junit:junit.xml2.2 🔴 核心配置字段详解
| 字段 | 类型 | 说明 |
|---|---|---|
paths | Array | 要上传的文件或目录路径(支持通配符),必须指定 |
name | String | 下载时的压缩包名称(默认artifacts.zip) |
expire_in | String | 过期时间(默认 30 天),如"1 week"或"30 days" |
reports | Map | 特殊报告类型(JUnit、覆盖率、代码质量等) |
when | String | 上传时机(on_success/on_failure/always) |
exclude | Array | 排除特定文件(从 paths 中剔除) |
public | Boolean | 是否公开可见(公开项目可用,私有项目无效) |
带所有字段的完整示例:
build:script:-mvn clean package-mvn testartifacts:paths:-target/*.jar-target/surefire-reports/name:"$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"exclude:-"target/**/*.log"# 排除所有日志文件expire_in:"30 days"reports:junit:"target/surefire-reports/TEST-*.xml"when:on_successpublic:true2.3 🟣 高级配置:条件上传与排除
条件上传(when):
test:script:-npm run testartifacts:when:always# 无论成功或失败都上传paths:-test-results/deploy:script:-npm run deployartifacts:when:on_failure# 仅当失败时上传,便于排障paths:-logs/排除特定文件(exclude):
build:artifacts:paths:-dist/-coverage/exclude:-"dist/**/*.map"# 排除所有 map 文件-"coverage/**/*.html"# 排除 HTML 报告三、常见场景配置示例
3.1 🟢 Java/Maven 项目
build:stage:buildscript:-mvn clean packageartifacts:paths:-target/*.jar-target/surefire-reports/reports:junit:-target/surefire-reports/TEST-*.xmlexpire_in:1 week3.2 🔵 JavaScript/Node.js 项目
build:stage:buildscript:-npm install-npm run build-npm test----coverage--watchAll=falseartifacts:paths:-dist/# 构建产物-coverage/# 覆盖率报告reports:junit:junit.xmlcoverage_report:coverage_format:coberturapath:coverage/cobertura-coverage.xmlexpire_in:1 week3.3 🟡 Python 项目
build:stage:buildscript:-pip install-r requirements.txt-python setup.py sdist bdist_wheel-pytest--junitxml=report.xmlartifacts:paths:-dist/# 打包后的 wheel 文件-.pytest_cache/reports:junit:report.xmlexpire_in:1 week3.4 🟠 二进制/通用项目
build:stage:buildscript:-go build-o myapp-./run_tests.shartifacts:paths:-myapp# 可执行文件-test-reports/-configs/# 配置文件目录name:"$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"expire_in:"30 days"四、在作业间传递 Artifacts
4.1 🔴 使用dependencies下载特定作业的制品
默认情况下,流水线中各阶段的作业会自动接收所有前置阶段的 artifacts。使用dependencies可以精确控制下载哪些作业的 artifacts:
stages:-build-test-deploybuild:stage:buildscript:-mkdir binary-echo "构建产物">binary/appartifacts:paths:-binary/test:stage:testscript:-echo "测试"artifacts:paths:-test-reports/dependencies:[]# 不下载任何 artifactsdeploy:stage:deployscript:-ls-la binary/-echo "部署"dependencies:-build# 仅下载 build 作业的 artifacts4.2 🟣 使用needs优化执行顺序
结合needs关键字实现更精细的依赖关系,允许作业无需等待所有前置阶段完成即可开始:
build_app_a:stage:buildscript:echo "构建 A"artifacts:paths:-dist_a/build_app_b:stage:buildscript:echo "构建 B"artifacts:paths:-dist_b/deploy_a:stage:deployneeds:["build_app_a"]# 只依赖 build_app_a,不需要等待 Bscript:echo "部署 A"dependencies:-build_app_adeploy_b:stage:deployneeds:["build_app_b"]script:echo "部署 B"dependencies:-build_app_b五、测试报告与可视化
5.1 🟢 JUnit 测试报告
GitLab 自动识别reports: junit路径下的 XML 文件,在 MR/流水线页面渲染为测试表格:
test:script:-npm test----watchAll=falseartifacts:reports:junit:-junit.xml-test-results/**/*.xml5.2 🔵 代码覆盖率报告
test:script:-npm test----coveragecoverage:'/All files[^|]*\|[^|]*\s+([\d\.]+)/'# 提取覆盖率数值artifacts:reports:coverage_report:coverage_format:coberturapath:coverage/cobertura-coverage.xml5.3 🟡 代码质量报告(Code Quality)
code_quality:stage:testscript:-docker run--env SOURCE_CODE="$PWD"...codeclimateartifacts:reports:codequality:gl-code-quality-report.json六、最佳实践
6.1 🟠 控制制品大小
- 只上传必要的文件,避免上传整个
node_modules/或target/(除非必要) - 使用
exclude排除不需要的日志、临时文件 - 设置合理的
expire_in时间(如开发构建 1 天,发布构建 30 天)
6.2 🟣 制品命名规范
使用 CI 变量使制品名称包含上下文信息:
artifacts:name:"$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"paths:-build/6.3 🔴 敏感信息处理
- 不要将包含密码或密钥的文件作为 artifacts 上传
- 使用
CI_JOB_TOKEN进行制品下载认证 - 私有项目默认可见性仅为项目成员
6.4 🟢 制品过期策略
| 场景 | 建议过期时间 |
|---|---|
| 日常开发构建 | 1 day或3 days |
| 功能分支构建 | 1 week |
| Release 构建 | 30 days或never |
| 测试报告 | 1 week |
七、总结
| 核心要点 | 说明 |
|---|---|
| 🟢核心作用 | 在作业间传递构建产物,供后续作业使用或手动下载 |
| 🔵与 Cache 的区别 | Artifacts 用于"必须传递的结果",Cache 用于"可有可无的加速" |
| 🟡关键字段 | paths(必填)、name、expire_in、reports、when |
| 🟠传递方式 | 默认所有前置阶段可用,通过dependencies精确控制 |
| 🔴报告集成 | JUnit、覆盖率、代码质量报告自动渲染到 MR 页面 |
| 🟣最佳实践 | 控制制品大小、设置过期时间、避免上传敏感信息 |
🔑核心启示:GitLab CI 的 artifacts 机制是连接流水线各环节的桥梁。它将阶段化的工作成果有序传递,让构建、测试、部署各司其职又环环相扣。正确的使用方式是:编译阶段产出二进制文件 → 测试阶段依赖这些文件运行 → 部署阶段使用测试通过的版本进行发布。这种清晰的依赖关系,正是现代化 CI/CD 流水线的核心设计理念。
🌺The End🌺点点关注,收藏不迷路🌺 ⬆ ⬆ 顶部 ⬆ ⬆ |