.gitlab-ci.yml配置
GitLab提供持续集成服务。如果添加一个.gitlab-ci.yml文件到项目根目录,并配置GitLab项目使用某个Runner,然后每一次提交或者是推送都会触发CI pipeline。
从7.12版本开始,GitLab CI使用YAML文件 (.gitlab-ci.yml)来管理项目配置。
YAML语言
YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。
YAML 语言(发音 /ˈjæməl/ )的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。
基本语法规则
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
#表示注释,从这个字符一直到行尾,都会被解析器忽略。
YAML 支持的数据结构有三种
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
# yaml animal: pets hash: { name: Steve, foo: bar } # js # { animal: 'pets' } # { hash: { name: 'Steve', foo: 'bar' } }数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- Cat - Dog - Goldfish # JS # [ 'Cat', 'Dog', 'Goldfish' ] - - Cat - Dog - Goldfish # js # [ [ 'Cat', 'Dog', 'Goldfish' ] ] animal: [Cat, Dog] # js # { animal: [ 'Cat', 'Dog' ] }纯量(scalars):单个的、不可再分的值。有:字符串、布尔值、整数、浮点数、Null、时间、日期
number: 12.30 isSet: true parent: ~ iso8601: 2001-12-14t21:59:43.10-05:00 date: 1976-07-31 e: !!str 123 f: !!str true str: 这是一行字符串{ number: 12.30, isSet: true, parent: null, // null用~表示 iso8601: new Date('2001-12-14t21:59:43.10-05:00'), // 时间采用 ISO8601 格式 date: new Date('1976-07-31'), // 日期采用复合 iso8601 格式的年、月、日表示, e: '123', // 使用两个感叹号,强制转换数据类型。 f: 'true', // 使用两个感叹号,强制转换数据类型。 str: "这是一行字符串" // 默认不使用引号, 如果字符串之中包含空格或特殊字符,需要放在引号(单引号和双引号都可以)之中。 }
更多数据类型,可查看YAML 语言教程
.gitlab-ci.yml是什么
.gitlab-ci.yml是用来配置CI在我们的项目中做些什么工作。它位于项目的根目录。
在任何的push操作,GitLab都会寻找.gitlab-ci.yml文件,并对此次commit开始jobs,jobs的内容来源于.gitlab-ci.yml文件。
.gitlab-ci.yml
YAML文件定义了一系列带有约束说明的任务。这些任务都是以任务名开始并且至少要包含script部分:
job1:
script: "execute-script-for-job1"
job2:
script: "execute-script-for-job2"
上面这个例子就是一个最简单且带有两个独立任务的CI配置,每个任务分别执行不同的命令。
script可以直接执行系统命令(例如:./configure;make;make install)或者是直接执行脚本(test.sh)。
任务是由 Runners 接管并且由服务器中runner执行。更重要的是,每一个任务的执行过程都是独立运行的。
用下面这个例子来说明YAML语法还有更多复杂的任务:
image: ruby:2.1
services:
- postgres
before_script:
- bundle install
after_script:
- rm secrets
stages:
- build
- test
- deploy
job1:
stage: build
script:
- execute-script-for-job1
only:
- master
tags:
- docker
下面列出保留字段,这些保留字段不能被定义为job名称:
| 关键字 | 是否必须 | 描述 |
|---|---|---|
| image | 否 | 用于docker镜像,查看docker文档 |
| services | 否 | 用于docker服务,查看docker文档 |
| stages | 否 | 定义构建阶段 |
| before_script | 否 | 定义在每个job之前运行的命令 |
| after_script | 否 | 定义在每个job之后运行的命令 |
| variable | 否 | 定义构建变量 |
| cache | 否 | 定义一组文件列表,可在后续运行中使用 |
image和services
这两个关键字允许使用一个自定义的Docker镜像和一系列的服务,并且可以用于整个job周期。
before_script
用来定义所有 job 之前运行的命令,包括 deploy(部署) jobs,但是在修复 artifacts 之后。它可以是一个数组或者是多行字符串。
after_script
用来定义所有 job 之后运行的命令。它必须是一个数组或者是多行字符串。
stages
用来定义可以被 job 调用的 stages。stages 的规范允许有灵活的多级 pipelines。
stages 中的元素顺序决定了对应 job 的执行顺序:
1. 相同stage的job可以平行执行。
2. 下一个stage的job会在前一个stage的job成功后开始执行。
接下仔细看看这个例子,它包含了3个 stage:
stages:
- build
- test
- deploy
- 首先,所有
build的 jobs 都是并行执行的。 - 所有
build的 jobs 执行成功后,test的 jobs 才会开始并行执行。 - 所有
test的 jobs 执行成功,deploy的 jobs 才会开始并行执行。 - 所有的
deploy的 jobs 执行成功,commit 才会标记为success - 任何一个前置的 jobs 失败了,commit 会标记为
failed并且下一个 stages 的 jobs 都不会执行。
注:
如果
.gitlab-ci.yml中没有定义stages,那么 job's stages 会默认定义为build,test和deploy。如果一个 job 没有指定
stage,那么这个任务会分配到teststage。
variables
GItLab CI 允许在 .gitlab-ci.yml 文件中添加变量,并在 job 环境中起作用。因为这些配置是存储在git仓库中,所以最好是存储项目的非敏感配置,例如:
variables:
DATABASE_URL:"postgres://postgres@postgres/my_database"
这些变量可以被后续的命令和脚本使用。服务容器也可以使用 YAML 中定义的变量,因此我们可以很好的调控服务容器。变量也可以定义成 job level。
除了用户自定义的变量外,Runner 也可以定义它自己的变量。CI_COMMIT_REG_NAME 就是一个很好的例子,它的值表示用于构建项目的分支或 tag 名称。除了在 .gitlab-ci.yml 中设置变量外,还有可以通过 GitLab 的界面上设置私有变量。
cache
用来指定需要在 job 之间缓存的文件或目录。只能使用该项目工作空间内的路径。
从GitLab 9.0开始,pipelines和job就默认开启了缓存。
如果 cache 定义在 jobs 的作用域之外,那么它就是全局缓存,所有 jobs 都可以使用该缓存。
cache:
paths:
- binaries/
- .config
注意,缓存是在jobs之前进行共享的。如果你不同的jobs缓存不同的文件路径,必须设置不同的cache:key,否则缓存内容将被重写。
缓存key
key 指令允许我们定义缓存的作用域(亲和性),可以是所有 jobs 的单个缓存,也可以是每个 job,也可以是每个分支或者是任何你认为合适的地方。
它也可以让你很好的调整缓存,允许你设置不同 jobs 的缓存,甚至是不同分支的缓存。
cache:key 可以使用任何的预定义变量。
默认 key 是默认设置的这个项目缓存,因此默认情况下,每个 pipelines 和 jobs 中可以共享一切,从 GitLab 9.0 开始。
Jobs
.gitlab-ci.yml 允许指定无限量 jobs。每个 jobs 必须有一个唯一的名字,而且不能是上面提到的关键字。job 由一列参数来定义 jobs 的行为。
job_name:
script:
- rake spec
- coverage
stage: test
only:
- master
except:
- develop
tags:
- ruby
- postgres
allow_failure: true
| Keyword | Required | Description |
|---|---|---|
| script | yes | Runner执行的命令或脚本 |
| image | no | 所使用的docker镜像,查阅使用docker镜像 |
| services | no | 所使用的docker服务,查阅使用docker镜像 |
| stage | no | 定义job stage(默认:test) |
| variables | no | 定义job级别的变量 |
| only | no | 定义一列git分支,并为其创建job |
| except | no | 定义一列git分支,不创建job |
| tags | no | 定义一列tags,用来指定选择哪个Runner(同时Runner也要设置tags) |
| allow_failure | no | 允许job失败。失败的job不影响commit状态 |
| when | no | 定义何时开始job。可以是on_success,on_failure,always或者manual |
| dependencies | no | 定义job依赖关系,这样他们就可以互相传递artifacts |
| cache | no | 定义应在后续运行之间缓存的文件列表 |
| before_script | no | 重写一组在作业前执行的命令 |
| after_script | no | 重写一组在作业后执行的命令 |
| environment | no | 定义此作业完成部署的环境名称 |
| coverage | no | 定义给定作业的代码覆盖率设置 |
script
script 是 Runner 执行的 yaml 脚本。举个例子:
job:
script: "bundle exec rspec"
该参数也可以用数组包含多个命令:
job:
script:
- uname -a
- bundle exec rspec
有时候,script命令需要被单引号或者是双引号包裹起来。举个例子,当命令中包含冒号(:)时,script需要被包在双引号中,这样YAML解析器才可以正确解析为一个字符串而不是一个键值对(key:value)。使用这些特殊字符的时候一定要注意::,{,},[,],,,&,*,#,?,|,-,<,>,=,!。
stage
stage 允许一组 jobs 进入不同的 stages。jobs 在相同的 stage 时会 parallel 同时进行。
only and except
only 和 except 是两个参数用分支策略来限制 jobs 构建:
only定义哪些分支和标签的 git 项目将会被 job 执行。except定义哪些分支和标签的 git 项目将不会被 job 执行。
variables
在 job 中是可以使用关键字 variables 来定义 job 变量。它的运行原理跟 global-level 是一样的,但是它允许设置特殊的 job 变量。
当设置了 job 级别的关键字 variables,它会覆盖全局 YAML 和预定义中的 job 变量。想要关闭全局变量可以在 job 中设置一个空数组:
job_name:
variables: []
tags
tags 可以从允许运行此项目的所有 Runners 中选择特定的 Runners 来执行 jobs。
在注册 Runner 的过程中,我们可以设置 Runner 的标签,比如ruby,postgres,development。
tags 可通过 tags 来指定特殊的 Runners 来运行 jobs:
job:
tags:
- ruby
- postgres
上面这个示例中,需要确保构建此 job 的 Runner 必须定义了 ruby 和 postgres 这两个 tags。
allow_failure
allow_failure 可以用于当你想设置一个job失败的之后并不影响后续的CI组件的时候。失败的jobs不会影响到commit状态。
when
用于实现在失败时或即使失败也要运行的作业。
when可以设置以下值:
- on_success - 只有前面 stages 的所有工作成功时才执行。 这是默认值。
- on_failure - 当前面 stages 中任意一个jobs失败后执行。
- always - 无论前面 stages 中 jobs 状态如何都执行。
manual- 手动执行(GitLab8.10增加)。更多请查看手动操作。
enviroment
environment 用于定义 job 部署到特殊的环境中。如果指定了environment,并且没有该名称下的环境,则会自动创建新环境。
artifacts
artifacts 用于指定成功后应附加到 job 的文件和目录的列表。只能使用项目工作间内的文件或目录路径。
job:
artifacts:
paths:
- binaries/
name: "$CI_COMMIT_REF_NAME"
untracked: true
dependencies
这个功能应该与artifacts一起使用,并允许定义在不同jobs之间传递artifacts。
注意:所有之前的 stages 都是默认设置通过。
如果要使用此功能,应该在上下文的job中定义dependencies,并且列出之前都已经通过的jobs和可下载的artifacts。你只能在当前执行的stages前定义jobs。你如果在当前stages或者后续的stages中定义了jobs,它将会报错。可以通过定义一个空数组是当前job跳过下载artifacts。
pages
pages是一个特殊的job,用于将静态的内容上传到GitLab,可用于为您的网站提供服务。它有特殊的语法,因此必须满足以下两个要求:
- 任何静态内容必须放在
public/目录下 artifacts必须定义在public/目录下
下面的这个例子是将所有文件从项目根目录移动到public/目录。.public工作流是cp,并且它不会循环复制public/本身。
pages:
stage: deploy
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- master