.gitlab-ci.yml 关键字参考
.gitlab-ci.yml 文件中关键字示例,查看官网 .gitlab-ci.yml 语法参考。
default
您可以为某些关键字设置全局默认值。例如:
default:
image: ruby:3.0
rspec:
script: bundle exec rspec
rspec 2.7:
image: ruby:2.7
script: bundle exec rspec
示例将 ruby:3.0 镜像设置为流水线中所有作业的默认镜像。rspec 2.7 作业不使用默认值,因为它使用特定于作业的 image: 部分覆盖了默认值。
额外细节:
- 创建流水线时,每个默认值都会复制到所有未定义该关键字的作业
- 如果作业已经配置了其中一个关键字,则作业中的配置优先,不会被默认替换
- 使用
inherit:default控制作业中默认关键字的继承
stages
使用 stages 来定义包含作业组的阶段,stages 是为流水线全局定义的。在作业中使用 stage 来定义作业属于哪个阶段,一般在 .gitlab-ci.yml 文件的顶部定义。
如果 .gitlab-ci.yml 文件中没有定义 stages,那么默认的流水线阶段是:
.prebuildtestdeploy.post
如果流水线仅包含 .pre 或 .post 阶段的作业,则它不会运行。在不同的阶段必须至少有一项其他作业。
stages 项的顺序定义了作业的执行顺序:
- 同一阶段的作业并行运行
- 下一阶段的作业在上一阶段的作业成功完成后运行
例如:也可以自定义 stages 值。
stages:
- check
- build
- test
- deploy
build 中的所有作业并行执行,如果 build 中的所有作业都成功,test 作业将并行执行;如果 test 中的所有作业都成功,deploy 作业将并行执行;如果 deploy 中的所有作业都成功,则流水线被标记为 passed。
如果任何作业失败,流水线将被标记为 failed 并且后续阶段的作业不会启动,当前阶段的作业不会停止并继续运行。
如果作业未指定 stage,则作业被分配到 test 阶段。
如果定义了一个阶段,但没有作业使用它,则该阶段在流水线中不可见。这对合规流水线配置很有用,因为:
- 阶段可以在合规性配置中定义,但如果不使用则保持隐藏
- 当开发人员在作业定义中使用它们时,定义的阶段变得可见
要使作业更早开始并忽略阶段顺序,请使用 needs 关键字。
stage
使用 stage 定义作业在哪个 stage 中运行。同一个 stage 中的作业可以并行执行。
如果没有定义 stage,则作业默认使用 test 阶段。
- 关键字类型:作业关键字。您只能将其用作作业的一部分
- 可能的输入:字符串
- 默认阶段
- 用户定义的阶段
例如:依次执行 build、test 和 deploy 阶段,job2 和 job3 会在 test 阶段中并行执行。
stages:
- build
- test
- deploy
job1:
stage: build
script:
- echo "This job compiles code."
job2:
stage: test
script:
- echo "This job tests the compiled code. It runs when the build stage completes."
job3:
script:
- echo "This job also runs in the test stage".
job4:
stage: deploy
script:
- echo "This job deploys the code. It runs when the test stage completes."
environment: production
额外细节:
- 如果作业在不同的 Runner 上运行,则它们可以并行运行
- 如果您只有一个 Runner,如果 Runner 的
concurrent设置大于1,作业可以并行运行
使用 stage: .pre 阶段在流水线开始时运行作业。.pre 始终是流水线的第一阶段。用户定义的阶段在 .pre 之后执行。您不必在 stages 中定义 .pre。
使用 stage: .post 阶段在流水线末尾时运行作业。.post 始终是流水线的最后阶段。用户定义的阶段在 .post 之前执行。您不必在 stages 中定义 .post。
如果流水线仅包含 .pre 或 .post 阶段的作业,则它不会运行。在不同的阶段必须至少有一项其他作业。
关键字类型:您只能将它与作业的 stage 关键字一起使用
例如:分别在流水线开始和末尾时运行作业。
stages:
- build
- test
job1:
stage: build
script:
- echo "This job runs in the build stage."
first-job:
stage: .pre
script:
- echo "This job runs in the .pre stage, before all other stages."
last-job:
stage: .post
script:
- echo "This job runs in the .post stage, after all other stages."
job2:
stage: test
script:
- echo "This job runs in the test stage."
额外细节:
- 如果流水线有包含
needs: []的作业和.pre阶段的作业,它们将在流水线创建后立即启动。具有needs: []的作业会立即启动,忽略任何阶段配置。
script
使用 script 指定 Runner 要执行的命令。除了 trigger 之外的所有作业都需要一个 script 关键字。
使用 before_script 定义在每个作业的 script 命令之前运行,但在 artifacts 恢复之后。
使用 after_script 定义在每个作业之后运行的命令,包括失败的作业。
- 关键字类型:作业关键字。您只能将其用作作业的一部分
- 可能的输入:一个数组,包括:
- 单行命令
- 长命令拆分多行,使用
-开头表示每一行脚本 - YAML 锚点
例如:
job1:
script: echo "job1"
job2:
script:
- uname -a
- echo "job2"
job3:
script:
- echo "This command executes after the job's 'before_script' commands."
- echo "An example script section."
after_script:
- echo "Execute this command after the script section completes."
before_script:
- echo "Execute this command before any 'script:' commands."
额外细节:
- 当您使用
script中的特殊字符时,必须使用单引号(')或双引号(") - 您在
before_script中指定的脚本与您在主script中指定的任何脚本连接在一起。组合脚本在单个shell中一起执行 - 不推荐在 default 中使用
before_script和after_script - 您在
after_script中指定的脚本在一个新的shell中执行,与任何before_script或script命令分开。结果:- 将当前工作目录设置回默认值(根据定义运行程序如何处理 Git 请求的变量)
- 无权访问由
before_script或script中定义的命令完成的更改,包括- 在
script脚本中导出的命令别名和变量 - 作业树之外的更改(取决于 runner),例如:由
before_script或script脚本安装的软件
- 在
- 有一个单独的超时,它被硬编码为
5分钟 - 不要影响作业的退出代码。如果
script部分成功并且after_script超时或失败,作业将退出,代码为 0(Job Succeeded)
如果作业超时或被取消,则不会执行 after_script 命令。存在一个问题,即为超时或取消的作业添加对执行 after_script 命令的支持。
cache
使用 cache 指定要在作业之间缓存的文件和目录列表,您只能使用本地工作副本中的路径。
流水线中的每个作业都是独立运行的,如果没有缓存,运行上一个作业时安装的项目依赖包,运行下一个作业还需要安装一次。如果将上一个作业安装的依赖包缓存起来,在下一个作业运行时将其恢复到工作目录中,就可以大大减少资源的浪费。缓存用的最多的场景就是缓存项目的依赖包。
缓存:
- 在流水线和作业之间共享
- 默认情况下,不在受保护和未受保护的分支之间共享
- 在产物之前恢复
- 限制为最多四个不同的缓存
您可以禁用特定作业的缓存,例如覆盖:
- 使用
default定义的默认缓存 - 添加了
include的作业的配置
cache:key
使用 cache:key 关键字为每个缓存提供唯一的标识键。使用相同缓存键的所有作业都使用相同的缓存,包括在不同的流水线中。
如果未设置,则默认键为 default。所有带有 cache 关键字但没有 cache:key 的作业共享 default 缓存。
必须与 cache:paths 一起使用,否则不会缓存任何内容。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:
- 一个字符串
- 预定义变量
- 两者的结合
例如:项目有多个分支,想要设置多个缓存。
cache-job:
script:
- echo "This job uses a cache."
cache:
key: binaries-cache-$CI_COMMIT_REF_SLUG
paths:
- binaries/
额外细节:
- 如果您使用
Windows Batch运行您的shell脚本,您需要用%替换$。例如:key:%CI_COMMIT_REF_SLUG% cache:key值不能包含:/字符,或等效的 URI 编码的%2F- 只有
.字符(任何数字),或等效的 URI 编码的%2E
- 缓存在作业之间共享,因此如果您为不同的作业使用不同的路径,您还应该设置不同的
cache:key,否则缓存内容可能会被覆盖
cache:paths
缓存 binaries 中以 .apk 和当前目录中以 .config 结尾的所有文件:
rspec:
script:
- echo "This job uses a cache."
cache:
key: binaries-cache
paths:
- binaries/*.apk
- .config
额外细节:
cache:paths关键字包括文件,即使它们未被跟踪或在您的.gitignore文件中。
cache:key:file
使用 cache:key:files 关键字在一两个特定文件更改时生成新密钥。cache:key:files 可让您重用一些缓存,并减少重建它们的频率,从而加快后续流水线运行的速度。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:一个或两个文件路径的数组
例如:缓存绑定到当前版本的 Gemfile.lock 和 package.json 文件。当这些文件之一发生变化时,将计算一个新的缓存键并创建一个新的缓存。任何使用相同的 Gemfile.lock 和 package.json 以及 cache:key:files 的未来作业都会使用新的缓存,而不是重建依赖项。
cache-job:
script:
- echo "This job uses a cache."
cache:
key:
files:
- Gemfile.lock
- package.json
paths:
- vendor/ruby
- node_modules
额外信息:缓存 key 是根据最近更改了每个列出的文件的提交计算得出的 SHA。如果在任何提交中都没有更改任何文件,则回退键是 default。
image
使用 image 指定运行作业的 Docker 镜像。对特定的 Runner 执行器有用(如:docker 执行器),对其它 Runner 执行器无效(如:shell 执行器)。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:镜像的名称,包括镜像库路径(如果需要),采用以下格式之一:
<image-name>(与使用带有latest标签的<image-name>相同)<image-name>:<tag><image-name>@<digest>
例如:流水线中所有作业默认使用 ruby:3.0 镜像。rspec 2.7 作业不使用默认值,因为它使用特定于作业的 image 部分覆盖了默认值。
default:
image: ruby:3.0
rspec:
script: bundle exec rspec
rspec 2.7:
image: registry.example.com/my-group/my-project/ruby:2.7
script: bundle exec rspec
image:name
作业运行所在的 Docker 镜像的名称。与自身使用的 image 类似。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:镜像的名称,包括镜像库路径(如果需要),采用以下格式之一
<image-name>(与使用带有latest标签的<image-name>相同)<image-name>:<tag><image-name>@<digest>
例如:使用 registry.example.com/my/image:latest 镜像。
image:
name: "registry.example.com/my/image:latest"
image:pull_policy
引入于 15.1 版本,功能标志为 ci_docker_image_pull_policy,默认禁用。Runner 用于获取 Docker 镜像的拉取策略。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:单个拉取策略或数组中的多个拉取策略。可以是
always、if-not-present或never- always:即使本地镜像存在也拉取镜像。默认
- if-not-present:仅在本地版本不存在时拉取镜像
- never:从不拉取镜像,只使用本地镜像
例如:job1 作业使用 if-not-present 拉取策略;job2 作业先使用 always 作为第一拉取策略,如果 always 拉取策略失败,再使用 if-not-present 第二拉取策略。
job1:
script: echo "A single pull policy."
image:
name: ruby:3.0
pull_policy: if-not-present
job2:
script: echo "Multiple pull policies."
image:
name: ruby:3.0
pull_policy: [always, if-not-present]
额外细节:
- 如果 Runner 不支持定义的拉取策略,则作业将失败并出现类似此错误:
ERROR: Job failed (system failure): the configured PullPolicies ([always]) are not allowed by AllowedPullPolicies ([never])
image:entrypoint
作为容器入口点执行的命令或脚本。
创建 Docker 容器时,entrypoint 被转换为 Docker 的 --entrypoint 选项。语法类似于 Dockerfile ENTRYPOINT 指令,其中每个 shell 令牌都是数组中的一个单独字符串。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:一个字符串
例如:容器启动时运行 /bin/bash 命令。
image:
name: super/sql:experimental
entrypoint: ["/bin/bash"]
services
使用 services 指定您的脚步成功运行所需的任何其他 Docker 镜像。services 镜像链接到 image 关键字中指定的镜像。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:服务镜像的名称,包括镜像库路径(如果需要),采用以下格式之一
<image-name>(与使用带有latest标签的<image-name>相同)<image-name>:<tag><image-name>@<digest>
例如:作业启动一个 Ruby 容器。然后,该作业从该容器启动另一个运行 PostgreSQL 的容器。然后该作业在该容器中运行脚本。
default:
image:
name: ruby:2.6
entrypoint: ["/bin/bash"]
services:
- name: my-postgres:11.7
alias: db-postgres
entrypoint: ["/usr/local/bin/db-postgres"]
command: ["start"]
before_script:
- bundle install
test:
script:
- bundle exec rake spec
在此示例中,极狐GitLab 为作业启动了两个容器:
- 运行
script命令的 Ruby 容器 - 一个 PostgreSQL 容器。Ruby 容器中的
script命令可以连接到位于db-postgres主机名的 PostgreSQL 数据库
tags
使用 tags 从项目可用的所有 Runner 列表中选择一个特定的 Runner。开发者可以为一条流水线指定一个 Runner,也可以针对某一个作业指定一个 Runner。
注册 Runner 时,您可以指定 Runner 的标签,例如:ruby、postgres 或 development。
- 关键字类型:作业关键字。您只能将其用作作业的一部分或在 default 部分中使用
- 可能的输入:
- 标签名称数组
- 14.1 及更高版本中的 CI/CD 变量
例如:只有同时具有 ruby 和 postgres 标签的 Runner 才能运行该作业。
job:
tags:
- ruby
- postgres
额外细节:
- 在 14.3 及更高版本中,标签数量必须小于
50 - 如果指定的
tags找到多个 Runner,作业会在多个 Runner 之间进行调度。建议使用同一个 Runner 执行整条流水线 - 如果没有指定
tags,在执行时系统会去寻找那些可用、公共的 Runner 执行
variables
使用 variables 为作业定义自定义变量。变量在 script、before_script 和 after_script 命令中可用。您还可以在某些作业关键字中使用变量作为输入。
- 关键字类型:全局和工作关键字
- 可能的输入:变量名和值对
- 名称只能使用数字、字母和下划线(
_) - 值必须是字符串
- 名称只能使用数字、字母和下划线(
例如:分别在全局和作业中定义变量。
variables:
DEPLOY_SITE: "https://example.com/"
deploy_job:
stage: deploy
script:
- deploy-script --url $DEPLOY_SITE --path "/"
environment: production
deploy_review_job:
stage: deploy
variables:
REVIEW_PATH: "/review"
script:
- deploy-review-script --url $DEPLOY_SITE --path ${REVIEW_PATH}
environment: production
额外细节:
- 所有 YAML 定义的变量也设置为任何链接的 Docker 服务容器
- YAML 定义的变量用于非敏感项目配置。将敏感信息存储在受保护变量或 CI/CD secrets 中
- 手动流水线变量和计划流水线变量默认情况下不传递给下游流水线。使用
trigger:forward将这些变量转发到下游流水线 - 变量名在使用时,既可以使用
$VariableName形式,也可以使用${VariableName}形式 - 变量在全局中定义,则所有作业都可以使用;变量在作业中定义,则只能在当前作业中使用
- 如果作业中定义了全局中的变量,则作业级别变量优先
