Help us learn about your current experience with the documentation. Take the survey.

CI/CD 作业

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

CI/CD 作业是 GitLab CI/CD pipeline 的基本元素。 作业在 .gitlab-ci.yml 文件中进行配置,包含要执行的命令列表, 用于完成构建、测试或部署代码等任务。

作业:

  • runner 上执行,例如在 Docker 容器中。
  • 独立于其他作业运行。
  • 拥有 作业日志,包含作业的完整执行日志。

作业使用 YAML 关键字 定义,这些关键字定义了作业执行的各个方面, 包括:

  • 控制 作业如何何时 运行。
  • 将作业分组到称为 阶段 的集合中。 阶段按顺序运行,而同一阶段中的所有作业可以并行运行。
  • 定义 CI/CD 变量 以实现灵活配置。
  • 定义 缓存 以加速作业执行。
  • 将文件保存为 产物,其他作业可以使用这些产物。

向流水线添加作业

要向流水线添加作业,请将其添加到您的 .gitlab-ci.yml 文件中。作业必须:

例如:

my-ruby-job:
  script:
    - bundle install
    - bundle exec my_ruby_command

my-shell-script-job:
  script:
    - my_shell_script.sh

作业名称

您不能使用以下关键字作为作业名称:

  • image
  • services
  • stages
  • before_script
  • after_script
  • variables
  • cache
  • include
  • deploy 阶段配置的 pages:deploy

此外,这些名称在加引号时是有效的,但不推荐使用,因为它们可能使流水线配置不清晰:

  • "true":
  • "false":
  • "nil":

作业名称必须为 255 个字符或更少。

为您的作业使用唯一名称。如果多个作业在文件中具有相同的名称, 只有一个会被添加到流水线中,并且很难预测选择的是哪一个。 如果在包含的一个或多个文件中使用相同的作业名称, 参数会被合并

隐藏作业

要临时禁用作业而不从配置文件中删除它, 请在作业名称开头添加一个句点(.)。隐藏的作业不需要包含 scripttrigger 关键字,但必须包含有效的 YAML 配置。

例如:

.hidden_job:
  script:
    - run test

隐藏的作业不会被 GitLab CI/CD 处理,但它们可以用作可重用配置的模板, 通过以下方式:

设置作业关键字的默认值

您可以使用 default 关键字设置默认作业关键字和值, 这些值默认被流水线中的所有作业使用。

例如:

default:
  image: 'ruby:2.4'
  before_script:
    - echo Hello World

rspec-job:
  script: bundle exec rspec

当流水线运行时,作业使用默认关键字:

rspec-job:
  image: 'ruby:2.4'
  before_script:
    - echo Hello World
  script: bundle exec rspec

控制默认关键字和变量的继承

您可以控制以下内容的继承:

例如:

default:
  image: 'ruby:2.4'
  before_script:
    - echo Hello World

variables:
  DOMAIN: example.com
  WEBHOOK_URL: https://my-webhook.example.com

rubocop:
  inherit:
    default: false
    variables: false
  script: bundle exec rubocop

rspec:
  inherit:
    default: [image]
    variables: [WEBHOOK_URL]
  script: bundle exec rspec

capybara:
  inherit:
    variables: false
  script: bundle exec capybara

karma:
  inherit:
    default: true
    variables: [DOMAIN]
  script: karma

在此示例中:

  • rubocop
    • 继承:无。
  • rspec
    • 继承:默认的 imageWEBHOOK_URL 变量。
    • 不继承:默认的 before_scriptDOMAIN 变量。
  • capybara
    • 继承:默认的 before_scriptimage
    • 不继承:DOMAINWEBHOOK_URL 变量。
  • karma
    • 继承:默认的 imagebefore_script,以及 DOMAIN 变量。
    • 不继承:WEBHOOK_URL 变量。

查看流水线中的作业

当您访问流水线时,可以看到该流水线的相关作业。

