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

配置Runner

  • 层级(Tier): 免费版、高级版、旗舰版
  • 提供方式(Offering): GitLab.com、GitLab 自托管、GitLab 专用

本文档描述如何在 GitLab UI 中配置 Runner。

如果你需要在安装 GitLab Runner 的机器上配置 Runner,请参阅 GitLab Runner 文档

设置最大作业超时

你可以为每个 Runner 指定一个最大作业超时,以防止使用该 Runner 的项目中较长的作业超时。如果最大作业超时短于项目中定义的作业超时,则使用最大作业超时。

若要设置 Runner 的最大超时,请在 REST API 端点 PUT /runners/:id 中设置 maximum_timeout 参数。

对于实例 Runner

先决条件:

  • 你必须是管理员。

你可以在 GitLab 自托管中覆盖实例 Runner 的作业超时。

在 GitLab.com 上,你不能覆盖 GitLab 托管的实例 Runner 的作业超时,必须改用 项目定义的超时

若要设置最大作业超时:

  1. 在左侧边栏底部,选择 管理员
  2. 选择 CI/CD > Runners
  3. 在你要编辑的 Runner 右侧,选择 Edit ( pencil )。
  4. Maximum job timeout 字段中,输入以秒为单位的值。最小值为 600 秒(10 分钟)。
  5. 选择 Save changes

对于组 Runner

先决条件:

  • 你必须有该组的 Owner 角色。

若要设置最大作业超时:

  1. 在左侧边栏,选择 Search or go to 并找到你的组。
  2. 选择 Build > Runners
  3. 在你要编辑的 Runner 右侧,选择 Edit ( pencil )。
  4. Maximum job timeout 字段中,输入以秒为单位的值。最小值为 600 秒(10 分钟)。
  5. 选择 Save changes

对于项目 Runner

先决条件:

  • 你必须有该项目的 Owner 角色。

若要设置最大作业超时:

  1. 在左侧边栏,选择 Search or go to 并找到你的项目。
  2. 选择 Settings > CI/CD
  3. 展开 Runners
  4. 在你要编辑的 Runner 右侧,选择 Edit ( pencil )。
  5. Maximum job timeout 字段中,输入以秒为单位的值。最小值为 600 秒(10 分钟)。如果未定义,则改用 项目的作业超时
  6. 选择 Save changes

最大作业超时的工作原理

示例 1 - Runner 超时大于项目超时

  1. 你为一个 Runner 设置了 maximum_timeout 参数为 24 小时。
  2. 你将项目的 Maximum job timeout 设为 2 小时
  3. 你启动一个作业。
  4. 如果运行时间过长,作业将在 2 小时 后超时。

示例 2 - Runner 超时未配置

  1. 你从一个 Runner 中移除了 maximum_timeout 参数配置。
  2. 你将项目的 Maximum job timeout 设为 2 小时
  3. 你启动一个作业。
  4. 如果运行时间过长,作业将在 2 小时 后超时。

示例 3 - Runner 超时小于项目超时

  1. 你为一个 Runner 设置了 maximum_timeout 参数为 30 分钟
  2. 你将项目的 Maximum job timeout 设为 2 小时。
  3. 你启动一个作业。
  4. 如果运行时间过长,作业将在 30 分钟 后超时。

设置 scriptafter_script 超时

要控制 scriptafter_script 在终止前运行的时长,请在 .gitlab-ci.yml 文件中指定一个超时值。

例如,你可以指定一个超时来提前终止长时间运行的 script。这确保了在 作业超时 超出之前,工件和缓存仍能被上传。scriptafter_script 的超时值必须小于作业超时。

  • 要为 script 设置超时,使用作业变量 RUNNER_SCRIPT_TIMEOUT
  • 要为 after_script 设置超时并覆盖默认的 5 分钟,使用作业变量 RUNNER_AFTER_SCRIPT_TIMEOUT

这两个变量都接受 Go 的持续时间格式(例如,40s1h20m2h4h30m30s)。

例如:

job-with-script-timeouts:
  variables:
    RUNNER_SCRIPT_TIMEOUT: 15m
    RUNNER_AFTER_SCRIPT_TIMEOUT: 10m
  script:
    - "我允许运行 min(15m, 剩余作业超时)。"
  after_script:
    - "我允许运行 min(10m, 剩余作业超时)。"

job-artifact-upload-on-timeout:
  timeout: 1h                           # 将作业超时设置为 1 小时
  variables:
     RUNNER_SCRIPT_TIMEOUT: 50m         # 仅允许 script 运行 50 分钟
  script:
    - long-running-process > output.txt # 将在 50 分钟后被终止

  artifacts: # 工件将有大约 10 分钟的上传时间
    paths:
      - output.txt
    when: on_failure # 由于 script 超时后终止被视为失败,因此使用 on_failure

确保 after_script 执行

为确保 after_script 成功运行,RUNNER_SCRIPT_TIMEOUTRUNNER_AFTER_SCRIPT_TIMEOUT 的总和不得超过作业配置的超时。

以下示例展示了如何配置超时以确保 after_script 即使主脚本超时也能运行:

