近期因为折腾gitlab-ci,专门去翻了很多文档,想想貌似自己挺傻的。按照官网教程本来biubiubiu就弄好了,非自己折腾了好几天,还没啥积累,真是作。想想唯一能积累的就是ci的配置详解了。
该文基于最新版GitLab Community Edition 10.1.1和GitLab Runner9.5.1-1
使用.gitlab-ci.yml配置你的项目
这篇文档描述了.gitlab-ci.yml的用法,本文件是被gitlab runner用于管理你的项目任务。
如果你想要快速查看Gitlab CI的介绍,请点击这里 快速开始向导
.gitlab-ci.yml
从版本7.12开始,GitLab CI使用YAML文件(.gitlab-ci.yml)对你的项目进行配置。该文件放置在你项目的根目录下,并且包涵了你的项目如何被编译的描述语句。
YAML文件使用一系列约束叙述定义了“任务”启动时所要做的事情。“任务”被定义为具名的顶级元素,并且至少包括一条脚本语句:
job1:
script: "execute-script-for-job1"
job2:
script: "execute-script-for-job2"
上面的例子是两个在ci中能起作用的最简单的,分离的任务,每一个任务执行一条不同的命令。
当然了,一条命令会立即在克隆的仓库中执行一句语句(例如:./configure;make;make install)或者启动一个脚本(例如test.sh)
任务会被Runners拿到并在Runner的环境下被执行。重要的是,每个任务将会独立进行,与其他任务分离开来。
YAML语法允许我们使用更复杂的任务声明,例如下面的例子:
# docker镜像
image: ruby:2.1
# 依赖的docker服务
services:
- postgres
# 开始执行脚本前所需执行脚本
before_script:
- bundle install
# 脚本执行完后的钩子,执行所需脚本
after_script:
- rm secrets
# 该ci pipeline适合的场景
stages:
- build
- test
- deploy
# 定义的任务1
job1:
# 场景为构建
stage: build
# 所需执行的脚本
script:
- execute-script-for-job1
# 在哪个分支上可用
only:
- master
# 指定哪个ci runner跑该工作
tags:
- docker
以下是一些不可被用于任务名的保留字:
关键字 | 是否必须 | 描述 |
---|---|---|
image | no | 使用的docker镜像, |
services | no | 使用的docker服务, |
stages | no | 定义构建场景 |
types | no | stages的别名(不赞成使用) |
before_script | no | 定义每个任务的脚本启动前所需执行的命令 |
after_script | no | 定义每个任务的脚本执行结束后所需执行的命令 |
variables | no | 定义构建变量 |
cache | no | 定义哪些文件需要缓存,让后续执行可用 |
image and services
这两个选项允许我们指定任务运行时所需的自定义的docker镜像和服务,这两个选项的配置在以下文档中有涉及
before_script
before_script是用于定义一些在所有任务执行前所需执行的命令, 包括部署工作(但是是在job环境手动恢复之后执行)。可以接受一个数组或者多行字符串。
after_script
在GitLab 8.7引进,需要GitLab Runner v1.2以上的版本
after_script用于定义所有job执行过后需要执行的命令. 可以接受一个数组或者多行字符串。
注意: before_script和script在一个上下文中是串行执行的,after_script是独立执行的,所以根据执行器(在runner注册的时候,可以选择执行器,docker,shell,blabla...)的不同,工作树之外的变化可能不可见,例如,在before_script中执行软件的安装。
注意:你可以在任务中定义before_script,after_script,也可以将其定义为顶级元素,定义为顶级元素将为每一个任务都执行相应阶段的脚本或命令
stages
stages是用于定义场景阶段,可以被任务所使用用于定义所属场景阶段。stages的允许定义多个,灵活的场景阶段的pipline。
stages定义的元素的顺序决定了任务执行的顺序:
1.任务指定的stage名相同,该多个任务将并行执行(但是经过测试,貌似也是按照A-Z的头字母顺序顺序执行的。。只是GitLab-UI上看着是并行。。。)
2.下一个场景阶段的任务将会在前一个场景阶段的任务都完成的情况下执行
让我们来思考一下下面的例子,下面的例子定义了3个场景阶段:
stages:
- build
- test
- deploy
1.首先, 所有build场景的任务将被并行执行.
2.如果所有build场景的任务都成功了, test场景的所有任务将会并行执行.
3.如果所有test场景的任务都成功了, depoly场景的所有任务将会执行.
4.如果所有depoly场景的任务都成功了, 提交将会标记为成功.
5.如果其中某一步场景某一个任务失败了, 那么提交将会被标记为失败,并且之后的场景和任务将不会执行.
这里也有两种边缘情况值得一说:
- 如果在.gitlab-ci.yml中没有定义stages,build、test、deploy将是任务可设定的场景阶段的默认值.
- 如果一个任务没有指定场景阶段,该任务将会默认为test场景阶段,
types
不赞成使用,在未来的发行版中将会被移除,请使用stages代替
为stages的别名
variables
由GitLab Runner v0.5.0引入
GitLab CI允许你为.gitlab-ci.yml增加变量,该变量将会被设置入任务环境。这些变量是你存储在git仓库里,并且非敏感的项目配置,例如:
variables:
DATABASE_URL: "postgres://postgres@postgres/my_database"
注意:整数和字符串一样,对于设置变量名和变量值来说都是合法的。但浮点数是非法的。
这些变量在之后的所有命令和脚本中都能使用。并且YAML文件定义的变量同样会被设置到所有被用户创建的服务容器里。重要的是,变量也可以定义在一个任务级别中
job1:
variables:
STATIC_PATH: "./"
除了用户定义的变量,你的运行环境中也有一些由Runner射只的变量,其中一个例子是 CI_COMMIT_REF_NAME变量,该变量的值表示了正在构建的项目的分支或者标签名。除了用户设置的变量之外,gitlab的ui也能设置一些“秘密变量”。详细见文档【variables】
cache
注意:
- 由gitlab runner v0.7.0引入
- 在GitLab 9.2之前,缓存将会在artifacts被下载之后(artifacts详见配置详解二)被重置
- 在此之后,缓存将会在artifacts被下载之前被重置
cache用于指定一些需要在任务间进行缓存的文件和目录,你只能使用项目工作空间内的路径来指定缓存。下面是一个例子
stages:
- pre_build
- build
cache:
key: ${CI_BUILD_REF_NAME}
paths:
- node_modules/
pre_build:
stage: pre_build
script:
- npm install
在GitLab9.0以后,我们默认启用了pipelines和jobs之间的缓存共享!
如果cache定义在jobs的作用域外(就是做为顶级元素),则这意味着这个设置是全局的,所有任务都会使用该定义(使用的意思是Checking cache for default,
Successfully extracted cache。从默认缓存存储位置拉取缓存)。
缓存binaries和.config下的所有文件(我实验过了,缓存定义在job里,1个是没有用的,两个job定义了相同的缓存,他们才会从 default cache path 里被找到)
rspec:
script: test
cache:
paths:
- binaries/
- .config
缓存所有未追踪的文件:
rspec:
script: test
cache:
untracked: true
缓存binaries文件夹和所有未追踪的文件
rspec:
script: test
cache:
untracked: true
paths:
- binaries/
使用任务中的缓存重写全局设置,下面的rspec任务只会缓存binaries文件夹
cache:
paths:
- my/files
rspec:
script: test
cache:
key: rspec
paths:
- binaries/
注意,当缓存被任务共享的时候,如果你在不同任务里用了不同路径,你需要设置一个不同的缓存键值,防止缓存内容被覆盖。
缓存嗯,经过了优化,所以请不要期望缓存一直存在。更加详细的缓存实现细节,请查看GitLabRunner
cache:key
自GitLab RunnerV1.0.0被引入
key指令允许用户定义缓存的亲和性(作用域?实验过基本就是指缓存所作用的区域),key值定义的位置,可以让单个缓存适应所有的任务,也可以让单个缓存适应每一个任务,也可以让单个缓存适应每一个分支,或者是任何地方,你觉得合适的。
cache:key变量可以使用任何runner预定义的变量
从GitLab9.0开始,key的默认值是默认为整个项目,因此在默认下,所有的缓存都会被所有pipline和job共享~
注意:cache:key变量不能包含/字符
配置示例
允许job共用缓存(经过测试,如果key名称设置为job,那么不同分支不同job都适用该cache策略)
cache:
key: "$CI_JOB_NAME"
untracked: true
允许每个分支共用缓存(相同分支使用同一份缓存,实验通过):
cache:
key: "$CI_COMMIT_REF_NAME"
untracked: true
允许每个分支的每个任务共用缓存:
cache:
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
untracked: true
允许每个分支的每个阶段共用缓存
cache:
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
untracked: true
window下请用%替换¥,powershell下用$env:替换$
cache:policy
gitlab9.4引入
该项是指,一个缓存任务在执行开始前按计划下载文件的默认行为,在执行结束后按计划重新上传。这个选项允许job中造成的改变持久化,并被运用于后来的运行中。所以该项被誉为pull-push的缓存策略。(没试过,不造是啥)
如果你清楚的知道,你所执行的job不会修改已经缓存的文件夹,你可以通过在job中声明policy:pull设置跳过缓存上传过程。(通常,该设置将伴随着一个在早期做了普通缓存工作的job,以确保缓存存在,并有效)
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无条件性的重新创造了一个没有前文引用的缓存,你可以在job中使用policy: push 去跳过下载阶段
gitlab-ci配置详解(一)
gitlab-ci配置详解(二)
资料
centos7简单安装gitlab-ce/ee(官网quick start)
GitLab简明安装指南
GitLab设置stmp发件
postfix mail command not find
gitLab修改默认端口
GitLab使用已有的nginx服务
GitLab-CI与GitLab-Runner
GitLab-Runner官方文档
基于Gitlab CI搭建持续集成环境
如何汉化GitLab
非GitLab集成包手装GitLab
GitLab从安装到差点放弃