.gitlab-ci.yml 配置
GitLab 内置持续集成能力。在项目根目录添加 .gitlab-ci.yml,同时项目配置可用的 GitLab Runner,代码每一次提交、推送就会自动触发 CI Pipeline。
从 GitLab 7.12 版本开始,GitLab CI 采用 YAML 格式文件 .gitlab-ci.yml 做流水线配置。
YAML 语言基础
YAML 是面向配置文件的序列化语言,读写对人友好,比 JSON 更适合编写配置。发音 /ˈjæməl/。
基础语法规则
- 大小写敏感
- 使用空格缩进表达层级关系,禁止使用 Tab
- 相同层级左侧对齐即可,缩进空格数量无强制要求
#为行注释,#到行末尾全部作为注释内容
YAML 三种数据结构
对象(映射、哈希、字典)
键值对形式,冒号后面必须带空格;也支持行内简写格式。
# 普通写法
animal: pets
# 行内对象
hash: { name: Steve, foo: bar }
对应 JS 对象:
{ animal: 'pets' }
{ hash: { name: 'Steve', foo: 'bar' } }
数组(序列、列表)
使用 -(减号 + 空格)表示数组每一项;同样支持行内简写。
# 普通数组
- Cat
- Dog
- Goldfish
# 嵌套数组
-
- Cat
- Dog
- Goldfish
# 行内数组
animal: [Cat, Dog]
对应 JS:
[ 'Cat', 'Dog', 'Goldfish' ]
[ [ 'Cat', 'Dog', 'Goldfish' ] ]
{ animal: [ 'Cat', 'Dog' ] }
纯量 scalar
不可拆分基础值:字符串、布尔、整数、浮点数、null、日期、时间。
number: 12.30
isSet: true
parent: ~ # ~ 代表 null
iso8601: 2001-12-14T21:59:43.10-05:00
date: 1976-07-31
e: !!str 123 # !!str 强制转为字符串
f: !!str true
str: 这是一行字符串
转换为 JS:
{
number: 12.30,
isSet: true,
parent: null,
iso8601: new Date('2001-12-14T21:59:43.10-05:00'),
date: new Date('1976-07-31'),
e: '123',
f: 'true',
str: "这是一行字符串"
}
注意:字符串默认不用引号;包含特殊字符、: {} [] 等符号时,建议用单引号、双引号包裹。
.gitlab-ci.yml 简介
.gitlab-ci.yml 存放在项目仓库根目录,用来定义 CI 流水线要执行的工作。每次执行 git push,GitLab 都会读取该配置文件,根据配置创建若干 Job,交给 Runner 执行。
配置由多个 Job 组成,每个 Job 以任务名称开头,至少必须包含 script 字段。
最简示例:
job1:
script: "execute-script-for-job1"
job2:
script: "execute-script-for-job2"
script:执行 shell 命令,可以是多条系统命令,也可以调用本地脚本文件。- Job 由 Runner 调度执行,每个 Job 的运行环境相互独立。
一份完整参考配置示例(ruby:2.1 已停更,请换成项目实际镜像;默认分支若是 main 把 master 改掉):
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 镜像 |
| services | 否 | 配套 Docker 服务 |
| stages | 否 | 定义流水线全部阶段,决定 Job 执行顺序 |
| before_script | 否 | 所有 Job 执行之前运行的命令 |
| after_script | 否 | 所有 Job 执行之后运行的命令 |
| variables | 否 | 全局流水线环境变量 |
| cache | 否 | 跨 Job 缓存文件、目录 |
image、services
全局指定 Job 使用的 Docker 镜像与附属服务容器,整个流水线所有 Job 默认继承。
before_script
在每一个 Job 执行前运行命令,会在恢复 artifacts 之后执行;支持数组、多行字符串格式。
after_script
每一个 Job 结束之后执行的命令;支持数组、多行字符串格式。无论 Job 成功失败都会执行。
stages 流水线阶段
stages 定义流水线的阶段列表,列表顺序就是执行顺序:
- 同一个 stage 下所有 Job 并行执行
- 上一 stage 的全部 Job 成功,才会执行下一 stage
- 任意一个 Job 失败,流水线标记失败,后续 stage 不再执行
stages:
- build
- test
- deploy
执行流程:
- build 阶段全部 Job 并行运行
- build 全部成功 → 执行 test 阶段所有 Job
- test 全部成功 → 执行 deploy 阶段所有 Job
- deploy 全部成功,流水线整体标记成功
- 任意 Job 失败,流水线失败,终止后续阶段
注意:
- 不写
stages,默认内置三个阶段:build、test、deploy。 - Job 如果没有写
stage,默认归属到test阶段。
variables 全局变量
在配置文件中定义环境变量,作用于全部 Job,适合存放非敏感配置。密码、密钥不要写在仓库配置文件,请到 GitLab 项目页面配置受保护的 CI 变量。
variables:
DATABASE_URL: "postgres://postgres@postgres/my_database"
- 变量可以被脚本、服务容器读取;
- Job 内部也可以定义局部变量,局部变量会覆盖全局;
- GitLab 会内置大量预定义 CI 变量,如
CI_COMMIT_REF_NAME获取当前分支、标签名。
cache 缓存
跨 Job 之间复用文件、目录,减少重复下载编译。
写在顶层为全局缓存,所有 Job 共享。
cache:
paths:
- binaries/
- .config
注意:多个 Job 如果缓存不同文件,必须设置不同 cache:key,否则缓存会互相覆盖。cache:key 支持使用 CI 预定义变量,实现按分支、按项目隔离缓存。
Job 任务配置
一个流水线可以定义任意数量 Job。Job 名字不能是上面的保留关键字,每个 Job 通过一系列关键字控制行为。
job_name:
script:
- rake spec
- coverage
stage: test
only:
- master
except:
- develop
tags:
- ruby
- postgres
allow_failure: true
| 关键字 | 是否必填 | 说明 |
|---|---|---|
| script | ✅ 是 | Runner 执行的命令、脚本 |
| image | 否 | Job 单独指定 docker 镜像,覆盖全局 image |
| services | 否 | Job 单独指定 docker 服务 |
| stage | 否 | 归属流水线阶段,默认 test |
| variables | 否 | Job 局部变量,覆盖全局变量 |
| only | 否 | 指定哪些分支、标签触发该 Job(现行更推荐 rules) |
| except | 否 | 指定哪些分支、标签不触发该 Job(现行更推荐 rules) |
| tags | 否 | 筛选具备对应标签的 Runner 执行此 Job |
| allow_failure | 否 | 允许 Job 失败;失败不影响整体流水线状态 |
| when | 否 | Job 触发时机:on_success、on_failure、always、manual |
| dependencies | 否 | 控制跨 Job 下载 artifacts |
| cache | 否 | Job 级别缓存,覆盖全局 cache |
| before_script | 否 | 覆盖全局,当前 Job 前置命令 |
| after_script | 否 | 覆盖全局,当前 Job 后置命令 |
| environment | 否 | 定义部署环境名称 |
| coverage | 否 | 代码覆盖率匹配规则 |
script
Job 的核心,Runner 执行脚本命令。支持多条命令数组。
特殊提醒:命令中包含
:{}[]&*#!等 YAML 特殊符号,整条命令要用引号包裹,避免 YAML 解析出错。
job:
script:
- uname -a
- bundle exec rspec
stage
把 Job 归属到某个流水线阶段;同一个 stage 的 Job 并行运行。
only、except
控制 Job 在哪些分支、tag 下执行。现行 GitLab 更推荐用 rules 组合分支、路径等条件;only、except 仍能用。
only:匹配的分支、tag 才运行 Jobexcept:匹配的分支、tag 跳过该 Job
variables(Job 级别)
局部变量优先级高于全局 variables。可以设置空数组 variables: [] 关闭继承全部全局变量。
job_name:
variables: []
tags
用来筛选 Runner。Runner 在注册的时候会打上标签,Job 的 tags 必须和 Runner 的标签完全匹配,Runner 才会接手该任务。
job:
tags:
- ruby
- postgres
allow_failure
设置为 true 时,该 Job 即便运行失败,不会让整个流水线变成失败状态,不阻塞后续阶段。
when
控制 Job 在什么条件下运行:
on_success:默认,前面全部阶段 Job 成功才执行on_failure:前面流水线出现失败才执行always:无论前面成功失败,都执行manual:手动触发,需要在页面点击按钮才运行 Job
artifacts 产物
Job 运行结束后,把指定文件、目录作为产物保存到 GitLab,可以被下游 Job 下载获取。
job:
artifacts:
paths:
- binaries/
name: "$CI_COMMIT_REF_NAME"
untracked: true
dependencies
配合 artifacts 使用,指定从哪些前置 Job 下载产物。只能引用前面阶段的 Job。设置空数组 dependencies: [],代表不下载任何上游产物。
pages 部署静态站点
pages 是 GitLab CI 的特殊 Job,用来部署静态网页到 GitLab Pages。有两条硬性约束:
- 静态资源必须输出到
public/目录 artifacts必须声明public路径
pages:
stage: deploy
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- master