job-with-script-timeouts:
  timeout: 5m
  variables:
    RUNNER_SCRIPT_TIMEOUT: 1m
    RUNNER_AFTER_SCRIPT_TIMEOUT: 1m
  script:
    - echo "开始构建..."
    - sleep 120 # 等待 2 分钟以触发超时。由于 RUNNER_SCRIPT_TIMEOUT,script 在 1 分钟后中止。
    - echo "构建完成。"
  after_script:
    - echo "开始清理..."
    - sleep 15 # 仅等待几秒钟。由于在 RUNNER_AFTER_SCRIPT_TIMEOUT 和作业的 timeout 值范围内,运行成功。
    - echo "清理完成。"

scriptRUNNER_SCRIPT_TIMEOUT 被取消,但 after_script 成功运行,因为它仅耗时 15 秒,小于 RUNNER_AFTER_SCRIPT_TIMEOUT 和作业的 timeout 值。

保护敏感信息

使用实例运行器时的安全风险更大,因为它们默认对 GitLab 实例中的所有组和项目可用。运行器执行器和文件系统配置会影响安全性。有权访问运行器主机环境的用户可以查看运行器执行的代码和运行器认证信息。例如,有权访问运行器认证令牌的用户可以克隆运行器并在向量攻击中提交虚假作业。有关更多信息,请参阅 安全注意事项

配置长轮询

要减少作业排队时间和 GitLab 服务器的负载,请配置 长轮询

在 fork 项目中使用实例运行器

当项目被 fork 时,与作业相关的作业设置会被复制。如果你为某个项目配置了实例运行器,且用户 fork 了该项目,则实例运行器将为该项目的作业提供服务。

由于 已知问题,如果 fork 项目的运行器设置与新项目命名空间不匹配,会显示以下消息:分叉项目时出错。请重试。

要解决这个问题,请确保 fork 项目和新的命名空间中的实例运行器设置一致。

  • 如果 fork 项目中实例运行器是启用的,那么新命名空间中也应启用
  • 如果 fork 项目中实例运行器是禁用的,那么新命名空间中也应禁用

重置项目的运行器注册令牌(已弃用)