流水线中作业的顺序取决于流水线图的类型。

  • 对于 完整流水线图,作业按名称字母顺序排序。
  • 对于 流水线迷你图,作业按状态严重程度排序, 失败的作业首先出现,然后按名称字母顺序排序。

选择单个作业会显示其 作业日志,并允许您:

  • 取消作业。
  • 如果作业失败,重试作业。
  • 如果作业通过,再次运行作业。
  • 清除作业日志。

查看项目中的所有作业

  • Offering: GitLab.com, GitLab Self-Managed

此功能的可用性由功能标志控制。有关更多信息,请参阅历史记录。

按名称过滤作业是一项 实验功能。有关此功能开发的更多信息,请参阅 issue 387547

要查看项目中运行的所有作业的完整列表:

  1. 在左侧边栏,选择 Search or go to 并找到您的项目。
  2. 选择 Build > Jobs

您可以按 作业名称作业状态作业来源 过滤列表。

可用的作业状态

CI/CD 作业可以具有以下状态:

  • canceled:作业被手动取消或自动中止。
  • canceling:作业正在被取消,但 after_script 正在运行。
  • created:作业已创建但尚未处理。
  • failed:作业执行失败。
  • manual:作业需要手动操作才能启动。
  • pending:作业在队列中等待 runner。
  • preparing:runner 正在准备执行环境。
  • running:作业在 runner 上执行。
  • scheduled:作业已调度但尚未开始执行。
  • skipped:作业因条件或依赖关系被跳过。
  • success:作业成功完成。
  • waiting_for_resource:作业正在等待资源可用。

查看作业的来源

GitLab CI/CD 作业现在包含一个来源属性,指示最初触发 CI/CD 作业的操作。 使用此属性跟踪作业如何启动,或根据特定来源过滤作业运行。

可用的作业来源

来源属性可以具有以下值:

  • api:通过 Jobs API 的 REST 调用启动的作业。
  • chat:通过使用 GitLab ChatOps 的聊天命令启动的作业。
  • container_registry_push:通过容器 registry 推送启动的作业。
  • duo_workflow:通过 GitLab Duo Agent Platform 启动的作业。
  • external:通过与 GitLab 集成的外部仓库中的事件启动的作业。这不包括拉取请求事件。
  • external_pull_request_event:通过外部仓库中的拉取请求事件启动的作业。
  • merge_request_event:通过合并请求事件启动的作业。
  • ondemand_dast_scan:通过按需 DAST 扫描启动的作业。
  • ondemand_dast_validation:通过按需 DAST 验证启动的作业。
  • parent_pipeline:通过父流水线启动的作业。
  • pipeline:通过用户手动运行流水线启动的作业。
  • pipeline_execution_policy:通过触发的流水线执行策略启动的作业。
  • pipeline_execution_policy_schedule:通过调度的流水线执行策略启动的作业。
  • push:通过代码推送启动的作业。
  • scan_execution_policy:通过扫描执行策略启动的作业。
  • schedule:通过调度的流水线启动的作业。
  • security_orchestration_policy:通过调度的扫描执行策略启动的作业。
  • trigger:通过另一个作业或流水线启动的作业。
  • unknown:通过未知来源启动的作业。
  • web:通过用户从 GitLab UI 启动的作业。
  • webide:通过用户从 Web IDE 启动的作业。

在流水线视图中将相似作业分组

如果您有许多相似的作业,您的 流水线图 会变得很长且难以阅读。

您可以自动将相似的作业分组。如果作业名称以特定格式命名, 它们会在常规流水线图中(不是迷你图)折叠为一个组。

如果您看到作业名称旁边有一个数字而不是重试或取消按钮,您就可以识别出流水线是否已分组作业。 该数字表示分组的作业数量。悬停它们会显示所有作业是否都已通过或是否有任何失败。点击展开它们。

显示多个阶段和作业的流水线图,包括三组分组作业。

