作业产物

作业可以输出文件和目录的存档。此输出称为作业产物。

您可以使用 GitLab UI 或 API 下载作业产物。

创建作业产物

要创建作业产物,请在您的 .gitlab-ci.yml 文件中使用 artifacts 关键字:

pdf:
  script: xelatex mycv.tex
  artifacts:
    paths:
      - mycv.pdf
    expire_in: 1 week

在此示例中,名为 pdf 的作业调用 xelatex 命令从LaTeX 源文件 mycv.tex 构建 PDF 文件。

paths 关键字确定要添加到作业产物的文件。 文件和目录的所有路径都相对于创建作业的仓库。

expire_in 关键字决定保留作业产物的时间。 您还可以使用 UI 防止作业产物过期。 如果未定义 expire_in,则使用实例范围的设置。

如果您为同一个 ref 运行两种类型的流水线(如分支和调度),稍后完成的流水线将创建作业产物。

要禁用工件传递,请使用空的 dependencies 定义作业:

job:
  stage: build
  script: make build
  dependencies: []

您可能只想为标记版本创建产物,以避免使用临时构建产物填充构建服务器存储。例如,使用 rules 只为标签创建产物:

default-job:
  script:
    - mvn test -U
  rules:
    - if: $CI_COMMIT_BRANCH

release-job:
  script:
    - mvn package -U
  artifacts:
    paths:
      - target/*.war
  rules:
    - if: $CI_COMMIT_TAG

您也可以对目录使用通配符。例如,您想获取以 xyz 结尾的目录中的所有文件:

job:
  artifacts:
    paths:
      - path/*xyz/*

使用 CI/CD 变量定义产物名称

您可以使用 CI/CD 变量来动态定义产物文件的名称。

例如,要使用当前作业的名称创建存档:

job:
  artifacts:
    name: "$CI_JOB_NAME"
    paths:
      - binaries/

要使用当前分支或标签的名称创建档案,仅包括二进制目录:

job:
  artifacts:
    name: "$CI_COMMIT_REF_NAME"
    paths:
      - binaries/

如果您的分支名称包含正斜杠(例如feature/my-feature),建议使用 $CI_COMMIT_REF_SLUG 而不是 $CI_COMMIT_REF_NAME 来正确命名产物。

要使用当前作业的名称和当前的分支或标签创建仅包含二进制文件目录的存档:

job:
  artifacts:
    name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    paths:
      - binaries/

要使用当前 stage 和分支名称的名称创建存档:

job:
  artifacts:
    name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
    paths:
      - binaries/

如果您使用 Windows Batch 来运行你的 shell 脚本,你必须用 % 替换 $

job:
  artifacts:
    name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%"
    paths:
      - binaries/

如果您使用 Windows PowerShell 运行你的 shell 脚本,你必须用 $env: 替换 $

job:
  artifacts:
    name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME"
    paths:
      - binaries/

从作业产物中排除文件

使用 artifacts:exclude 防止文件被添加到产物存档中。

例如,将所有文件存储在 binaries/ 中,而不是位于 binaries/ 子目录中的 *.o 文件。

artifacts:
  paths:
    - binaries/
  exclude:
    - binaries/**/*.o

artifacts:paths 不同,exclude 路径不是递归的。 要排除目录的所有内容,请明确匹配它们而不是匹配目录本身。

例如,要将所有文件存储在 binaries/ 中,但不存储在 temp/ 子目录中:

artifacts:
  paths:
    - binaries/
  exclude:
    - binaries/temp/**/*

将未跟踪的文件添加到产物

使用 artifacts:untracked 将所有 Git 未跟踪文件添加为产物(以及在 artifacts:paths)。未跟踪的文件是那些尚未添加到仓库,但存在于仓库检出中的文件。

将所有 Git 未跟踪文件和文件保存在 binaries 中:

artifacts:
  untracked: true
  paths:
    - binaries/

保存所有未跟踪的文件,但排除 *.txt

artifacts:
  untracked: true
  exclude:
    - "*.txt"

下载作业产物

您可以下载作业产物或查看作业存档:

  • 流水线 页面上,流水线右侧:

    Job artifacts in Pipelines page

  • 作业 页面上,作业右侧:

    Job artifacts in Jobs page

  • 在作业的详细信息页面上。 保留 按钮表示设置了一个 expire_in 值:

    Job artifacts browser button

  • 在合并请求中,通过流水线详细信息:

    Job artifacts in merge request

  • 浏览存档时:

    Job artifacts browser

    如果项目中启用了 GitLab Pages,则可以直接在浏览器中预览产物中的HTML文件。如果项目是内部或私有的,则必须启用 GitLab Pages 访问控制才能预览 HTML 文件。

