GitLab CI/CD管道配置文件.gitlab-ci.yml使用参考


.gitlab-ci.yml是GitLab CI/CD管道(Pipeline)使用的配置文件,该文件定义了管道的结构和执行顺序。本文件参考GitLab官方文档,简单翻译及整理。

  1. 介绍
  2. 配置参数
  3. 设置默认参数
  4. 详细参数
  5. 不推荐使用的参数
  6. 自定义构建目录
  7. YAML的特殊功能
  8. 触发器(Trigger
  9. 处理Git推送
  10. 跳过Job

在每个项目中,使用名为.gitlab-ci.yml的YAML文件配置GitLab CI/CD管道.gitlab-ci.yml文件定义了管道的结构和顺序,并确定:

  • GitLab Runner执行的内容
  • 遇到特定条件时所要做的操作。如:当一个过程成功或失败时

本文内容涵盖了CI/CD管道配置。其它CI/CD相关配置,请参阅:

以下是几个GitLab提供的配置管道的完整示例:

注意:如果你有一个GitLab拉取镜像的存储库,那么可能需要在“设置”>“存储库”>“从远程存储库中提取”>“触发管道更新镜像”(Settings > Repository > Pull from a remote repository > Trigger pipelines for mirror updates.)中启用管道触发。


1. 介绍

管道配置都是从作业(Job)开始的。作业是.gitlab-ci.yml文件的最基本元素。作业应该有以下特点:

  • 定义了约束,指出应在什么条件下执行它们
  • 具有任意名称的顶级元素,并且必须至少包含script子句
  • 不限制可以定义多少个

示例如下:

job1:
  script: "execute-script-for-job1"

job2:
  script: "execute-script-for-job2"

以上的示例中定义了尽可能简单的CI/CD配置两个单独的作业(job1job2),其中,每个作业的执行的命令不同。命令可以是直接执行代码(如:./configure;make;make install)或运行在存储库中脚本(如:test.sh)。

作业由会Runner提取并在Runner环境中执行。重要的是,每个作业彼此独立运行。


1.1 验证.gitlab-ci.yml

GitLab CI的每个实例都有一个称为“Lint”的嵌入式调试工具,该工具可以验证.gitlab-ci.yml文件的内容。可以在项目名称空间的ci/lint页下找到Lint。例如,https://gitlab.example.com/gitlab-org/project-123/-/ci/lint


1.2 不可用的Job名

每个作业都要有唯一的名称,但以下保留关键字能用做作业名

  • image
  • services
  • stages
  • types
  • before_script
  • after_script
  • variables
  • cache


1.3 使用保留关键字

如果使用某些特殊值(如truefalse)出现验证错误时,请尝试以下操作:

  • 引用它们
  • 将其改为其它形式,如:/bin/true


2. 配置参数

每个Job其行为由参数列表定义。以下是Job可用的参数:

关键字 说明
script 由Runner执行的Shell脚本
image 所使用的Docker镜像。也可以用:image:nameimage:entrypoint
services 使用Docker服务镜像。也可以用:services:nameservices:aliasservices:entrypointservices:command
before_script 覆盖作业之前执行的一组命令
after_script 覆盖作业之后执行的一组命令
stages 定义管道中的阶段
stage 定义一个工作阶段(默认:test
only 限制创建作业的时间。也可以用:only:refsonly:kubernetesonly:variablesonly:changes
except 限制不创建作业的时间。也可以用:except:refsexcept:kubernetesexcept:variablesexcept:changes
rules 评估和确定作业的选定属性,以及是否创建作业的条件列表。不能only/except一起使用
tags 用于选择Runner的标签列表
allow_failure 允许作业失败。失败的工作不会影响提交状态
when 什么时候执行作业。也可以用:when:manualwhen:delayed
environment 作业部署到的环境的名称。也可以用:environment:nameenvironment:urlenvironment:on_stopenvironment:action
cache 在后续运行之间应缓存的文件列表。也可以用:cache:pathscache:keycache:untrackedcache:policy
artifacts 成功时附加到作业的文件和目录列表。也可以用:artifacts:pathsartifacts:expose_asartifacts:nameartifacts:untrackedartifacts:whenartifacts:expire_inartifacts:reportsartifacts:reports:junit

在GitLab Enterprise Edition中可用:artifacts:reports:codequalityartifacts:reports:sastartifacts:reports:dependency_scanningartifacts:reports:container_scanningartifacts:reports:dastartifacts:reports:license_managementartifacts:reports:dastartifacts:reports:license_managementartifacts:reports:dastartifacts:reports:performanceartifacts:reports:metrics
dependencies 通过提供要从中获取工件(artifacts)的作业列表,限制将哪些工件传递给指定作业
coverage 指定作业的代码覆盖率设置
retry 发生故障时可自动重试作业的重试次数
timeout 定义优先于项目范围设置的自定义作业级别的超时
parallel 可并行运行作业实例数
trigger 定义下游管道触发器
include 当前作业所包括的外部YAML文件。也可以用:include:localinclude:fileinclude:templateinclude:remote
extends 该作业所要继承的配置项
pages 上传作业结果,以用于GitLab Pages
variables 在作业级别上定义的作业变量
interruptible 定义在通过新的运行(run)使其冗余时是否可以取消作业

注意:typestype参数不建议使用


3. 设置默认参数

可以使用default:关键字,将某些参数全局设置为所有Job的默认设置。然后,特定于Job的配置可以覆盖默认参数。

以下参数可以在default:块内定义:

以下示例中,将ruby:2.5镜像设置为所有Job的默认参数,而rspec 2.6Job除外,其使用ruby:2.6镜像:

default:
  image: ruby:2.5

rspec:
  script: bundle exec rspec

rspec 2.6:
  image: ruby:2.6
  script: bundle exec rspec


4. 详细参数

以下是用于配置CI/CD管道参数的详细说明。

script

是Job所需的唯一必需关键字。它是一个由Runner执行的shell脚本,例如:

job:
  script: "bundle exec rspec"

备注:有时,timeout命令需要用单引号或双引号引起来。例如,包含冒号(:)的命令就需要用引号引起来,以便YAML解析器知道将整个内容解释为字符串而不是“键: 值”对。使用特殊字符时要小心: :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, `

script的YAML锚点

在GitLab 12.5中引入

可以将YAML锚点与脚本一起使用,从而可以在多个Job中所包括的预定义命令列表。例如:

.something: &something
- echo 'something'

job_name:
  script:
    - *something
    - echo 'this is the script'


image

用于指定Job所使用的Docker镜像

示例:


image:name

扩展Docker配置选项

更多相关信息,请参阅:image有效设置

image:entrypoint

扩展Docker配置选项

更多相关信息,请参阅:image有效设置


services

用于指定服务Docker镜像,该镜像链接到image中指定的基本image


services:name

扩展Docker配置选项

更多相关信息,请参阅:services有效设置

services:alias

扩展Docker配置选项

更多相关信息,请参阅:services有效设置

services:entrypoint

扩展Docker配置选项

更多相关信息,请参阅:services有效设置

services:command

扩展Docker配置选项

更多相关信息,请参阅:services有效设置


before_scriptafter_script

GitLab 8.7中引入,且要求GitLab Runner v1.2

before_script用于定义应在所有作业,包括部署作业之前;但在在还原工件(artifacts)之后运行的命令。必须是一个数组。

after_script用于定义将在所有作业,包括失败的作业之后运行的命令。必须是一个数组。

before_script中指定的脚本:

  • 与主脚本中指定的script串联。当与script定义串联时,Job级的before_script定义将覆盖全局级的before_script定义
  • 与主script脚本一起作为一个脚本,在单个shell上下文中执行

after_script中指定的脚本:

  • 将当前工作目录重新设置为默认目录
  • 在与before_scriptscript脚本,在分开的shell上下文中执行
  • 由于上下文分开,因此无法查看由before_scriptscript脚本中定义的脚本所做的更改:
    • 在shell中。例如,script脚本中导出的命令别名和变量
    • 在工作树之外(取决于Runner执行程序)。例如,由script或code>script脚本安装的软件

如果按Job设置全局定义的before_scriptafter_script则有可能覆盖它们:

default:
  before_script:
    - global before script

job:
  before_script:
    - execute this instead of global before script
  script:
    - my command
  after_script:
    - execute this after my script


before_scriptafter_script的YAML锚点

GitLab 12.5 引入

你可以将YAML锚点before_scriptafter_script结合使用,从而可以在多个Job中包含预定义的命令列表。

示例:

.something_before: &something_before
- echo 'something before'

.something_after: &something_after
- echo 'something after'


job_name:
  before_script:
    - *something_before
  script:
    - echo 'this is the script'
  after_script:
    - *something_after


stages

stages用于定义Job可以使用的阶段,并且是全局定义的。

stages的规范允许有灵活的多阶段管道。stages中元素的顺序定义了作业执行的顺序:

  1. 同一阶段的Job并行运行
  2. 前一阶段的Jon成功完成后,运行下一阶段的Job

参考以下示例,该示例定义了3个阶段:

stages:
  - build
  - test
  - deploy
  1. 首先,所有buildJob并行执行
  2. 如果所有buildJob都并行执行成功,则testJob将并行执行
  3. 如果所有testJob都并行执行成功,则并行执行deployJob
  4. 如果所有deployJob都并行执行成功,则将提交标记为passed
  5. 如果先前的任何Job执行失败,则将提交标记为failed并且不再执行后续Job

还有两个边界情况值得注意:

  1. 如果.gitlab-ci.yml中未定义任何stages,则默认允许将buildtestdeploy用作Job的阶段
  2. 如果作业未指定stages,则为该Job分配test阶段


.pre.post

在GitLab 12.4中引入

每个管道都可以使用以下阶段:

  • .pre,它始终是管道中的第一个阶段
  • .post,它始终是管道中的最后一个阶段

用户定义的阶段都在.pre之后且.post之前执行。

即使.gitlab-ci.yml定义不正确,>.pre.post的顺序也无法更改。例如,以下配置是等效的:

  • 按顺序配置:
    stages:
      - .pre
      - a
      - b
      - .post
  • 乱序配置:
    stages:
      - a
      - .pre
      - b
      - .post
  • 未明确配置:
    stages:
      - a
      - b


stage

stage被定义为每个Job,并且依赖于全局定义的stages。它允许将Job分为不同的阶段,并且可以并行执行同一stage的Job(取决于特定条件)。例如:

stages:
  - build
  - test
  - deploy

job 0:
  stage: .pre
  script: make something useful before build stage

job 1:
  stage: build
  script: make build dependencies

job 2:
  stage: build
  script: make build artifacts

job 3:
  stage: test
  script: make test

job 4:
  stage: deploy
  script: make deploy

job 5:
  stage: .post
  script: make something useful at the end of pipeline


使用你自己的Runner

当>使用你自己的Runner,默认情况下,GitLab Runner一次仅运行一个Job(更多相关信息,请参见Runner全局设置中的concurrent标志)。

仅在以下情况下,Job会在你自己的Runner上并行运行:

  • 在不同Runner上运行
  • Runner的concurrent设置已修改


only/except (基本)

注意:这些参数将很快被弃用,以支持rules,因为它提供了更强大的语法。

onlyexcept两个参数用于设置Job策略以限制Job的创建时间:

  • only:定义要运行Job的分支和标签的名称
  • except:定义不运行Job的分支和标签的名称

以下是一些可用于作业策略的规则:

  • onlyexcept同时包括。如果Job中同时定义了onlyexcept,则引用(ref)将被onlyexcept过滤。
  • onlyexcept允许使用正则表达式(支持的正则语法
  • onlyexcept允许指定存储库路径以过滤派生Job。

此外,onlyexcept允许使用特殊关键字:

关键字 说明
branches 当管道的Git引用是分支时
tags 当管道的Git引用是标签时
api 当第二个管道API触发了管道(不是触发器API)时
external 使用GitLab以外的CI服务时
pipelines 对于多项目触发器,使用带有CI_JOB_TOKEN的API创建
pushes 管道由用户的git push触发
schedules 用于定时计划的管道
triggers 用于使用触发令牌(token)创建的管道
web 用于使用GitLab UI中的"运行管道"(Run pipeline)按钮创建的管道(在项目的Pipelines下)
merge_requests 创建或更新合并请求时(请参阅:合并请求管道)
external_pull_requests 在GitHub上创建或更新外部拉取请求时(请参阅:外部拉取请求的管道)
chat 用于使用GitLab ChatOps命令创建的Job

在以下示例中,job将只运行了以issue-开头的引用,而所有分支(branches)将被忽略:

job:
  # use regexp
  only:
    - /^issue-.*$/
  # use special keyword
  except:
    - branches

模式匹配默认情况下区分大小写。可以使用i标志修饰符,以使模式匹配不区分大小写,例如/pattern/i

job:
  # use regexp
  only:
    - /^issue-.*$/i
  # use special keyword
  except:
    - branches

以下示例中,job将仅对标签(tags)引用运行,或者通过API触发器或Pipeline Schedule显示请求构建时,Job将运行:

job:
  # use special keywords
  only:
    - tags
    - triggers
    - schedules

存储库路径仅对父存储库执行的Job可用,但不能用于派生Job:

job:
  only:
    - branches@gitlab-org/gitlab
  except:
    - master@gitlab-org/gitlab
    - /^release/.*$/@gitlab-org/gitlab

以上示例中,会为gitlab-org/gitlab上的所有分支运行job,但master和其它以release/开头的分支除外。

如果job没有only规则,则默认将设置为only: ['branches', 'tags'];如果没有except规则,则默认将为空。

例如:

job:
  script: echo 'test'

可转换为:

job:
  script: echo 'test'
  only: ['branches', 'tags']


常用表达式

因为@用于表示引用的存储库路径的开头,所以匹配正则表达式中如果包含@字符的引用名称,则需要使用十六进制字符\x40代替。

正则表达式只能匹配标签(tags)或分支(branches)名称。如果指定了存储库路径,则始终以字面量形式匹配。

如果必须使用正则表达式来匹配标签或分支名称,则模式匹配的整个引用名称部分必须是正则表达式,并且必须用/括起来(在结束符/后面附加正则表达式标志)。所以,issue-/.*/并不能匹配所有以issue-开头的标签名或分支名。

提示使用定位符^$避免正则表达式仅匹配标签名称或分支名称的子字符串。例如,/^issue-.*$/等效于/^issue-/,而仅/issue/也会匹配一个名为severe-issues的分支。


支持的only/except正则表达式语法

注意:这是GitLab 11.9.4引入的重大更改.

在GitLab 11.9.4中,GitLab开始内部将onlyexcept 参数中使用的正则表达式转换为RE2

这意味着仅支持Ruby Regexp提供的功能子集。由于计算复杂性,RE2限制了所提供的功能集,也就是说某些功能在GitLab 11.9.4中会变得不可用。

对于从11.9.7到GitLab 12.0的GitLab版本,GitLab提供了一个功能标记,管理员可以启用它,从而允许用户使用不安全的正则表达式语法。这带来了与以前允许的语法版本的兼容性,并允许用户正常迁移到新语法。

Feature.enable(:allow_unsafe_ruby_regexp)


only/except (高级)

注意:这是Alpha版功能,如有更改,恕不另行通知!

GitLab支持简单策略和复杂策略,因此可以使用数组和哈希配置方案。有四个键可用:

  • refs
  • variables
  • changes
  • kubernetes

如果在onlyexcept下使用多个键,则这些键将被视为单个联合表达式。其为:

  • only:表示“如果所有条件都匹配,则包括此Job”
  • only:表示“如果符合任何条件,则排除此Job

使用only,各个键在逻辑上由AND联接:

(任何引用) AND (任何变量) AND (任何更改) AND (如果Kubernetes是可用的)

except实现如下:

NOT((任何引用) AND (任何变量) AND (任何更改) AND (如果Kubernetes是可用的))

或者,可以更直观的用OR来表达:

(任何引用) OR (任何变量) OR (任何更改) OR (如果Kubernetes是可用的)


only:refs/except:refs

refs策略在GitLab 10.0中引入

refs策略采用与简化的only/except配置相同的值。

以下示例中,仅在master分支计划或运行管道时才创建deployJob:

deploy:
  only:
    refs:
      - master
      - schedules


only:kubernetes/except:kubernetes

kubernetes策略在GitLab 10.0中引入

kubernetes策略仅接受active关键字。

以下示例中,仅当项目中的Kubernetes服务处于活动状态时,才创建deployJob:

deploy:
  only:
    kubernetes: active


only:variables/except:variables

variables策略在GitLab 10.0中引入

variables关键字用于定义变量表达式。也就是说,你可以使用预定义变量/项目/组或环境范围的变量来定义GitLab将要评估的表达式,以决定是否应创建Job。

使用示例:

deploy:
  script: cap staging deploy
  only:
    refs:
      - branches
    variables:
      - $RELEASE == "staging"
      - $STAGING

另一个示例,根据提交消息排除Job:

end-to-end:
  script: rake test:end-to-end
  except:
    variables:
      - $CI_COMMIT_MESSAGE =~ /skip-end-to-end-tests/

更多关于变量表达式的相关信息


only:changes/except:changes

changes策略在GitLab 11.4中引入

使用changes关键字与onlyexcept,能够基于通过Git推送(push)操作事件修改的文件中定义,以确一个Job是否应被创建。

示例:

docker build:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  only:
    changes:
      - Dockerfile
      - docker/scripts/*
      - dockerfiles/**/*
      - more_scripts/*.{rb,py,sh}

在上述示例中,当将提交推送到GitLab中的现有分支时,它会创建并触发docker build作业,只要提交中包含对以下任何一项的更改:

  • Dockerfile文件
  • docker/scripts/目录中的任何文件
  • dockerfiles目录中的任何文件和子目录
  • more_scripts目录中具有rbpysh扩展名的more_scripts文件

注意:如果使用only:changes仅允许在管道成功的情况下合并合并请求,则如果不同时使用only:merge_requests,则可能导致一些异常行为。

还可以使用全局模式来匹配存储库根目录中或存储库中任何目录中的多个文件,但是它们必须用双引号括起来,否则GitLab将无法解析.gitlab-ci.yml。例如:

test:
  script: npm run test
  only:
    changes:
      - "*.json"
      - "**/*.sql"

如果在.md的根目录中检测到任何扩展名为.md文件更改,则以下示例将跳过build作业:

build:
  script: npm run build
  except:
    changes:
      - "*.md"

注意:此功能与不带合并请求管道的新分支或标签一起使用时,需要注意一些要点。


在合并请求的管道中使用only:changes

使用用于合并请求的管道,可以根据在合并请求中修改的文件来定义要创建的Job。

为了推断出源分支的正确基础SHA,建议将此关键字与only: merge_requests结合使用。这样,可以从任何进一步的提交中正确计算出文件差异,因此可以在管道中正确测试合并请求中的所有更改。

例如:

docker build service one:
  script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
  only:
    refs:
      - merge_requests
    changes:
      - Dockerfile
      - service-one/**/*

在上述情况下,如果创建或更新了合并请求,从而更改了service-one目录或Dockerfile,则GitLab会创建并触发docker build service oneJob。

请注意,如果合并请求的管道only: changeonly: change组合使用,但only: merge_requests被省略,则可能会发生有害行为。

例如:

docker build service one:
  script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
  only:
    changes:
      - Dockerfile
      - service-one/**/*

在上面示例中,管道可能由于对service-one/**/*中的文件的更改而失败。然后可以推送之后的提交,该提交不包括对该文件的任何更改,但包括对Dockerfile的更改,并且该管道可以通过,因为它仅测试对Dockerfile的更改。GitLab会检查“通过”的“最新管道”,并将合并请求显示为可合并,尽管之前的管道失败是由于尚未更正的更改引起的。

使用此配置时,必须注意检查最新的管道是否正确地纠正了先前管道的任何故障。


使用不带管道的only:changes合并请求

如果没有用于合并请求的管道,则管道会在与合并请求没有明确关联的分支或标签上运行。在这种情况下,将使用先前的SHA来计算diff,这等效于git diff HEAD~。这可能会导致某些意外行为,包括:

  • 当将新分支或新标签推送到GitLab时,该策略始终评估为true
  • 推送新提交时,将使用先前的提交作为基础SHA来计算更改的文件。


rules

在GitLab 12.3中引入

rules允许按顺序评估临时规则对象的列表,直到有一个匹配的并为Job动态提供属性。

可用规则如下:

例如,使用if,以下配置指定针对master分支的合并请求为每个管道构建并运行job,而不考虑其他的构建状态:

job:
  script: "echo Hello, Rules!"
  rules:
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
      when: always
    - if: '$VAR =~ /pattern/'
      when: manual
    - when: on_success

在此示例中,如果第一个规则:

  • 如果匹配,则将分配when: always属性
  • 如果不匹配,将依次评估第二和第三条规则,直到找到匹配项。也就是说,将为作业分配以下任一项
    • 如果第二条规则匹配,则分配when: manual属性
    • 如果第二个规则不匹配,则为when: on_success属性。由于没有条件子句,因此第三条规则始终会匹配。


rules:if

rules:ifonly:variables略有不同,它仅接受单个表达式字符串,而不接受它们的数组。应使用&&||将要求值的任何表达式集合并为一个表达式。例如:

job:
  script: "echo Hello, Rules!"
  rules:
    - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"' # This rule will be evaluated
      when: always
    - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/' # This rule will only be evaluated if the target branch is not "master"
      when: manual
    - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' # If neither of the first two match but the simple presence does, we set to "on_success" by default

如果提供的规则都不匹配,则Job将设置为when:never,并且不包含在管道中。如果在配置中根本不包含rules:when,则行为默认为job:when,其继续默认为on_success


rules:changes

changes的工作方式与only/except相同,其接受路径数组。

docker build:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  rules:
    - changes: # Will include the job and set to when:manual if any of the follow paths match a modified file.
      - Dockerfile
      when: manual
    - if: '$VAR == "string value"'
      when: manual # Will include the job and set to when:manual if the expression evaluates to true, after the `changes:` rule fails to match.
    - when: on_success # If neither of the first rules match, set to on_success

在以上示例中,job设置为:

  • 如果Dockerfile已更改或$VAR == "string value"则手动运行
  • when:on_success遵循最后一条规则,在此规则中,没有任何较早的条件为true

rules:exists

在GitLab 12.4中引入

exists接受路径数组,如果这些路径中的任何一个作为存储库中的文件存在,则将匹配。

job:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  rules:
    - exists:
      - Dockerfile

还可以使用全局模式来匹配存储库中任何目录中的多个文件。例如:

job:
  script: bundle exec rspec
  rules:
    - exists:
      - spec/**.rb

注意:出于性能原因,使用exists与模式限制为10000个检查。第10000次检查后,规则将始终匹配


复杂的规则条款

要使用AND将ifchangesexists子句结合在一起,请在同一规则中使用它们。

在以下示例中:

  • 如果Dockerfiledocker/scripts/中的任何文件已更改并且$VAR == "string value"则手动运行作业
  • 否则,作业将不包含在管道中
docker build:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  rules:
    - if: '$VAR == "string value"'
      changes: # Will include the job and set to when:manual if any of the follow paths match a modified file.
      - Dockerfile
      - docker/scripts/*
      when: manual
  # - when: never would be redundant here, this is implied any time rules are listed.

当前可用的唯一子句是:

  • if
  • changes
  • exists

例如branchesrefs当前仅可用于only/except关键字在rules中还不可用,在此情况下,它们的用法和行为会被单独考虑。


允许的属性

rules当前唯一可用属性是:

  • when
  • start_in,如果when被设置为delayed

如果when被评估为除never以外的值,则when作业将包含在管道中。

延迟作业需要一个start_in值,所以规则对象也如此。例如:

docker build:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  rules:
    - changes: # Will include the job and delay 3 hours when the Dockerfile has changed
      - Dockerfile
      when: delayed
      start_in: '3 hours'
    - when: on_success # Otherwise include the job and set to run normally


tags

tags用于从允许运行此项目的所有Runner列表中选择指定的Runner。

在注册Runner期间,可以指定Runner的标签,如:rubypostgresdevelopment

tags允许您使用已为其分配了指定标签的Runner运行Job:

tags允许使用已为其分配了指定标签的Runner运行Job:

job:
  tags:
    - ruby
    - postgres

以上示例中,会确保job由定义为rubypostgres标签的Runner构建。

标签是在不同平台上运行不同作业的好方法。如,可以指定带有osx标签的OS X Runner和带有windows标签的Windows Runner,以下作业将在各自的平台上运行:

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

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


allow_failure

allow_failure用于定义允许Job失败,而不会影响其余CI套件。手动作业除外,默认值为false

启用后,如果作业失败,该作业将在用户界面中显示橙色警告。但是,管道的逻辑流程将认为作业成功/通过(success/passed),并且不会被阻塞。

假设所有其它作业均成功,则该作业的阶段( Stages)及其管道将显示相同的橙色警告。但是,关联的提交将被标记为"通过"(passed),而不会发出警告。

在下面的示例中,job1job2会并行运行,但是如果job1失败,则不会停止下一阶段的运行,因为它标记为allow_failure: true

job1:
  stage: test
  script:
    - execute_script_that_will_fail
  allow_failure: true

job2:
  stage: test
  script:
    - execute_script_that_will_succeed

job3:
  stage: deploy
  script:
    - deploy_to_staging


when

when用于指定在发生故障或已经发生故障的情况下所要执行的作业。

when可以设置为以下值:

  1. on_success - 仅当先前阶段中的所有作业都成功(或由于标记为allow_failure而被视为成功)时才执行作业。这也是默认值。
  2. on_failure - 仅当至少一个先前阶段的作业失败时才执行作业。
  3. always - 执行作业,而不管先前阶段的作业状态如何。
  4. manual - 手动执行作业(添加于 GitLab 8.10)。相关信息参考下面的manual部分。
stages:
  - build
  - cleanup_build
  - test
  - deploy
  - cleanup

build_job:
  stage: build
  script:
    - make build

cleanup_build_job:
  stage: cleanup_build
  script:
    - cleanup build when failed
  when: on_failure

test_job:
  stage: test
  script:
    - make test

deploy_job:
  stage: deploy
  script:
    - make deploy
  when: manual

cleanup_job:
  stage: cleanup
  script:
    - cleanup after jobs
  when: always

以上脚本将:

  1. 仅当build_job失败时执行cleanup_build_job
  2. 无论是否成功,总是执行cleanup_job作为管道的最后一步。
  3. 允许从GitLab的UI手动执行deploy_job


when:manual

手动操作是一种特殊的Job,其不会自动执行,需要用户手工启动。手动操作的示例用法,是将部署到生产环境。可以从管道(Pipelines)、作业(Jobs)、环境(Environments)和部署视图手工启动。更多相关内容,请参考:环境文档

手动操作可以是可选的或阻塞的。阻塞的手动操作将在定义该操作的阶段阻止管道的执行。当有人通过单击Play按钮执行阻塞的手动Job时,可以恢复管道的执行。

当管道被阻塞时,如果设置了"管道成功时合并"(Merge When Pipeline Succeeds),则不会合并。阻塞的管道也确实有特殊状态,称为“手动”(manual)。默认情况下,手动操作是非阻塞的。如果要阻塞手动操作,则必须在.gitlab-ci.yml的作业定义中添加allow_failure: false

可选的手动操作默认情况下设置为allow_failure: true ,其状态不会对整体管道状态产生影响。因此,如果手动操作失败,则管道最终是成功的。

手动操作被视为写操作,因此当用户想要触发操作时,将使用受保护分支的权限。换句话说,为了触发分配给正在为其运行管道的分支的手动操作,用户需要有合并到该分支的能力。可以使用受保护的环境来更严格地保护手动部署,以防止未经授权的用户运行该部署。

注意:同时使用when:manualtrigger导致jobs:#{job-name} when should be on_success, on_failure or always错误,是因为when:manual阻止了使用触发器。

受保护的手动Job

可以使用受保护的环境来定义授权用户执行手动作业的精确用户列表。通过仅允许与受保护环境关联的用户触发手动作业,可以实现一些特殊用例,例如:

  • 更精确地限制可以部署到环境的人员。
  • 允许阻塞管道,直到获得相关用户“批准”为止。

为此,必须要:

  1. 为job添加environment。例如:
    deploy_prod:
      stage: deploy
      script:
        - echo "Deploy to production server"
      environment:
        name: production
        url: https://example.com
      when: manual
      only:
        - master
  2. “受保护的环境”设置中,选择环境(上例中为production),然后将被授权触发手动作业的用户,角色或组添加到“允许部署”(Allowed to Deploy)列表中。只有该列表中的人员以及始终能够使用受保护环境的GitLab管理员才能触发此手动作业。

此外,如果通过添加allow_failure: false将手动作业定义为阻塞,则直到触发手动作业后,管道的下一阶段才会运行。这可以作为一种方法,使定义的用户列表可以通过触发阻止的手动作业来“批准”(approve)后续的管道阶段。


when:delayed

在GitLab 11.4中引入

延迟的Job用于在一定时间后执行脚本。如果要避Job立即进入pending状态,此功能很有用。

可以使用start_in键设置时间段。除非提供了单位,否则start_in的值是以秒为单位的经过时间。start_in键必须小于或等于一小时。有效值的示例包括:

  • 10 seconds
  • 30 minutes
  • 1 hour

当阶段(stage)中有延迟(delayed)的作业时,直到延迟的作业完成,管道才会继续进行。这意味着此关键字也可以用于在不同阶段之间插入延迟。

上一阶段完成后,延迟作业的计时器立即启动。与其他类型的作业类似,延迟的作业计时器不会启动,除非上一个阶段已通过。

下面的示例创建一个名为timeout rollout 10%的作业,该作业在上一阶段完成后30分钟执行:

timed rollout 10%:
  stage: deploy
  script: echo 'Rolling out 10% ...'
  when: delayed
  start_in: 30 minutes

可以通过点击“取消调度”(Unschedule)按钮停止延迟工作的活动计时器。除非你手动执行该作业,否则该作业以后将永远不会执行。

可以通过单击Play按钮立即开始延迟的工作。GitLab Runner会很快选择你的Job并开始Job。


environment

environment用于定义作业部署的特定环境。如果指定了environment,但不存在该名称下的环境,则将自动创建一个新环境。

最简单的形式,可以将environment关键字定义为:

deploy to production:
  stage: deploy
  script: git push production HEAD:master
  environment:
    name: production

在上述示例中,deploy to production作业将被标记为在production环境中进行部署。


environment:name

environment的名称可以包含:

  • 字母
  • 数字
  • 空格
  • -
  • _
  • /
  • $
  • {
  • }

通用名称是qastagingproduction ,但是也可以使用任何适用于你的工作流程的名称。

除了直接在code>environment关键字之后定义环境名称之外,还可以将其定义为单独的值. 为此,请在environment下使用name关键字:
deploy to production:
  stage: deploy
  script: git push production HEAD:master
  environment:
    name: production


environment:url

这是一个可选值,设置该值时,它将在GitLab中的各个位置显示按钮,单击这些按钮会跳转到所定义的URL。

下面的示例中,如果Job成功完成,它将在合并请求和环境/部署(vironments/deployments)页面中创建按钮,这些页面将指向https://prod.example.com

deploy to production:
  stage: deploy
  script: git push production HEAD:master
  environment:
    name: production
    url: https://prod.example.com


environment:on_stop

通过在environment定义on_stop关键字,可以实现关闭(停止)环境。

请参考environment:action章节,获取相关示例。


environment:action

在GitLab 8.13中引入

action关键字与on_stop结合使用,并在调用关闭环境的Job中定义。示例如下:

review_app:
  stage: deploy
  script: make deploy-app
  environment:
    name: review
    on_stop: stop_review_app

stop_review_app:
  stage: deploy
  variables:
    GIT_STRATEGY: none
  script: make delete-app
  when: manual
  environment:
    name: review
    action: stop

上面示例中,我们设置了review_app作业以部署到review环境,并且在on_stop下定义了一个新的stop_review_app作业。一旦rreview_app作业成功完成,它将根据when下定义的内容触发stop_review_app作业。在这种情况下,我们将其设置为manual,因此需要通过GitLab的Web界面手工操作才能运行。

同样在示例中,GIT_STRATEGY设置为none,所以会在自动触发stop_review_app作业删除分支后,GitLab Runner将不会尝试检出代码。

stop_review_app作业必须定义以下关键字:

  • when - 参考
  • environment:name
  • environment:action
  • stage应该与review_app相同,以便在删除分支时自动停止环境


动态环境

示例:

deploy as review app:
  stage: deploy
  script: make deploy
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_ENVIRONMENT_SLUG.example.com/

deploy as review app作业将被标记为部署,以动态创建review/$CI_COMMIT_REF_NAME环境,其中$CI_COMMIT_REF_NAME是运行程序所设置的环境变量$CI_ENVIRONMENT_SLUG变量基于环境名称,但适合包含在URL中。这种情况下,如果deploy as review app作业在名为pow的分支中运行,则可以使用https://review-pow.example.com/之类的URL访问此环境。

当然,这意味着托管应用程序的基础服务器已正确配置。

常见的用例是为分支创建动态环境并将其用作Review Apps。可以在https://gitlab.com/gitlab-examples/review-apps-nginx/上查看使用Review Apps的简单示例。


cache

更多信息:了解缓存工作原理及一些好的做法,请参考缓存依赖项文档

cache用于指定应在Job之间缓存的文件和目录的列表。只能使用本地工作副本中的路径。

如果在Job范围之外定义了cache,则意味着它是全局设置,所有Job都将使用该定义。

cache:paths

通过paths指令选择要缓存的文件或目录。只能在$CI_PROJECT_DIR中指定路径。可以遵循使用glob模式和filepath.Match

如,将所有文件缓存在以.apk.config文件结尾的binaries中:

rspec:
  script: test
  cache:
    paths:
      - binaries/*.apk
      - .config

本地定义的缓存将覆盖全局定义的选项。以下rspec作业将仅缓存binaries/

cache:
  paths:
    - my/files

rspec:
  script: test
  cache:
    key: rspec
    paths:
      - binaries/

需要注意,由于缓存是在作业之间共享的,因此如果为不同的作业使用不同的路径,则还应该设置不同的cache:key,否则缓存内容可能会被覆盖。


cache:key

在GitLab v1.0.0中引入

由于缓存是在作业之间共享的,因此如果为不同的作业使用不同的路径,则还应该设置一个不同的cache:key,否则缓存内容可能会被覆盖。

key指令允许你定义作业之间缓存的相似性,从而允许为所有作业使用单个缓存、按作业缓存、按分支缓存或适合你工作流程的任何其他方式。这样,你可以微调缓存,从而允许你在不同作业甚至不同分支之间缓存数据。

cache:key变量可以使用任何预定义的变量,并且默认key(如果未设置)只是字面的default,这意味着从GitLab 9.0开始,默认情况下,所有内容在每个管道和作业之间共享。

注意:cache:key变量不能包含/字符,或等效的URI编码的%2F;也禁止仅由点(.%2E)组成的值。

例如,要启用每分支缓存:

cache:
  key: "$CI_COMMIT_REF_SLUG"
  paths:
    - binaries/

如果使用Windows Batch运行Shell脚本,则需要将$替换为%

cache:
  key: "%CI_COMMIT_REF_SLUG%"
  paths:
    - binaries/


cache:key:files

在GitLab v12.5中引入

如果添加了cache:key:files,则必须用它定义一个或两个文件。缓存key将是根据更改了指定文件的最新提交(一次或两次)计算得出的SHA。如果两个文件在任何提交中均未更改,则key为default

cache:
  key:
    files:
      - Gemfile.lock
      - package.json
  paths:
    - vendor/ruby
    - node_modules
cache:key:prefix

在GitLab v12.5中引入

prefix参数允许key由指定的prefixcache:key:prefix计算的SHA组合而成,从而为key:files增加了额外的功能。例如,添加rspecprefix,将使key看起来像:rspec-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5。如果两个文件在任何提交中均未更新,则前缀将添加到default,则示例中的key将是rspec-default

prefix遵循与与key相同的限制,因此它可以使用任何预定义变量。同样的,/字符或等效URI编码的%2F;也禁止仅由点(.%2E)组成的值,是不允许的。

cache:
  key:
    files:
      - Gemfile.lock
    prefix: ${CI_JOB_NAME}
  paths:
    - vendor/ruby


cache:untracked

设置cache:untracked将缓存Git存储库中所有未跟踪的文件:

rspec:
  script: test
  cache:
    untracked: true

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

rspec:
  script: test
  cache:
    untracked: true
    paths:
      - binaries/


cache:policy

在GitLab v9.4中引入

缓存Job的默认是在执行开始时下载文件,并在结束时重新上传文件。这样可以将Job所做的任何更改保留下来,以备将来运行,这被称为pull-push缓存策略。

如果你确认该Job不会更改缓存的文件,则可以通过设置policy: pull来跳过上传步骤。通常,这会在早期阶段与普通的缓存作业结合在一起,以确保不时更新缓存:

stages:
  - setup
  - test

prepare:
  stage: setup
  cache:
    key: gems
    paths:
      - vendor/bundle
  script:
    - bundle install --deployment

rspec:
  stage: test
  cache:
    key: gems
    paths:
      - vendor/bundle
    policy: pull
  script:
    - bundle exec rspec ...

这有助于加快Job的执行速度并减少缓存服务器上的负载,尤其是有大量并行使用缓存的作业时。

此外,如果有一项Job可以无条件地重新创建缓存而不参考其先前的内容,则可以使用policy: push设置该Job跳过下载步骤。


artifacts

artifacts用于指定文件\目录的列表,这些文件应在成功(succeed)、失败(fail)或总是(always)时附加到Job

Job完成后,工件(artifacts)将被发送到GitLab,并可在GitLab UI中下载



artifacts:paths



artifacts:expose_as



artifacts:name

artifacts:untracked

artifacts:when

artifacts:expire_in

artifacts:reports

artifacts:reports:junit
artifacts:reports:codequality
artifacts:reports:sast
artifacts:reports:dependency_scanning
artifacts:reports:container_scanning
artifacts:reports:dast
artifacts:reports:license_management
artifacts:reports:performance
artifacts:reports:metrics

dependencies

当依赖的Job执行失败

needs

要求和限制

coverage

retry

timeout

parallel

trigger

简单的trigger语法

复杂的trigger语法

interruptible

include

include:local

include:file

include:template

include:remote

嵌套包含(include)

include示例

单个字符串或多个值的数组
重用before_script模版
覆盖外部模板值
使用嵌套包含

extends

同时使用extendsinclude

pages

variables

Git策略(strategy)

Git子模块策略

Git 检出(checkout)

Git 清除(clean)标志

Job 阶段尝试

浅克隆



5. 不推荐使用的参数

5.1 全局定义的types

5.2 Job定义的type

5.3 全局定义的imageservicescachebefore_scriptafter_script



6. 自定义构建目录

6.1 处理并发

6.2 嵌套路径



7. YAML的特殊功能

7.1 隐藏 Key (Job)

7.2 锚点



8. 触发器(Trigger)



9. 处理Git推送



10. 跳过Job