简单介绍gitlab-ci/cd的使用
官方文档: GitLab CI/CD
没有比官方文档更好不过的教程了!
gitlab-ci如何运行?
gitlab-ci
并不是平白无故运行起来的,依托于一个叫做GitLab Runner 的东西,我们配置的gitlab-ci 才会顺利的运行。
如果你对Install GitLab Runner 感兴趣,可以参看文档,gitlab-runner是如何安装的。
ci/cd
的运行 至少需要一个gitlab-runner
。当然也可以配置多个,比如您可以在macos
系统上安装gitlab-runner
并注册到gitlab
中,这样您就可以将类似ios打包的过程放到这个runner上了。以此类推,如果您有特殊要求的ci/cd,可以指定特殊的runner。
ci/cd运行过程:
gitlab
按照您项目中的的gitlab-ci.yaml
配置,创建一个或多个job,然后等待gitlab-runner运行这些job。
大概的过程类似于:
-
选择一个执行器
也就是执行命令等操作的环境,需要gitlab-runner
中配置。例如shell
也就是在gitlab-runner
主机上运行。docker
就是拉取某个镜像,在镜像中执行命令。
下文的runner的执行器均为docker
-
拉取源码
-
重建缓存
如果当前job
或者流水线有配置缓存,会拉取缓存。(下文详细说)
-
下载artifacts
如果当前job的上游有配置artifacts
,会下载artifacts
(下文详细说)
-
执行命令
执行您的scripts
顾名思义,流水线 ,也就是定义整个流程需要完成哪些阶段,每个阶段需要做什么。
以下为官方示例为例:
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
|
stages: # 阶段
- build
- test
- deploy
image: alpine
# 作业
build_a:
stage: build
script:
- echo "This job builds something."
build_b:
stage: build
script:
- echo "This job builds something else."
test_a:
stage: test
script:
- echo "This job tests something. It will only run when all jobs in the"
- echo "build stage are complete."
test_b:
stage: test
script:
- echo "This job tests something else. It will only run when all jobs in the"
- echo "build stage are complete too. It will start at about the same time as test_a."
deploy_a:
stage: deploy
script:
- echo "This job deploys something. It will only run when all jobs in the"
- echo "test stage complete."
deploy_b:
stage: deploy
script:
- echo "This job deploys something else. It will only run when all jobs in the"
- echo "test stage complete. It will start at about the same time as deploy_a."
|
对于更多内容,可参考官方文档
作业才是流水线每个阶段实际执行的内容,每个作业都应该定义在顶级,并且拥有至少一个script
。
您可以理解为流水线的工人
以官方文档为例:
1
2
3
4
5
|
job1: # 作业的名称
script: "execute-script-for-job1" # 作业执行的脚本
job2: # 作业的名称
script: "execute-script-for-job2" # 作业执行的脚本
|
作业定义的数量不受限制,每个作业都是独立的单独运行。
⚠️ 每个作业都是单独,独立运行。所以,即使在同一个流水线中 也就是在一次ci/cd
中。每个作业运行的runner
都可能是不同的。
例如:你在runner1 上拉取了依赖,你在runner2上编译了代码,你在runner3上发送了一个通知。
那么,如果在deploy
时想使用上一个阶段编译出来的文件该如何操作呢?
Artifacts 制品,可以理解为作业产出的内容(上个流水线工人产出的内容)
简单以下面这个为例:
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
|
stages:
- install
- build
- deploy
install-online:
stage: install
image: tool/yarn:v1
script:
- yarn install
- yarn build:prod
# 将yarn build 打包出来的dist 作为制品,传到下一个job
artifacts:
paths:
- dist/
# 默认情况下,后面阶段的作业会自动下载由前面阶段的作业创建的所有制品。
build-online-image:
stage: build
image: tool/docker:latest
only:
- master
script:
- docker build -t $ONLIE_IMAGE_NAME .
- docker push $ONLIE_IMAGE_NAME
- docker tag $ONLIE_IMAGE_NAME $IMAGE
- docker push $IMAGE
deploy-online:
stage: deploy
image: kubematrix/cli:v1
# 如果您不需要依赖任何的制品,你可以使用dependencies: []
dependencies: []
only:
- master
script:
- matrix workloads deploy
|
在install
时安装依赖并打包出一个dist
文件夹,使用artifacts
将这个文件夹打包出来。
在install
执行完成后,build
阶段时会自动下载之前的artifacts
也就是dist
文件夹,完成了将上个阶段编译出来的文件带到下个阶段的操作。
dependencies 依赖 可参考官方文档,
Cache 缓存
以php为例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#
# https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
#
image: php:7.2
# Cache libraries in between jobs
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- vendor/
before_script:
# Install and run Composer
- curl --show-error --silent "https://getcomposer.org/installer" | php
- php composer.phar install
test:
script:
- vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never
|
以$CI_COMMIT_REF_SLUG
(预定义变量,这里是指分支的名称)为key, 将vendor/
目录缓存下来。
缓存下来 以后的每一次作业,都会下载缓存,这样会加速composer install
的速度
⚠️需要注意的点:
配置阿里云OSS存储cache文件
Advanced configuration | GitLab
为了统一缓存,我们需要使用OSS
首先进入gitlab-runner
对应的主机,gitlab-runner list
查看配置文件存放的位置
/etc/gitlab-runner/config.toml
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
|
[[runners]]
name = "cloud5"
url = "https://gitlab.xxx.cn/"
token = "token"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
Type = "s3"
Shared = true
Path = "xxx"
[runners.cache.s3]
ServerAddress = "oss-cn-hangzhou.aliyuncs.com"
AccessKey = "key"
SecretKey = "sec"
BucketName = "gitlab-runner-cached"
BucketLocation = "oss-cn-hangzhou"
[runners.docker]
tls_verify = false
image = "ruby:2.6"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/root/.docker/:/root/.docker/", "/data/gitlab-runner/cache:/cache", "/data/gitlab-runner/npm-cache:/root/.npm", "/data/gitlab-runner/composer-cache:/root/.composer"]
shm_size = 0
pull_policy = "if-not-present"
|
主要内容为以下:
1
2
3
4
5
6
7
8
9
10
|
[runners.cache]
Type = "s3" # 缓存类型
Shared = true # 缓存在多个runner之间共享
Path = "xxx" # 缓存路径前缀,如果一个gitlab-runner在多个gitlab中注册,可以使用前缀的方式做区分
[runners.cache.s3]
ServerAddress = "oss-cn-hangzhou.aliyuncs.com" # oss地址
AccessKey = "key" # key
SecretKey = "sec" # secret
BucketName = "gitlab-runner-cached" # bucketName
BucketLocation = "oss-cn-hangzhou" # BucketLocation
|
以此类推,你需要在所有的gitlab-runner中配置此缓存,这样所有的缓存都会被上传到阿里云的OSS中,无论你的job运行在哪个runner中。
示例:
以一个前端项目为例:
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
|
# 定义
variables:
ONLIE_IMAGE_NAME: registry.cn-hangzhou.aliyuncs.com/$CI_PROJECT_NAME:$CI_COMMIT_SHORT_SHA
stages:
- preInstall
- install
- build
- deploy
build-image:
stage: build
image: docker
only:
- test
script:
- docker build -t $IMAGE .
- docker push $IMAGE
# ---------------------------------- master ----------------------------------
# 只有当package.json变化时才会重新install
preInstall-job:
stage: preInstall
image: yarn:v1
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
- yarn.lock
# 只需要推送缓存,不需要拉取缓存
policy: push
only:
refs:
- master
changes:
- package.json
script:
- yarn install
install-online:
stage: install
image: yarn:v1
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
- yarn.lock
# 只需要拉取缓存,不需要推送缓存
policy: pull
only:
- master
script:
# 当缓存存在时不需要install
- if [ ! -d "./node_modules/" ];then yarn install; else ls -alh; fi
- yarn build:prod
# 打包制品给后面的job
artifacts:
paths:
- dist/
build-online-image:
stage: build
# 使用docker镜像
image: docker:latest
# 只在master分支变动时运行这个job
only:
- master
script:
- docker build -t $ONLIE_IMAGE_NAME . # 构建镜像
- docker push $ONLIE_IMAGE_NAME # 推送镜像
deploy-online:
stage: deploy
# 使用kubematrix-cli镜像
image: kubematrix/cli:v1
# 依赖为空,表示不需要任何的依赖
dependencies: []
only:
- master
script:
- matrix workloads deploy
|
示例讲解
-
GitLab CI/CD variables | GitLab 变量
可以在文档Predefined variables reference | GitLab 中查看预定义的变量
首先定义变量 ONLIE_IMAGE_NAME 以供使用
-
定义stages 流水线阶段
定义了4个阶段,preInstall,install,build,deploy,下面的job将按照关联的stag顺序执行
-
定义job
stag
定义了job对应的阶段。
image
:定义了执行脚本所使用的docker镜像。
only : 定义了job只在某些情况下执行。默认为only.refs
输入分支名,或与分支相匹配的正则表达式。only.changes
检测只在某些文件变动时运行。
cache
: 定义了改job使用缓存,cache.policy
缓存规则,默认为pull-push
开始job
前拉取缓存,job
成功后推送缓存。 可修改为push
只推送,不拉取。pull
只拉取,不推送
artifacts
: 定义了需要打包的制品,给后面的job使用
dependencies
: 需要的依赖,如果上面的job有artifacts
会默认下载,如果不需要artifacts
可将这个属性定义为空数组