查看失败的作业产物

如果最新的作业未能上传产物,您可以在 UI 中看到该信息。

Latest artifacts button

删除作业产物

caution这是一种会导致数据丢失的破坏性操作。谨慎使用。

您可以删除单个作业,这也会删除作业的产物和日志。您必须是:

  • 作业的所有者。
  • 至少具有项目维护者角色的用户。

要删除作业:

  1. 转到作业的详细信息页面。
  2. 在作业日志的右上角,选择 删除作业日志 ()。
  3. 在确认对话框中,选择 OK

在合并请求 UI 中公开作业产物

使用 artifacts:expose_as 关键字在合并请求 UI 中公开作业工件。

例如,要匹配单个文件:

test:
  script: ["echo 'test' > file.txt"]
  artifacts:
    expose_as: 'artifact 1'
    paths: ['file.txt']

通过此配置,系统添加了一个链接 artifact 1 到指向 file.txt 的相关合并请求。要访问该链接,请选择合并请求概览中管道图下方的 查看已公开产物

匹配整个目录的示例:

test:
  script: ["mkdir test && echo 'test' > test/file.txt"]
  artifacts:
    expose_as: 'artifact 1'
    paths: ['test/']

检索其他项目的作业产物

要从不同的项目中检索作业产物,您可能需要使用私有令牌来身份验证和下载产物。

搜索作业产物的工作原理

在 13.5 及更高版本中,父子流水线 的产物按从父到子的层次顺序进行搜索。例如,如果父流水线和子流水线都有一个同名的作业,则返回父流水线中的作业产物。

通过 URL 访问最新的作业产物

您可以使用 URL 从最新的成功流水线下载作业产物。

要下载整个产物档案:

https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/download?job=<job_name>

要从产物下载单个文件:

https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/raw/<path_to_file>?job=<job_name>

例如,要在 gitlab-org 命名空间的 gitlab 项目的 main 分支中下载名为 coverage 的作业的最新产物:

https://gitlab.com/gitlab-org/gitlab/-/jobs/artifacts/main/download?job=coverage

要从相同的产物下载文件 review/index.html

https://gitlab.com/gitlab-org/gitlab/-/jobs/artifacts/main/raw/review/index.html?job=coverage

要浏览最新的作业产物:

https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/browse?job=<job_name>

例如:

https://gitlab.com/gitlab-org/gitlab/-/jobs/artifacts/main/browse?job=coverage

要下载特定文件,包括 GitLab Pages 中显示的 HTML 文件:

https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/file/<path>?job=<job_name>

例如,当作业 coverage 创建产物 htmlcov/index.html 时:

https://gitlab.com/gitlab-org/gitlab/-/jobs/artifacts/main/file/htmlcov/index.html?job=coverage

何时删除作业产物

有关何时删除作业产物的信息,请参阅 expire_in 文档。

保留最近成功作业的产物

  • 引入于 13.0 版本。
  • 功能标志移除于 13.4 版本。
  • 支持通过 CI/CD 设置可选于 13.8 版本。

默认情况下,对于每个 ref 上的最新提交,始终为成功的流水线保留产物。这意味着最新的产物不会根据 expire_in 规范立即过期。

如果同一 ref 上的新提交的流水线成功完成,则根据 expire_in 配置删除先前流水线的产物。新流水线的产物会自动保留。如果针对 ref 上的最新提交运行多个流水线,则保留所有产物。

保留最新的产物可以在有大量作业或大型产物的项目中使用大量存储空间。如果项目中不需要最新的产物,您可以禁用此行为以节省空间:

  1. 在顶部栏上,选择 主菜单 > 项目 并找到您的项目。
  2. 在左侧边栏上,选择 设置 > CI/CD
  3. 展开 产物
  4. 清除 保留最近成功作业的产物 复选框。

您可以在实例的 CI/CD 设置中,为私有化部署实例上的所有项目禁用此行为。

作业产物故障排查

错误消息 No files to upload

此消息之前通常会出现其他错误或警告,这些错误或警告指定了文件名以及未生成文件名的原因。检查作业日志以获取这些消息。

如果您没有发现有用的消息,请在激活 CI/CD 调试日志记录后重试失败的作业。 此日志记录应提供帮助您进一步调查的信息。

错误消息 Missing /usr/bin/gitlab-runner-helper. Uploading artifacts is disabled.