传递运行器注册令牌和支持某些配置参数的选项在 GitLab 15.6 中已被弃用(issue #380872),并计划在 GitLab 20.0 中移除。
请使用 运行器创建工作流 生成认证令牌以注册运行器。此过程可完整追溯运行器所有权,并增强运行器集群的安全性。
更多信息请参阅 迁移到新的运行器注册工作流

如果您认为项目的注册令牌被泄露,应重置该令牌。注册令牌可用于为项目注册另一个运行器,该新运行器可能被用于获取秘密变量的值或克隆项目代码。

要重置注册令牌:

  1. 在左侧边栏选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 运行器
  4. 新建项目运行器 右侧,选择垂直省略号( ellipsis_v )。
  5. 选择 重置注册令牌
  6. 选择 重置令牌

重置注册令牌后,其将不再有效,无法再为项目注册新的运行器。您还应更新用于部署和注册新运行器的工具中的注册令牌。

认证令牌安全性

每个运行器使用一个 运行器认证令牌 连接并认证 GitLab 实例。

为防止令牌被泄露,您可以设置令牌按指定间隔自动轮换。当令牌轮换时,无论运行器状态(onlineoffline)如何,都会为每个运行器更新令牌。

无需手动干预,且不会影响正在运行的作业。有关令牌轮换的更多信息,请参阅 运行器认证令牌轮换时不更新

若需手动更新运行器认证令牌,可运行命令 重置令牌

重置运行器配置认证令牌

若运行器的认证令牌暴露,攻击者可能利用其 克隆运行器

要重置运行器配置认证令牌:

  1. 删除运行器:
  2. 创建新运行器以分配新的运行器认证令牌:
  3. 可选。若要验证之前的运行器认证令牌已被撤销,可使用 运行器 API

也可使用 运行器 API 重置运行器配置认证令牌。

自动轮换运行器身份验证令牌

您可以指定一个间隔来轮换运行器的身份验证令牌。 定期轮换运行器身份验证令牌有助于降低通过受损令牌对您的 GitLab 实例进行未授权访问的风险。

前提条件:

要自动轮换运行器身份验证令牌:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 设置 > CI/CD
  3. 展开 持续集成与部署
  4. 为运行器设置 运行器过期时间,留空则表示不过期。
  5. 选择 保存更改

在间隔到期前,运行器会自动请求新的运行器身份验证令牌。 有关令牌轮换的更多信息,请参阅 Runner authentication token does not update when rotated

防止运行器泄露敏感信息

为确保运行器不会泄露敏感信息,您可以将它们配置为仅运行 受保护的分支 上的作业,或带有 受保护标签 的作业。

配置为在受保护分支上运行作业的运行器可以 可选地在合并请求管道中运行作业

对于实例运行器

前提条件:

  • 您必须是管理员。
  1. 在左侧边栏底部,选择 Admin
  2. 选择 CI/CD > Runners
  3. 在要保护的运行器右侧,选择 编辑 ( pencil )。
  4. 勾选 受保护 复选框。
  5. 选择 保存更改

对于组运行器

前提条件:

  • 您必须是该组的所有者。
  1. 在左侧边栏,选择 搜索或前往 并找到您的组。
  2. 选择 构建 > Runners
  3. 在要保护的运行器右侧,选择 编辑 ( pencil )。
  4. 勾选 受保护 复选框。
  5. 选择 保存更改

对于项目运行器

前提条件:

  • 您必须是该项目的所有者。
  1. 在左侧边栏,选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 Runners
  4. 在要保护的运行器右侧,选择 编辑 ( pencil )。
  5. 勾选 受保护 复选框。
  6. 选择 保存更改

控制运行器可运行的作业

您可以使用 标签 来控制运行器可运行的作业。 例如,您可以为具有运行 Rails 测试套件依赖项的运行器指定 rails 标签。

GitLab CI/CD 标签与 Git 标签不同。GitLab CI/CD 标签与运行器关联。 Git 标签与提交关联。

对于实例运行器

前提条件:

  • 您必须是管理员。

要控制实例运行器可运行的作业:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 CI/CD > Runners
  3. 在要编辑的运行器右侧,选择 编辑 ( pencil )。
  4. 设置运行器以运行带标签或不带标签的作业:
    • 若要运行带标签的作业,请在 标签 字段中以逗号分隔输入作业标签。例如 macos, rails
    • 若要运行不带标签的作业,勾选 运行不带标签的作业 复选框。
  5. 选择 保存更改

对于组运行器

前提条件:

  • 您必须是该组的所有者。

要控制组运行器可运行的作业:

  1. 在左侧边栏,选择 搜索或前往 并找到您的组。
  2. 选择 构建 > Runners
  3. 在要编辑的运行器右侧,选择 编辑 ( pencil )。
  4. 设置运行器以运行带标签或不带标签的作业:
    • 若要运行带标签的作业,请在 标签 字段中以逗号分隔输入作业标签。例如 macos, ruby
    • 若要运行不带标签的作业,勾选 运行不带标签的作业 复选框。
  5. 选择 保存更改

对于项目运行器

前提条件:

  • 您必须是该项目的所有者。

要控制项目运行器可运行的作业:

  1. 在左侧边栏,选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 Runners
  4. 在要编辑的运行器右侧,选择 编辑 ( pencil )。
  5. 设置运行器以运行带标签或不带标签的作业:
    • 若要运行带标签的作业,请在 标签 字段中以逗号分隔输入作业标签。例如 macos, ruby
    • 若要运行不带标签的作业,勾选 运行不带标签的作业 复选框。
  6. 选择 保存更改

运行器如何使用标签

运行器仅运行带标签的任务

以下示例说明了将运行器设置为仅运行带标签任务时可能产生的影响。

示例 1:

  1. 该运行器被配置为仅运行带标签的任务,并且拥有 docker 标签。
  2. 一个带有 hello 标签的任务被执行并卡住。

示例 2:

  1. 该运行器被配置为仅运行带标签的任务,并且拥有 docker 标签。
  2. 一个带有 docker 标签的任务被执行并运行。

示例 3:

  1. 该运行器被配置为仅运行带标签的任务,并且拥有 docker 标签。
  2. 一个未定义任何标签的任务被执行并卡住。

运行器允许运行不带标签的任务

以下示例说明了将运行器设置为可运行带标签和不带标签任务时可能产生的影响。

示例 1:

  1. 该运行器被配置为运行不带标签的任务,并且拥有 docker 标签。
  2. 一个未定义任何标签的任务被执行并运行。
  3. 第二个带有 docker 标签的任务被执行并运行。

示例 2:

  1. 该运行器被配置为运行不带标签的任务,并且未定义任何标签。
  2. 一个未定义任何标签的任务被执行并运行。
  3. 第二个带有 docker 标签的任务被卡住。

运行器和任务具有多个标签

匹配任务与运行器的选择逻辑基于作业脚本块中定义的 tags 列表。

以下示例说明了运行器和任务具有多个标签时的潜在影响。若要让运行器被选中执行任务,它必须具备任务脚本块中定义的所有标签。

示例 1:

  1. 该运行器被配置了标签 [docker, shell, gpu]
  2. 任务拥有标签 [docker, shell, gpu] 并被执行运行。

示例 2:

  1. 该运行器被配置了标签 [docker, shell, gpu]
  2. 任务拥有标签 [docker, shell,] 并被执行运行。

示例 3:

  1. 该运行器被配置了标签 [docker, shell]
  2. 任务拥有标签 [docker, shell, gpu] 且未被执行。

使用标签在不同平台上运行任务

你可以使用标签在不同的平台上运行不同的任务。例如,如果你有一个带有 osx 标签的 macOS 运行器和一个带有 windows 标签的 Windows 运行器,你可以在每个平台上运行一个任务。

更新 .gitlab-ci.yml 文件中的 tags 字段:

windows job:
  stage: build
  tags:
    - windows
  script:
    - echo Hello, %USERNAME%!

osx job:
  stage: build
  tags:
    - osx
  script:
    - echo "Hello, $USER!"

在标签中使用CI/CD变量

.gitlab-ci.yml 文件中,结合 tags 使用 CI/CD 变量 来实现动态运行器选择:

variables:
  KUBERNETES_RUNNER: kubernetes

  job:
    tags:
      - docker
      - $KUBERNETES_RUNNER
    script:
      - echo "Hello runner selector feature"

使用变量配置运行器行为

你可以使用 CI/CD 变量 全局或针对单个作业来配置运行器的 Git 行为:

你也可以使用变量来配置运行器尝试执行作业某些阶段的次数(参考 作业阶段重试)。

在使用 Kubernetes 执行器时,你可以通过变量覆盖 Kubernetes 对请求和限制的 CPU 及内存分配(详情请见 覆盖容器资源)。

Git 策略

GIT_STRATEGY 变量用于配置构建目录的准备方式以及仓库内容的获取方式。你可以在 variables 部分全局设置此变量,或在每个作业中单独设置。

variables:
  GIT_STRATEGY: clone

可选值为 clonefetchnoneempty。若未指定值,作业将使用 项目的流水线设置 中定义的策略。

clone 是最慢的选项。它会为每个作业从零开始克隆仓库,确保本地工作副本始终处于纯净状态。如果发现现有工作树,会在克隆前将其移除。

fetch 更快,因为它会复用本地工作副本(若不存在则回退到 clone)。git clean 用于撤销上一个作业所做的更改,git fetch 用于获取自上一个作业运行后提交的新内容。

不过,fetch 确实需要访问之前的工作树。在使用 shelldocker 执行器时效果良好,因为这些执行器会尝试保留工作树并在默认情况下复用它们。

当使用 Docker Machine 执行器 时,这种方式存在限制。

none 类型的 Git 策略也会复用本地工作副本,但会跳过 GitLab 通常执行的 Git 操作。若有 GitLab Runner 预克隆脚本,这些脚本也会被跳过。该策略意味着你可能需要在 你的 .gitlab-ci.yml 脚本 中添加 fetchcheckout 命令。

它可用于仅对制品(artifact)进行操作的作业,例如部署作业。Git 仓库数据可能存在,但很可能已过时。你应仅依赖通过缓存或制品带入本地工作副本的文件。请注意,来自先前流水线的缓存和制品文件可能仍存在于本地。

none 不同,empty Git 策略会在下载缓存或制品文件前删除并重新创建专用构建目录。在此策略下,若提供了 GitLab Runner 钩子脚本,这些脚本仍会运行以允许进一步的行为自定义。当你满足以下条件时,请使用 empty Git 策略:

  • 你不需要仓库数据存在。
  • 你希望每次作业运行时都有一个干净、可控或定制的初始状态。

Git 子模块策略

GIT_SUBMODULE_STRATEGY 变量用于控制在构建前获取代码时是否及如何包含 Git 子模块。你可以全局设置或在每个作业的 variables 部分设置。

三种可能值分别为 nonenormalrecursive

  • none 表示获取项目代码时不包含子模块。此设置匹配 1.10 版本之前的默认行为。

  • normal 表示仅包含顶级子模块。等效于:

    git submodule sync
    git submodule update --init
  • recursive 表示包含所有子模块(包括子模块的子模块)。此功能需要 Git v1.8.1 及更高版本。当使用非基于 Docker 的执行器的 GitLab Runner 时,需确保 Git 版本符合要求。等效于:

    git submodule sync --recursive
    git submodule update --init --recursive

为确保此功能正常工作,子模块必须在 .gitmodules 中配置为以下任一形式:

  • 公网可访问仓库的 HTTP(S) URL,或
  • 同一 GitLab 服务器上其他仓库的相对路径。参见 Git 子模块 文档。

你可以使用 GIT_SUBMODULE_UPDATE_FLAGS 提供额外标志来控制高级行为。

Git 检出

GIT_STRATEGY 设为 clonefetch 时,可使用 GIT_CHECKOUT 变量指定是否执行 git checkout。若未指定,默认为 true。你可以在 variables 部分全局或按作业设置。

若设为 false,Runner 行为如下:

  • 执行 fetch 时:更新仓库并将工作副本留在当前版本,
  • 执行 clone 时:克隆仓库并将工作副本留在默认分支。

GIT_CHECKOUT 设为 trueclonefetch 行为相同。Runner 会检出与 CI 流水线相关的修订版的工作副本:

variables:
  GIT_STRATEGY: clone
  GIT_CHECKOUT: "false"
script:
  - git checkout -B master origin/master
  - git merge $CI_COMMIT_SHA

Git clean 标志

GIT_CLEAN_FLAGS 变量用于控制检出源码后 git clean 的默认行为。你可以在全局或每个作业的 variables 部分中设置它。

GIT_CLEAN_FLAGS 接受 git clean 命令的所有可能选项。

如果指定了 GIT_CHECKOUT: "false",则禁用 git clean

如果 GIT_CLEAN_FLAGS 是:

  • 未指定,git clean 标志默认为 -ffdx
  • 给定值 none,不执行 git clean

例如:

variables:
  GIT_CLEAN_FLAGS: -ffdx -e cache/
script:
  - ls -al cache/

Git fetch 额外标志

使用 GIT_FETCH_EXTRA_FLAGS 变量来控制 git fetch 的行为。你可以在全局或每个作业的 variables 部分中设置它。

GIT_FETCH_EXTRA_FLAGS 接受 git fetch 命令的所有选项。但是,GIT_FETCH_EXTRA_FLAGS 标志会被追加到无法修改的默认标志之后。

默认标志包括:

如果 GIT_FETCH_EXTRA_FLAGS 是:

  • 未指定,git fetch 标志默认为 --prune --quiet 加上默认标志。
  • 给定值 nonegit fetch 仅使用默认标志执行。

例如,默认标志是 --prune --quiet,因此你可以通过仅覆盖为 --prune 来让 git fetch 更详细:

variables:
  GIT_FETCH_EXTRA_FLAGS: --prune
script:
  - ls -al cache/

之前的配置会导致 git fetch 以这种方式调用:

git fetch origin $REFSPECS --depth 20  --prune

其中 $REFSPECS 是 GitLab 内部提供给运行器的值。

同步或从 CI 作业中排除特定子模块

使用 GIT_SUBMODULE_PATHS 变量来控制哪些子模块需要同步或更新。你可以在全局或每个作业的 variables 部分中设置它。

路径语法与 git submodule 相同:

  • 要同步和更新特定路径:

    variables:
       GIT_SUBMODULE_PATHS: submoduleA submoduleB
  • 要排除特定路径:

    variables:
       GIT_SUBMODULE_PATHS: ":(exclude)submoduleA :(exclude)submoduleB"

Git 会忽略嵌套路径。若要忽略嵌套子模块,请排除父级子模块,然后在作业脚本中手动克隆它。例如,git clone <repo> --recurse-submodules=':(exclude)nested-submodule'。确保将字符串用单引号括起来,以便 YAML 能成功解析。

Git 子模块更新标志

使用 GIT_SUBMODULE_UPDATE_FLAGS 变量来控制当 GIT_SUBMODULE_STRATEGY 设为 normalrecursivegit submodule update 的行为。你可以在全局或每个作业的 variables 部分中设置它。

GIT_SUBMODULE_UPDATE_FLAGS 接受 git submodule update 子命令的所有选项。但 GIT_SUBMODULE_UPDATE_FLAGS 标志会附加在一些默认标志之后:

Git 会遵循参数列表中标志的最后出现位置,因此手动在 GIT_SUBMODULE_UPDATE_FLAGS 中提供这些标志会覆盖默认标志。

例如,你可以用此变量:

  • --remote 标志获取最新的远程 HEAD 而非仓库中追踪的提交(默认),从而自动更新所有子模块。
  • --jobs 4 标志通过多并行任务加速检出。
variables:
  GIT_SUBMODULE_STRATEGY: recursive
  GIT_SUBMODULE_UPDATE_FLAGS: --remote --jobs 4
script:
  - ls -al .git/modules/

上述配置会导致 git submodule update 以这种方式调用:

git submodule update --init --depth 20 --recursive --remote --jobs 4

你应该意识到在使用 --remote 标志时对构建的安全性、稳定性和可重复性的影响。在大多数情况下,最好明确跟踪子模块提交,并使用自动修复/依赖机器人更新它们。

--remote 标志不是必需的,用于检出子模块在其提交版本上。仅当你想将子模块自动更新到其最新远程版本时才使用此标志。

--remote 的行为取决于你的 Git 版本。如果你的超级项目的 .gitmodules 文件中指定的分支与子模块仓库的默认分支不同,某些 Git 版本会出现以下错误:

fatal: Unable to find refs/remotes/origin/<branch> revision in submodule path '<submodule-path>'

Runner 实现了一种“尽力而为”的后备机制,尝试在子模块更新失败时拉取远程引用。

如果此后备机制在你的 Git 版本下无效,请尝试以下解决方法:

  • 更新子模块仓库的默认分支以匹配超级项目中 .gitmodules 文件中设置的分支。
  • GIT_SUBMODULE_DEPTH 设为 0
  • 单独更新子模块并从 GIT_SUBMODULE_UPDATE_FLAGS 中移除 --remote 标志。

将子模块 URL 重写为 HTTPS

使用 GIT_SUBMODULE_FORCE_HTTPS 变量强制重写所有 Git 和 SSH 子模块 URL 为 HTTPS。即使子模块配置了 Git 或 SSH 协议,你也可以克隆同一 GitLab 实例中使用绝对 URL 的子模块。

variables:
  GIT_SUBMODULE_STRATEGY: recursive
  GIT_SUBMODULE_FORCE_HTTPS: "true"

启用后,GitLab Runner 使用 CI/CD 作业令牌 克隆子模块。该令牌使用执行作业的用户权限,无需 SSH 凭证。

浅克隆

你可以使用 GIT_DEPTH 指定获取和克隆的深度。
GIT_DEPTH 会执行仓库的浅克隆,能显著加快克隆速度。
对于包含大量提交或老旧大型二进制的仓库很有帮助。该值会传递给 git fetchgit clone

新建项目会自动应用 默认 git depth 值为 20

若你将深度设为 1 且存在作业队列或重试作业,作业可能会失败。

Git 获取和克隆基于引用(如分支名)进行,因此 Runner 无法克隆特定的 commit SHA。
若有多个作业在队列中,或重试旧作业,被测试的 commit 必须存在于克隆的 Git 历史中。
GIT_DEPTH 设得太小,会导致这些旧提交无法运行,作业日志会显示 unresolved reference
此时你应该考虑将 GIT_DEPTH 改为更大的值。

依赖 git describe 的作业在设置 GIT_DEPTH 时可能无法正常工作,因为仅存在部分 Git 历史。

若仅需获取或克隆最近 3 个提交:

variables:
  GIT_DEPTH: "3"

你可以在 variables 部分全局或按作业设置它。

Git 子模块深度

使用 GIT_SUBMODULE_DEPTH 变量指定获取和克隆子模块的深度,当 GIT_SUBMODULE_STRATEGY 设为 normalrecursive 时。
你可以在 variables 部分全局或针对特定作业设置它。

当你设置 GIT_SUBMODULE_DEPTH 变量时,它只会覆盖子模块的 GIT_DEPTH 设置。

若仅需获取或克隆最近 3 个提交:

variables:
  GIT_SUBMODULE_DEPTH: 3

自定义构建目录

默认情况下,GitLab Runner 在 $CI_BUILDS_DIR 目录的唯一子路径中克隆仓库。
不过,你的项目可能需要代码位于特定目录(例如 Go 项目)。这种情况下,你可以通过 GIT_CLONE_PATH 变量告诉 Runner 克隆仓库的目标目录:

variables:
  GIT_CLONE_PATH: $CI_BUILDS_DIR/project-name

test:
  script:
    - pwd

GIT_CLONE_PATH 必须始终位于 $CI_BUILDS_DIR 内。$CI_BUILDS_DIR 目录依赖于执行器及 runners.builds_dir 配置项的设置。

这仅在 runner 配置中启用了 custom_build_dir 时可用。

处理并发

使用并发数大于 1 的执行器可能导致失败。
builds_dir 在作业间共享,多个作业可能同时操作同一目录。

Runner 不会尝试阻止这种情况,遵守 runner 配置的要求是管理员和开发者的责任。

为避免此场景,你可以在 $CI_BUILDS_DIR 中使用唯一路径,因为 Runner 提供了两个额外变量以提供并发的唯一 ID

  • $CI_CONCURRENT_ID:给定执行器中所有运行作业的唯一 ID。
  • $CI_CONCURRENT_PROJECT_ID:给定执行器和项目中所有运行作业的唯一 ID。

在任何场景和执行器上都能稳定工作的最佳配置,是使用 $CI_CONCURRENT_ID 作为 GIT_CLONE_PATH 的一部分。例如:

variables:
  GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/project-name

test:
  script:
    - pwd -P

$CI_CONCURRENT_PROJECT_ID 应与 $CI_PROJECT_PATH 结合使用。
$CI_PROJECT_PATH 提供 group/subgroup/project 格式的仓库路径。例如:

variables:
  GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH

test:
  script:
    - pwd -P

嵌套路径

GIT_CLONE_PATH 的值仅展开一次。你不能在此值中嵌套变量。

例如,你在 .gitlab-ci.yml 文件中定义了以下变量:

variables:
  GOPATH: $CI_BUILDS_DIR/go
  GIT_CLONE_PATH: $GOPATH/src/namespace/project

GIT_CLONE_PATH 的值会被展开为 $CI_BUILDS_DIR/go/src/namespace/project,最终导致失败,因为 $CI_BUILDS_DIR 未被展开。

忽略 after_script 中的错误

您可以在作业中使用 after_script 定义一组命令,这些命令应在作业的 before_scriptscript 部分之后运行。无论脚本终止状态(失败或成功)如何,after_script 命令都会执行。

默认情况下,GitLab Runner 会忽略 after_script 运行时发生的任何错误。若要在 after_script 运行时立即使作业因错误而失败,请将 AFTER_SCRIPT_IGNORE_ERRORS CI/CD 变量设置为 false。例如:

variables:
  AFTER_SCRIPT_IGNORE_ERRORS: false

作业阶段尝试次数

您可以设置正在运行的作业尝试执行以下阶段的次数:

变量 描述
ARTIFACT_DOWNLOAD_ATTEMPTS 运行作业时下载工件的尝试次数
EXECUTOR_JOB_SECTION_ATTEMPTS 在出现 No Such Container 错误后,在作业中运行某个部分的尝试次数(仅适用于 Docker 执行器)。
GET_SOURCES_ATTEMPTS 运行作业时获取源代码的尝试次数
RESTORE_CACHE_ATTEMPTS 运行作业时恢复缓存的尝试次数

默认为单次尝试。

示例:

variables:
  GET_SOURCES_ATTEMPTS: 3

您可以在全局范围内或在作业的 variables 部分中按作业设置它们。

GitLab.com 实例运行程序上不可用的系统调用

GitLab.com 实例运行程序在 CoreOS 上运行。这意味着您无法使用来自 C 标准库的一些系统调用,如 getlogin

工件和缓存设置

工件和缓存设置控制工件和缓存的压缩比。使用这些设置指定作业生成的归档文件的大小。

  • 在慢速网络上,较小的归档文件上传速度可能更快。
  • 在带宽和存储不是问题的快速网络上,尽管生成的归档文件更大,但使用最快的压缩比可能会加快上传速度。

为了使 GitLab Pages 能够处理 HTTP 范围请求,工件应使用 ARTIFACT_COMPRESSION_LEVEL: fastest 设置,因为只有未压缩的 zip 归档文件支持此功能。

可以启用计量器以提供上传和下载的传输速率。

您可以使用 CACHE_REQUEST_TIMEOUT 设置来设置缓存上传和下载的最大时间。当缓慢的缓存上传显著增加作业持续时间时,请使用此设置。

variables:
  # 每 2 秒输出一次上传和下载进度
  TRANSFER_METER_FREQUENCY: "2s"

  # 对工件使用快速压缩,生成更大的归档文件
  ARTIFACT_COMPRESSION_LEVEL: "fast"

  # 对缓存不进行压缩
  CACHE_COMPRESSION_LEVEL: "fastest"

  # 设置缓存上传和下载的最大时长
  CACHE_REQUEST_TIMEOUT: 5
变量 描述
TRANSFER_METER_FREQUENCY 指定打印计量器传输速率的频率。它可以设置为持续时间(例如,1s1m30s)。持续时间为 0 时禁用计量器(默认值)。当设置了值时,管道会显示工件和缓存的上传和下载进度条。
ARTIFACT_COMPRESSION_LEVEL 要调整压缩比,请将其设置为 fastestfastdefaultslowslowest。此设置仅适用于 Fastzip 归档程序,因此还必须启用 GitLab Runner 功能标志 FF_USE_FASTZIP
CACHE_COMPRESSION_LEVEL 要调整压缩比,请将其设置为 fastestfastdefaultslowslowest。此设置仅适用于 Fastzip 归档程序,因此还必须启用 GitLab Runner 功能标志 FF_USE_FASTZIP
CACHE_REQUEST_TIMEOUT 配置单个作业的缓存上传和下载操作的最大持续时间(以分钟为单位)。默认值为 10 分钟。

制品来源元数据

Runner 可以生成 SLSA Provenance 并产生一个 SLSA Statement,该声明将来源信息绑定到所有构建制品上。这个声明被称为制品来源元数据。

要启用制品来源元数据,请将 RUNNER_GENERATE_ARTIFACTS_METADATA 环境变量设置为 true。你可以全局设置该变量,或针对单个作业设置:

variables:
  RUNNER_GENERATE_ARTIFACTS_METADATA: "true"

job1:
  variables:
    RUNNER_GENERATE_ARTIFACTS_METADATA: "true"

元数据以纯文本 .json 文件的形式呈现,与制品一同存储。文件名为 {ARTIFACT_NAME}-metadata.jsonARTIFACT_NAME 是在 .gitlab-ci.yml 文件中定义的制品名称。如果未定义名称,默认文件名为 artifacts-metadata.json

来源元数据格式

工件来源元数据以 in-toto v0.1 Statement 格式生成。它包含一个以 SLSA 1.0 Provenance 格式生成的来源谓词。

以下字段默认填充:

字段
_type https://in-toto.io/Statement/v0.1
subject 元数据适用的软件工件集合
subject[].name 工件的文件名。
subject[].sha256 工件的 sha256 校验和。
predicateType https://slsa.dev/provenance/v1
predicate.buildDefinition.buildType https://gitlab.com/gitlab-org/gitlab-runner/-/blob/{GITLAB_RUNNER_VERSION}/PROVENANCE.md。例如,v15.0.0
predicate.runDetails.builder.id 指向运行器详情页面的 URI,例如 https://gitlab.com/gitlab-com/www-gitlab-com/-/runners/3785264
predicate.buildDefinition.externalParameters 构建命令执行期间可用的任何 CI/CD 或环境变量的名称。该值始终表示为空字符串以保护秘密。
predicate.buildDefinition.externalParameters.source 项目的 URL。
predicate.buildDefinition.externalParameters.entryPoint 触发构建的 CI/CD 作业的名称。
predicate.buildDefinition.internalParameters.name 运行器的名称。
predicate.buildDefinition.internalParameters.executor 运行器执行器。
predicate.buildDefinition.internalParameters.architecture 运行 CI/CD 作业的架构。
predicate.buildDefinition.internalParameters.job 触发构建的 CI/CD 作业的 ID。
predicate.buildDefinition.resolvedDependencies[0].uri 项目的 URL。
predicate.buildDefinition.resolvedDependencies[0].digest.sha256 项目的提交版本。
predicate.runDetails.metadata.invocationID 触发构建的 CI/CD 作业的 ID。
predicate.runDetails.metadata.startedOn 构建开始的时间。此字段采用 RFC3339 格式。
predicate.runDetails.metadata.finishedOn 构建结束的时间。由于元数据生成发生在构建过程中,此时间略早于 GitLab 报告的时间。此字段采用 RFC3339 格式。

来源声明应类似以下示例:

{
 "_type": "https://in-toto.io/Statement/v0.1",
 "predicateType": "https://slsa.dev/provenance/v1",
 "subject": [
  {
   "name": "x.txt",
   "digest": {
    "sha256": "ac097997b6ec7de591d4f11315e4aa112e515bb5d3c52160d0c571298196ea8b"
   }
  },
  {
   "name": "y.txt",
   "digest": {
    "sha256": "9eb634f80da849d828fcf42740d823568c49e8d7b532886134f9086246b1fdf3"
   }
  }
 ],
 "predicate": {
  "buildDefinition": {
   "buildType": "https://gitlab.com/gitlab-org/gitlab-runner/-/blob/2147fb44/PROVENANCE.md",
   "externalParameters": {
    "CI": "",
    "CI_API_GRAPHQL_URL": "",
    "CI_API_V4_URL": "",
    "CI_COMMIT_AUTHOR": "",
    "CI_COMMIT_BEFORE_SHA": "",
    "CI_COMMIT_BRANCH": "",
    "CI_COMMIT_DESCRIPTION": "",
    "CI_COMMIT_MESSAGE": "",
    [... additional environmental variables ...]
    "entryPoint": "build-job",
    "source": "https://gitlab.com/my-group/my-project/test-runner-generated-slsa-statement"
   },
   "internalParameters": {
    "architecture": "amd64",
    "executor": "docker+machine",
    "job": "10340684631",
    "name": "green-4.saas-linux-small-amd64.runners-manager.gitlab.com/default"
   },
   "resolvedDependencies": [
    {
     "uri": "https://gitlab.com/my-group/my-project/test-runner-generated-slsa-statement",
     "digest": {
      "sha256": "bdd2ecda9ef57b129c88617a0215afc9fb223521"
     }
    }
   ]
  },
  "runDetails": {
   "builder": {
    "id": "https://gitlab.com/my-group/my-project/test-runner-generated-slsa-statement/-/runners/12270857",
    "version": {
     "gitlab-runner": "2147fb44"
    }
   },
   "metadata": {
    "invocationID": "10340684631",
    "startedOn": "2025-06-13T07:25:13Z",
    "finishedOn": "2025-06-13T07:25:40Z"
   }
  }
 }
}

暂存目录

如果您不想在系统默认临时目录中归档缓存和制品,可以指定不同的目录。

如果系统的默认临时路径有约束条件,您可能需要更改该目录。 如果在目录位置使用快速磁盘,也可以提高性能。

要更改目录,请在 CI 作业中将 ARCHIVER_STAGING_DIR 设置为变量,或在注册运行器时使用运行器变量(gitlab register --env ARCHIVER_STAGING_DIR=<dir>)。

您指定的目录用作提取前下载制品的位置。如果使用了 fastzip 归档程序,此位置也用作归档时的临时空间。

配置 fastzip 以提高性能

要调整 fastzip,请确保启用了 FF_USE_FASTZIP 标志。 然后使用以下任何环境变量。

变量 描述
FASTZIP_ARCHIVER_CONCURRENCY 要并发压缩的文件数量。默认值为可用 CPU 数量。
FASTZIP_ARCHIVER_BUFFER_SIZE 为每个并发分配的缓冲区大小。超过此数值的数据会移动到临时空间。默认值为 2 MiB。
FASTZIP_EXTRACTOR_CONCURRENCY 要并发解压的文件数量。默认值为可用 CPU 数量。

zip 归档中的文件是按顺序追加的。这使得并发压缩具有挑战性。fastzip 通过先将文件并发压缩到磁盘,然后将结果按顺序复制回 zip 归档来解决这个问题。

为了避免对小文件写入磁盘并重新读取内容,每个并发使用一个小缓冲区。此设置可通过 FASTZIP_ARCHIVER_BUFFER_SIZE 控制。此缓冲区的默认大小为 2 MiB,因此,16 个并发会分配 32 MiB。超过缓冲区大小的数据会被写入磁盘并重新读取。 因此,不使用缓冲区(FASTZIP_ARCHIVER_BUFFER_SIZE: 0),仅使用临时空间是一个有效的选项。

FASTZIP_ARCHIVER_CONCURRENCY 控制有多少文件被并发压缩。如前所述,此设置会增加内存使用量。它还会增加写入临时空间的临时数据量。 默认值是可用的 CPU 数量,但考虑到内存影响,这可能并不总是最佳设置。

FASTZIP_EXTRACTOR_CONCURRENCY 控制一次解压多少个文件。zip 归档中的文件可以原生地并发读取,因此除了解压器所需的内容外,不会额外分配内存。这默认为可用的 CPU 数量。