Gitlab CI 使用高级技巧
通过 iOS 使用 gitlab 自动打包 我们了解到了 Gitlab 的自动化打包的简单配置。但是现在有个问题。每次提交代码都会去自动打包一遍。很多时候这不是我们想要的效果。那么 Gitlab CI 有没有其他的打包方式呢?比如按需要触发,定时触发 build 等。答案是有的。具体的操作需要了解 YML。
Gitlab YAML 详解
Gitlab 中 YAML 相关关键字与概念解析
概念
- Job
YAML 文件使用一系列约束叙述定义了 Job 启动时所要做的事情。Job 被定义为具名的顶级元素,并且至少包括一条脚本语句。Job 被 Runner 拿到并在 Runner 的环境下执行。重要的是,每个 Job 都会与其他 Job 分离开来,独立进行。如:
job1:
script: "execute-script-for-job1"
job2:
script: "execute-script-for-job2"
上面的例子是两个在ci中能起作用的最简单的,分离的任务,每一个任务执行一条不同的命令。每条命令都会被Runners拿到并在Runner的环境下被执行。重要的是,每个任务将会独立进行,与其他任务分离开来。
关键字
- 不可以被用于 Job名 的保留字
关键字 | 是否必须 | 描述 |
image | no | 使用的docker镜像。详见 |
services | no | 使用的docker服务。详见 |
stages | no | 定义构建场景 |
types | no | stages的别名(不赞成使用) |
before_script | no | 定义每个任务的脚本启动前所需执行的命令 |
after_script | no | 定义每个任务的脚本执行结束后所需执行的命令 |
variables | no | 定义构建变量 |
cache | no | 定义哪些文件需要缓存,让后续执行可用 |
- Job 的保留字
关键字 | 是否必须 | 描述 |
script | yes | Runner执行的命令或脚本。可以包含多条命令 |
image | no | 使用的docker镜像。详见 |
services | no | 使用的docker服务。详见 |
stage | no | 定义job stage(默认:test) |
type | no | stage的别名(已弃用) |
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 | 定义给定作业的代码覆盖率设置 |
- only and except 保留字
关键字 | 描述 |
branches | 当一个分支被push上来 |
tags | 当一个打了tag的分支被push上来 |
api | 当一个pipline被piplines api所触发调起,详见piplines api |
external | 当使用了GitLab以外的CI服务 |
pipelines | 针对多项目触发器而言,当使用CI_JOB_TOKEN并使用gitlab所提供的api创建多个pipelines的时候 |
pushes | 当pipeline被用户的git push操作所触发的时候 |
schedules | 针对预定好的pipline而言(每日构建一类) |
triggers | 用token创建piplines的时候 |
web | 在GitLab页面上Pipelines标签页下,你按了run pipline的时候 |
重要的关键字解析
- after_script
before_script
和script
在一个上下文中是串行执行的,after_script
是独立执行的。所以根据执行器(在runner注册的时候,可以选择执行器,docker,shell 等)的不同,工作树之外的变化可能不可见,例如,在before_script中执行软件的安装。
你可以在任务中定义before_script
,after_script
,也可以将其定义为顶级元素,定义为顶级元素将为每一个任务都执行相应阶段的脚本或命令。 - stages
stages的允许定义多个,灵活的场景阶段的pipline。定义的元素的顺序决定了任务执行的顺序。例如:
stages:
- build
- test
- deploy
- build场景的任务将被并行执行。test、deploy 同理
- build 任务成功后,test 执行。test 成功后,deploy 执行
- 所有的都成功了,提交将会标记为成功
- 任何一步任务失败了,提交标记为失败并之后的场景,任务都不回执行。
- variables
GitLab CI允许你为.gitlab-ci.yml增加变量,该变量将会被设置入任务环境。这些变量是你存储在git仓库里,并且非敏感的项目配置,例如:
variables:
DATABASE_URL: "postgres://postgres@postgres/my_database"
# 注意:整数和字符串一样,对于设置变量名和变量值来说都是合法的。但浮点数是非法的。
详见此处
- script
script是一段由Runner执行的shell脚本,例如:
job:
script: "bundle exec rspec"
这个参数也可以使用数组包涵好几条命令:
job:
script:
- uname -a
- bundle exec rspec
注意:有些时候,script命令需要被单引号或者双引号所包裹。例如:当命令中包涵冒号的时候,该命令需要被引号所包裹。这样YAML解析器才知道该命令语句不是“key: value”语法的一部分。当命令中包涵以下字符时需要注意打引号:`: { } [ ] , & * # ? | - < > = ! % @ ``
- only and except
only和except两个参数说明了job什么时候将会被创建:
- only定义了job需要执行的所在分支或者标签
- except定义了job不会执行的所在分支或者标签
以下是这两个参数的几条用法规则:
- only和except如果都存在在一个job声明中,则所需引用将会被only和except所定义的分支过滤.
- only和except允许使用正则
- only和except允许使用指定仓库地址,但是不forks仓库
例子解析:
- job将会只在issue-开头的refs下执行,反之则其他所有分支被跳过:
job:
# use regexp
only:
- /^issue-.*$/
# use special keyword
except:
- branches
- job只会在打了tag的分支,或者被api所触发,或者每日构建任务上运行,
job:
# use special keywords
only:
- tags # tag 分支 commit 之后触发
- triggers # API 触发
- schedules # 每日构建触发
- job将会在父仓库gitlab-org/gitlab-ce的非master分支有提交时运行。
job:
only:
- branches@gitlab-org/gitlab-ce
except:
- master@gitlab-org/gitlab-ce
- 在计划被触发时或者master分支被push时触发,并且先决条件是kubernetes服务是活跃的(你启用了kubernetes服务作为执行器,相关请看gitlab ci runner的文档,ce用户一般用求不到)
job:
only:
refs:
- master
- schedules
kubernetes: active
- artifacts
artifacts 被用于在 job 作业成功后将制定列表里的文件或文件夹附加到 job 上,传递给下一个 job ,如果要在两个 job 之间传递 artifacts,你必须设置dependencies,下面有几个例子
- 传递所有binaries和.config:
artifacts:
paths:
- binaries/
- .config
- 传递所有git没有追踪的文件
artifacts:
untracked: true
- 传递binaries文件夹里所有内容和git没有追踪的文件
artifacts:
untracked: true
paths:
- binaries/
- 禁止传递来的artifact:
job:
stage: build
script: make build
dependencies: []
- 只为打tags的行为创建artifacts。artifacts将会在job执行完毕后送到GitLab ui前台来,你可以直接下载它(tag、details、pipeline 的下载按钮上都会出现)。
default-job:
script:
- mvn test -U
except:
- tags
release-job:
script:
- mvn package -U
artifacts:
paths:
- target/*.war
only:
- tags
artifacts:name
name指令允许你对artifacts压缩包重命名,你可以为每个artifect压缩包都指定一个特别的名字,这样对你在gitlab上下载artifect的压缩包有用
job:
artifacts:
name: "$CI_JOB_NAME"
artifacts:when
用于job失败或者未失败时使用。artifacts:when能设置以下值:
- on_success 这个值是默认的,当job成功时上传artifacts
- on_failure 当job执行失败时,上传artifacts
- always 不管失败与否,都上传
job:
artifacts:
when: on_failure #当失败时上传artifacts
artifacts:expire_in
artifacts:expire_in 用于设置 artifacts 上传包的失效时间. 如果不设置,artifacts 的打包是永远存在于 gitlab上 的。当指定 artifacts 过期时间的时候, 在该期间内,artifacts 包将储存在 gitLab 上。并且你可以在 job 页面找到一个 keep 按钮,按了以后可以覆盖过期时间,让 artifacts 永远存在。过期之后,用户将无法访问到 artifacts 包。时间的例子如下:
- '3 mins 4 sec'
- '2 hrs 20 min'
- '2h20min'
- '6 mos 1 day'
- '47 yrs 6 mos and 4d'
- '3 weeks and 2 days'
job:
artifacts:
expire_in: 1 week # 一周后过期
- Triggers
Triggers被用于重建特定分支,tag或者commit,他是api触发的。详见
其他关键字我没有用到因此也就没有继续研究了。
根据自己的需求进行 build 的设置
首先,设置 triggers。
trigger_setting_click.png
trigger_setting_click2.png
编写 YAML,这是为 triggers 触发:
tiggers.png
使用以下代码触发 build 。
curl -X POST -F token=你的token -F ref=你的Branch名称 https://your.gitlab.address/api/v4/projects/160/trigger/pipeline
参考文章
- Gialab YMAL 原文地址
- gitlab-ci配置详解(一)
- gitlab-ci配置详解(二)
- Gitlab CI yaml官方配置文件翻译