存在一个已知问题,即设置名为 DEBUG 的 CI/CD 变量会导致产物上传失败。

要解决此问题,请使用不同的变量名称或将其设置在 script 行内:

# This job might fail due to issue gitlab-org/gitlab-runner#3068
failing_test_job:
  variables:
    DEBUG: true
  script: bin/mycommand
  artifacts:
    paths:
      - bin/results

# This job does not define a CI/CD variable named `DEBUG` and is not affected by the issue
successful_test_job:
  script: DEBUG=true bin/mycommand
  artifacts:
    paths:
      - bin/results

错误消息 FATAL: invalid argument,出现在通过 Windows runner 上传 dotenv 产物时

PowerShell echo 命令使用 UCS-2 LE BOM(字节顺序标记)编码写入文件,但仅支持 UTF-8。如果您尝试使用 echo 创建 dotenv 产物,则会导致 FATAL: invalid argument 错误。

改用 PowerShell Add-Content,它使用 UTF-8:

test-job:
  stage: test
  tags:
    - windows
  script:
    - echo "test job"
    - Add-Content -Path build.env -Value "MY_ENV_VAR=true"
  artifacts:
    reports:
      dotenv: build.env

作业产物不过期

如果某些作业产物未按预期过期,请检查保留最近成功作业的产物设置是否已启用。

启用此设置后,来自每个 ref 的最新成功流水线的作业产物不会过期并且不会被删除。

错误消息 This job could not start because it could not retrieve the needed artifacts.

使用 needs:artifacts 关键字配置的作业在以下情况下无法启动并返回此错误消息:

  • 找不到作业的依赖项。
  • 由于权限不足,作业无法访问相关资源。

要遵循的故障排除步骤由作业配置中使用的语法决定。

使用 needs:project 配置的作业

使用 needs:project 的作业可能会发生 could not retrieve the needed artifacts. 错误,其配置类似于:

rspec:
  needs:
    - project: org/another-project
      job: dependency-job
      ref: master
      artifacts: true

要对此作业进行故障排除,请验证:

  • 项目 org/another-project 属于具有专业版订阅计划的群组。
  • 运行作业的用户有权访问 org/another-project 中的资源。
  • projectjobref 组合存在并产生所需的依赖关系。
  • 使用中的任何变量都会评估为正确的值。

使用 needs:pipeline:job 配置的作业

使用 needs:pipeline:job 的作业可能会发生 could not retrieve the needed artifacts. 错误,其配置类似于:

rspec:
  needs:
    - pipeline: $UPSTREAM_PIPELINE_ID
      job: dependency-job
      artifacts: true

要对此作业进行故障排除,请验证:

  • $UPSTREAM_PIPELINE_ID CI/CD 变量在当前流水线的父子流水线层次结构中可用。
  • pipelinejob 组合存在并解析为现有流水线。
  • dependency-job 已运行并成功完成。

作业产物未过期

如果某些作业产物未按预期过期,请检查保留最近成功作业的产物设置是否已启用。

启用此设置后,来自每个 ref 的最新成功流水线的作业产物不会过期并且不会被删除。

错误消息 This job could not start because it could not retrieve the needed artifacts.

使用 needs:artifacts 关键字配置的作业在以下情况下无法启动并返回此错误消息:

  • 找不到作业的依赖项。
  • 由于权限不足,作业无法访问相关资源。

要遵循的故障排除步骤由作业配置中使用的语法决定。

使用 needs:project 配置的作业

使用 needs:project 的作业可能会发生 could not retrieve the needed artifacts. 错误,其配置类似于:

rspec:
  needs:
    - project: org/another-project
      job: dependency-job
      ref: master
      artifacts: true

要对此作业进行故障排除,请验证:

  • 项目 org/another-project 属于具有高级订阅计划的群组。
  • 运行作业的用户有权访问 org/another-project 中的资源。
  • projectjobref 组合存在并产生所需的依赖关系。
  • 使用中的任何变量都会评估为正确的值。

使用 needs:pipeline:job 配置的作业

使用 needs:pipeline:job 的作业可能会发生 could not retrieve the needed artifacts. 错误,其配置类似于:

rspec:
  needs:
    - pipeline: $UPSTREAM_PIPELINE_ID
      job: dependency-job
      artifacts: true

要对此作业进行故障排除,请验证:

  • $UPSTREAM_PIPELINE_ID CI/CD 变量在当前流水线的父子流水线层次结构中可用。
  • pipelinejob 组合存在并解析为已有流水线。
  • dependency-job 已运行并成功完成。