Gitlab持续集成-(.gitlab-ci.yml)

从7.12版本开始,GitLab CI使用YAML文件(.gitlab-ci.yml)来管理项目配置。该文件存放于项目仓库的根目录,它定义该项目如何构建。

stages

stages用来定义可以被job调用的stages。stages的规范允许有灵活的多级pipelines。stages中元素的顺序决定了对应job的执行顺序:

  • 相同stage的job是并行执行的;
  • 下一个stage的job在前一个stage的job成功完成后才开始执行;
  • 如果.gitlab-ci.yml中没有定义stages,那么stages默认定义为build、test和deploy;
  • 如果一个job没有指定stage,那么这个任务会分配到test stage。

variables

variables用来定义变量,全局变量作用于所有job,也可以在指定的job中定义变量(优先级高于全局变量)
如果在job中想禁用全局定义的变量,可通过variables: {}定义一个空的哈希值。

GitLab CI/CD内置变量

variables 变量值
CI_JOB_NAME 对应的job_name
GIT_STRATEGY 指定git获取代码的方式(clone,fetch,none)

jobs

jobs用来定义了一组作业,其中必须包含script语句。

job.stage(默认:test

job中指定的stage必须是stages中存在的元素

job.tags

指定该job所允许运行的Runner,必须在注册Runner时设置Runner的tag

job.allow_failure

用于指定该job允许执行失败,则如果执行失败也不会影响下一个stage的执行。

job.script

script是job中必须指定的语句,指定Runner所要执行的命令

job.before_script、job.after_script

指定script执行前/后所执行的命令,也可定义在全局模式,则在所有job中的script执行前/后都会执行。

job.artifacts

用于指定job执行成功后,将会被发送到Gitlab中的文件,且默认情况下job之间会根据stage的优先级自动下载之前所有stage中的artifacts。

  • artifacts.paths:必选
  • artifacts.name:指定artifact的名称,同时Gitlab上下载的文件名即为artifact_name.zip
  • artifacts.when:指定artifact上传到Gitlab的条件(on_success[默认],on_failure,always)
  • artifacts.expire_in:指定artifact的过期时间(默认为30天),使用keep可永久保存

job.dependencies

dependencies用于指定在不同的job之间传递artifacts,(默认情况下当前的job都会自动下载之前stage中所有job定义的artifacts),指定dependencies: []可禁止该job下载artifacts

job.only、job.except

onlyexcept是两个参数用分支策略来限制jobs构建

  • onlyexcept可同时使用。如果在一个job配置中同时存在,则同时有效;
  • onlyexcept可以使用正则表达式;
  • onlyexcept允许使用特殊的关键字:branchestagstriggers

job.environment

environment用于定义job部署到指定的运行环境中。

  • environment.name:必选,指定environment名称
  • environment.url:可选,指定environment对应的URL,将在指定的environment页面中添加一个链接按钮指向该URL

job.when

when用于指定job执行的条件。

  • when.on_success:只有之前所有的stage成功才执行(默认);
  • when.on_failure:只有之前的stage至少有一个job失败才执行;
  • when.always:总是执行;
  • when.manual:需要手动在Gitlab Pipeline中点击play按钮才执行。manual中allow_failure默认为true

特殊的YAML特性

Hidden keys(jobs)

如果想临时disable某个job,不必注释整个job定义的行,只需在job name前加一个.即可

1
2
3
4
5
6
.compile_centos:
stage: build_centos
tags:
- centos
script:
- echo "##### build library"

Anchors

锚点可用于在文件中复制或继承配置,一般与Hidden keys(jobs)提供的job模版搭配使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
.job_template: &job_definition  #job中定义一个anchor:job_definition
image: ruby:2.1
services:
- postgres
- redis
test1:
<<: *job_definition #合并anchor:job_definition中的模版内容
script:
- test1 project
test2:
<<: *job_definition
script:
- test2 project

最终实现的效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.job_template:
image: ruby:2.1
services:
- postgres
- redis
test1:
image: ruby:2.1
services:
- postgres
- redis
script:
- test1 project
test2:
image: ruby:2.1
services:
- postgres
- redis
script:
- test2 project

Skipping jobs

如果你的commit信息中包含[ci skip]或者[skip ci],不论大小写,那么这个commit将会创建但是jobs也会跳过。


example:

实现要求:

  • 任何分支push都不会触发gitlab-ci;
  • 完成merge_requests后触发gitlab-ci,并执行编译、测试;
    编译、测试脚本由项目组编写,并存放到GITLAB_CI_SCRIPT_PATH变量定义的目录下
  • 创建tag:version标签后触发gitlab-ci,并执行编译、测试;
  • 创建tag:develop-version-flag标签后触发gitlab-ci,并执行编译、测试、上传生成包到对应的develop目录下;
    上传部署包是通过curl命令调用nexus的接口,同时根据tag名称保存到对应的环境/版本下,由于windows环境下默认不支持tar/awk/curl命令,因此需要安装对应的工具。linux、macos环境已集成在gitlab-ci.yml文件中,windows环境需要拷贝gitlab_ci_script/upload_windows.bat批处理文件到对应的目录下。另外如果同一项目同时支持多个环境(windows/linux/macos)上传的时候可以传递对应的参数,将自动上传到对应的目录下
  • 创建tag:release-version-flag标签后触发gitlab-ci,并执行编译、测试、上传生成包到对应的release目录下;
  • 打包时自动添加CHANGELOG;
    CHANGELOG打印最近50条commit记录
  • 根据编译环境选择所需的gitlab-runner
    由于同一项目可能同时支持多个环境(windows/linux/macos),若不需要某个环境则需要将对应的job删除
    若需要指定特定的runner,windows环境需要安装curl、awk、7-Zip工具,并添加相应的环境变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
##########################################################################
#
# user modify(please modify the value include example)
#
##########################################################################
variables:
#项目名称
PROJECT_NAME: example_project
#模块名称
MODULE_NAME: example_module
#生成文件路径(必须具体到文件,支持通配符)
PACKAGE_PATH: ./example_out/*
#windows环境下生成文件路径(必须具体到文件,支持通配符)
PACKAGE_PATH_WINDOWS: .\example_out\*

#打包文件名
PACKAGE_NAME: example_name
#需要缓存的文件或目录(相对路径,若需要缓存多个路径则需要指定多个变量并在job.cache.paths中引用,若不需要请删除整个job.cache)
CACHE_PATH: example_cache

#定义文件上传路径(用于打包tar.gz格式的压缩包,该目录在项目中是不存在的)
PACKAGE_UPLOAD_PATH: gitlab_ci_upload
#gitlab-ci相关执行脚本路径(文件必须存在,包含build/test/deploy,若不需要则脚本内容只写"echo stage:stage_name"命令,或注释掉对应stage的job.tags)
GITLAB_CI_SCRIPT_PATH: gitlab_ci_script
GITLAB_CI_BUILD_LINUX: ./$GITLAB_CI_SCRIPT_PATH/build_linux.sh
GITLAB_CI_TEST_LINUX: ./$GITLAB_CI_SCRIPT_PATH/test_linux.sh
GITLAB_CI_DEPLOY_LINUX: ./$GITLAB_CI_SCRIPT_PATH/deploy_linux.sh
GITLAB_CI_BUILD_MACOS: ./$GITLAB_CI_SCRIPT_PATH/build_macos.sh
GITLAB_CI_TEST_MACOS: ./$GITLAB_CI_SCRIPT_PATH/test_macos.sh
GITLAB_CI_DEPLOY_MACOS: ./$GITLAB_CI_SCRIPT_PATH/deploy_macos.sh
GITLAB_CI_BUILD_WINDOWS: .\%GITLAB_CI_SCRIPT_PATH%\build_windows.bat
GITLAB_CI_TEST_WINDOWS: .\%GITLAB_CI_SCRIPT_PATH%\test_windows.bat
GITLAB_CI_DEPLOY_WINDOWS: .\%GITLAB_CI_SCRIPT_PATH%\deploy_windows.bat
#Windows环境下上传批处理脚本(windows环境必须,且windows runner环境需安装curl、awk、7-Zip工具)
GITLAB_CI_UPLOAD_WINDOWS: .\%GITLAB_CI_SCRIPT_PATH%\upload_windows.bat

#nexus仓库地址
REPOSITORY_URL: https://nexus.yealinkops.com/repository/packages-manager
REPOSITORY_USER: devops
REPOSITORY_PASSWORD: UaW9URs9KQlYtFz3
GIT_SUBMODULE_STRATEGY: recursive


##########################################################################
#
# gitlab-ci stage
#
##########################################################################
.function: &function |
function upload() {
echo "############## Begin to execute job:upload ##############"
if [ ! -d "$PACKAGE_UPLOAD_PATH" ];then
mkdir $PACKAGE_UPLOAD_PATH
else
rm -rf $PACKAGE_UPLOAD_PATH/*
fi
git log --graph -n 50 --pretty="[%cd] - <%an> %s" > CHANGELOG.txt
cp -a $PACKAGE_PATH gitlab_ci_upload
cd $PACKAGE_UPLOAD_PATH
tar zcf ../$PACKAGE_NAME.tar.gz *

if [ -n "$CI_COMMIT_TAG" ];then
VERSION=`echo $CI_COMMIT_TAG|awk -F"-" '{print $2}'`
TAG_PREFIX=`echo $CI_COMMIT_TAG|awk -F'-' '{print $1}'`
curl -v -u $REPOSITORY_USER:$REPOSITORY_PASSWORD -T "{../$PACKAGE_NAME.tar.gz,../CHANGELOG.txt}" $REPOSITORY_URL/$PROJECT_NAME/$MODULE_NAME/$TAG_PREFIX/$VERSION/$1/
fi
echo "############## End to execute job:upload ##############"
}

# gitlab-ci执行的任务(默认包含build、test、upload、deploy,按顺序执行,任意一步失败则任务中断,不需要则需删除stage和与其相关的job)
stages:
- build
- test
- upload
- deploy

##### stage: build
#job_name(包含linux/macos/windows,若不需要某个环境则需要删除该job)
build_linux:
#job对应的stage,同一stage中的多个job并发执行
stage: build
#只有合并请求/打标签/以develop或release开头flags结尾的分支或标签才会执行job
only:
- merge_requests
- tags
- /^develop-.*flag$/
- /^release-.*flag$/
#需要缓存的文件或目录(变量中定义,不需要请删除或注释)
cache:
paths:
- $CACHE_PATH/
#job执行的命令
script:
- sh $GITLAB_CI_BUILD_LINUX
#job运行的环境
tags:
- centos7.5_231

build_macos:
stage: build
only:
- merge_requests
- tags
- /^develop-.*flag$/
- /^release-.*flag$/
cache:
paths:
- $CACHE_PATH/
script:
- sh $GITLAB_CI_BUILD_MACOS
tags:
- macos_232

build_windows:
stage: build
only:
- merge_requests
- tags
- /^develop-.*flag$/
- /^release-.*flag$/
cache:
paths:
- $CACHE_PATH/
script:
- chcp 65001
- call %GITLAB_CI_BUILD_WINDOWS%
tags:
- win10_233

#stage: test
test_linux:
stage: test
variables:
GIT_STRATEGY: none
only:
- merge_requests
- tags
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- sh $GITLAB_CI_TEST_LINUX
tags:
- centos7.5_231

test_macos:
stage: test
variables:
GIT_STRATEGY: none
only:
- merge_requests
- tags
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- sh $GITLAB_CI_TEST_MACOS
tags:
- macos_232

test_windows:
stage: test
variables:
GIT_STRATEGY: none
only:
- merge_requests
- tags
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- chcp 65001
- call %GITLAB_CI_TEST_WINDOWS%
tags:
- win10_233

#stage: upload
upload_linux:
stage: upload
variables:
GIT_STRATEGY: none
only:
- /^develop-.*flag$/
- /^release-.*flag$/
#upload函数可传递1个参数,用于多种平台时指定上传的目录,若不需要可不传递参数
script:
- *function
- upload linux
tags:
- centos7.5_231

upload_macos:
stage: upload
variables:
GIT_STRATEGY: none
only:
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- *function
- upload macos
tags:
- macos_232

upload_windows:
stage: upload
variables:
GIT_STRATEGY: none
only:
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- chcp 65001
- call %GITLAB_CI_UPLOAD_WINDOWS% windows
tags:
- win10_233

#stage: deploy
deploy_linux:
stage: deploy
variables:
GIT_STRATEGY: none
only:
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- sh $GITLAB_CI_DEPLOY_LINUX
tags:
- centos7.5_231

deploy_macos:
stage: deploy
variables:
GIT_STRATEGY: none
only:
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- sh $GITLAB_CI_DEPLOY_MACOS
tags:
- macos_232

deploy_windows:
stage: deploy
variables:
GIT_STRATEGY: none
only:
- /^develop-.*flag$/
- /^release-.*flag$/
script:
- chcp 65001
- call %GITLAB_CI_DEPLOY_WINDOWS%
tags:
- win10_233
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@echo off
echo ############## Begin to execute job:upload ##############
::<================ user modify(please modify content of script)
if exist %PACKAGE_UPLOAD_PATH% (
del /S /Q %PACKAGE_UPLOAD_PATH%\*
) else (
mkdir %PACKAGE_UPLOAD_PATH%
)
git log --graph -n 50 --pretty="[%%cd] - <%%an> %%s" > CHANGELOG.txt
copy /Y %PACKAGE_PATH_WINDOWS% gitlab_ci_upload
cd %PACKAGE_UPLOAD_PATH%
7z a ../%PACKAGE_NAME%.tar *
7z a ../%PACKAGE_NAME%.tar.gz ../%PACKAGE_NAME%.tar

for /f %%i in ('echo %CI_COMMIT_TAG% ^|awk -F"-" "{print $2}"') do set VERSION=%%i
for /f %%i in ('echo %CI_COMMIT_TAG% ^|awk -F"-" "{print $1}"') do set TAG_PREFIX=%%i
curl -v -u %REPOSITORY_USER%:%REPOSITORY_PASSWORD% -T {../%PACKAGE_NAME%.tar.gz,../CHANGELOG.txt} %REPOSITORY_URL%/%PROJECT_NAME%/%MODULE_NAME%/%TAG_PREFIX%/%VERSION%/%1/
::=============================================================>
echo ############## End to execute job:upload ##############
坚持原创技术分享,您的支持将鼓励我继续创作!
0%