要创建作业组,在 .gitlab-ci.yml 文件中, 使用数字和以下符号之一分隔每个作业名称:

  • 斜杠(/),例如 slash-test 1/3slash-test 2/3slash-test 3/3
  • 冒号(:),例如 colon-test 1:3colon-test 2:3colon-test 3:3
  • 空格,例如 space-test 0 3space-test 1 3space-test 2 3

您可以互换使用这些符号。

在以下示例中,这三个作业在一个名为 build ruby 的组中:

build ruby 1/3:
  stage: build
  script:
    - echo "ruby1"

build ruby 2/3:
  stage: build
  script:
    - echo "ruby2"

build ruby 3/3:
  stage: build
  script:
    - echo "ruby3"

流水线图显示一个名为 build ruby 的组,包含三个作业。

作业通过从左到右比较数字进行排序。您 通常希望第一个数字是索引,第二个数字是总数。

此正则表达式 评估作业名称:([\b\s:]+((\[.*\])|(\d+[\s:\/\]+\d+))){1,3}\s*\z。 仅从作业名称的末尾移除一个或多个 : [...]X YX/YX\Y 序列。 在作业名称开头或中间找到的匹配子字符串不会被移除。

重试作业

作业完成后,您可以重试它,无论其最终状态如何(失败、成功或已取消)。

当您重试作业时:

  • 会创建一个具有新作业 ID 的新作业实例。
  • 作业使用与原始作业相同的参数和变量运行。
  • 如果作业产生产物,会创建新的产物并存储。
  • 新作业与发起重试的用户关联,而不是创建原始流水线的用户。
  • 任何先前被跳过的后续作业都会重新分配给发起重试的用户。

当您重试一个触发下游流水线的 触发作业 时:

  • 触发作业会生成一个新的下游流水线。
  • 下游流水线也与发起重试的用户关联。
  • 下游流水线使用重试时存在的配置运行, 这可能与原始运行不同。

重试作业

先决条件:

  • 您必须至少拥有项目的 Developer 角色。
  • 作业不能被 归档

要从合并请求重试作业:

  1. 在左侧边栏,选择 Search or go to 并找到您的项目。
  2. 从您的合并请求中,执行以下操作之一:
    • 在流水线小部件中,在您要重试的作业旁边,选择 Run again retry )。
    • 选择 Pipelines 选项卡,在您要重试的作业旁边,选择 Run again retry )。

要从作业日志重试作业:

  1. 转到作业的日志页面。
  2. 在右上角,选择 Run again retry )。

要从流水线重试作业:

  1. 在左侧边栏,选择 Search or go to 并找到您的项目。
  2. 选择 Build > Pipelines
  3. 找到包含您要重试的作业的流水线。
  4. 从流水线图中,在您要重试的作业旁边,选择 Run again retry )。

重试流水线中所有失败或已取消的作业

如果流水线有多个失败或已取消的作业,您可以一次性重试所有作业:

  1. 在左侧边栏,选择 Search or go to 并找到您的项目。
  2. 执行以下操作之一:
    • 选择 Build > Pipelines
    • 转到合并请求并选择 Pipelines 选项卡。
  3. 对于有失败或已取消作业的流水线,选择 Retry all failed or canceled jobs retry )。

取消作业

您可以取消尚未完成的 CI/CD 作业。

当您取消作业时,接下来发生的情况取决于其状态和 GitLab Runner 版本:

  • 对于尚未开始执行的作业,作业会立即被取消。
  • 对于正在运行的作业:
    • 对于 GitLab Runner 16.10 及更高版本与 GitLab 17.0 及更高版本,作业被标记为 canceling,同时 runner 运行作业的 after_script。 当 after_script 完成后,作业被标记为 canceled
    • 对于 GitLab Runner 16.9 及更早版本与 GitLab 16.11 及更早版本,作业会立即被 canceled,而不运行 after_script
%%{init: { "fontFamily": "GitLab Sans" }}%%
stateDiagram-v2
    accTitle: CI/CD 作业状态转换
    accDescr: 显示 CI/CD 作业的可能状态转换,包括取消路径。

    direction TB
    state if_versions <>
    [*] --> pending: 作业已创建
    pending --> canceled: 取消请求
    canceled --> [*]
    pending --> running: Runner 接收作业
    running --> success: 作业成功
    success --> [*]
    running --> failed: 作业失败
    failed --> [*]
    running --> if_versions: 取消请求
    if_versions --> canceling: GitLab 17.0 及更高版本与 GitLab Runner 16.10 及更高版本
    if_versions --> canceled: GitLab 16.11 及更早版本与 GitLab Runner 16.9 及更早版本
    canceling --> canceled: after_script 完成

如果您需要立即取消作业而不等待 after_script,请使用 强制取消

取消作业

先决条件:

要从合并请求取消作业:

  1. 在左侧边栏,选择 Search or go to 并找到您的项目。
  2. 从您的合并请求中,执行以下操作之一:
    • 在流水线小部件中,在您要取消的作业旁边,选择 Cancel cancel )。
    • 选择 Pipelines 选项卡,在您要取消的作业旁边,选择 Cancel cancel )。

要从作业日志取消作业:

  1. 转到作业的日志页面。
  2. 在右上角,选择 Cancel cancel )。

要从流水线取消作业:

  1. 在左侧边栏,选择 Search or go to 并找到您的项目。
  2. 选择 Build > Pipelines
  3. 找到包含您要取消的作业的流水线。
  4. 从流水线图中,在您要取消的作业旁边,选择 Cancel cancel )。

取消流水线中所有正在运行的作业

您可以一次性取消正在运行的流水线中的所有作业。

  1. 在左侧边栏,选择 Search or go to 并找到您的项目。
  2. 执行以下操作之一:
    • 选择 Build > Pipelines
    • 转到合并请求并选择 Pipelines 选项卡。
  3. 对于您要取消的流水线,选择 Cancel the running pipeline cancel )。

强制取消作业

如果您不想等待 after_script 完成,或者作业无响应,您可以强制取消它。 强制取消立即将作业从 canceling 状态移动到 canceled

当您强制取消作业时,作业令牌 会被立即撤销。 如果 runner 仍在执行作业,它会失去对 GitLab 的访问权限。 runner 会中止作业而不等待 after_script 完成。

先决条件:

  • 您必须至少拥有项目的 Maintainer 角色。
  • 作业必须处于 canceling 状态,这需要:
    • GitLab 17.0 及更高版本。
    • GitLab Runner 16.10 及更高版本。

要强制取消作业:

  1. 转到作业的日志页面。
  2. 在右上角,选择 Force cancel

排查失败的作业

当流水线失败或允许失败时,有多个地方可以找到失败的原因:

  • 流水线图 中,在流水线详细信息视图中。
  • 在流水线小部件中,在合并请求和提交页面上。
  • 在作业视图中,在作业的全局和详细视图中。

在每个地方,如果您将鼠标悬停在失败的作业上,您可以看到它失败的原因。

显示失败作业和失败原因的流水线图。

您也可以在作业详细信息页面上看到失败的原因。

使用根因分析

您可以在 GitLab Duo Chat 中使用 GitLab Duo 根因分析来 排查失败的 CI/CD 作业

部署作业

部署作业是使用 environments 的 CI/CD 作业。 部署作业是任何使用 environment 关键字和 start environment action 的作业。 部署作业不需要在 deploy 阶段。以下 deploy me 作业是部署作业的示例。action: start 是默认行为, 此处为清晰起见进行了定义,但您可以省略它:

deploy me:
  script:
    - deploy-to-cats.sh
  environment:
    name: production
    url: https://cats.example.com
    action: start

部署作业的行为可以通过 部署安全 设置来控制, 例如 防止过时的部署作业确保一次只运行一个部署作业