gitlab--workflow、rules
workflow
workflow 关键字适用于整个管道,并将确定是否创建管道。 :可以设置为always
或never
. 如果未提供,则默认值always
- if:定义变量条件
- when:只有两个值,always 和 nevel
|
合并请求时运行流水线 |
|
提交代码运行流水线 |
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "push"' # 当为 push 的时候才会触发,其他情况下不会触发该流水线
when: never # 上面的条件为 true 时,永远不执行
- when: always # 上面的条件为 false 时,永远执行
stages: # 指定运行的步骤,没有指定就顺序执行
- build
- deploy
- test
- rebase
build1: # job 的名称
tags:
- k8s # 指定运行的 runner 标签
stage: build # stage 的名称
script:
- echo "Do your build here"
test1:
stage: test
script:
- echo "Do a test here"
- echo "For example run a test suite"
rebase:
stage: rebase
script:
- echo "Do another parallel test here"
- echo "For example run a lint test"
deploy1:
tags:
- k8s
stage: deploy
script:
- echo "Do your deploy here"
当上面执行 push 操作时,才会运行流水线,否则不会运行流水线
rules
rules 可以按照设置的规则来判断是否执行流水线,也可以设置以什么样的方式执行(when)
rules 有三个关键字
- if:判断条件,如果条件满足时执行该 job,不满足时不执行 job
- changes:某个或多个文件改变时执行该 job,没有改变时不执行 job
- exists:文件存在时执行该 job,不存在时不执行 job
if
if 可以使用多条件,&& 所有条件满足时才会执行该 job,|| 某个条件满足时就会执行该 job
stages: # 指定运行的顺序
- test
- deploy
variables:
name: zouzou
deploy:
tags:
- k8s
stage: deploy
retry:
parallel: 3 # 要并行运行的作业实例数
rules:
- if: '$name == "zouzou"' # 如果变量名等于 zouzou,则运行流水线,将流水线设置为手动执行
when: manual
- if: '$name == "haha"' # 如果变量名等于 haha,则延迟 10 秒执行
when: delayed
start_in: "10"
- when: on_success # 上面两个条件都不满足的话,则上个流水线成功时该流水线触发
script:
- echo "我是部署阶段"
test:
stage: test
script:
- echo "我是测试阶段"
现在 name 的值是等于 zouzou的,查看流水线
将 name 的值改为 haha,在来查看流水线
changes
接受文件路径数组。 如果提交中文件发生的变化则为 true。触发流水线
先在项目下创建一个 Dockerfile 的文件,随便写点内容
修改 .gitlab-ci.yml 文件内容,修改后的如下
stages: # 指定运行的顺序
- test
- deploy
variables:
name: haha
deploy:
tags:
- k8s
stage: deploy
retry:
parallel: 3 # 要并行运行的作业实例数
rules:
- changes: # 当 Dockerfile 或者 Jenkinsfile 里的文件内容改变时,才会执行 deploy 的 job
- Dockerfile
- Jenkinsfile
script:
- echo "我是部署阶段"
test:
stage: test
script:
- echo "我是测试阶段"
触发流水线查看下,可以看到,只有 test 的 job 触发了
这时候只有 Dockerfile 或者 Jenkinsfile 里的文件没有发生改变,deploy 的 job 都不会触发
接下来我们修改一下 Dockerfile 的内容,然后提交
提交后查看流水线
stages: # 指定运行的顺序
- test
- deploy
variables:
name: haha
deploy:
tags:
- k8s
stage: deploy
retry:
parallel: 3 # 要并行运行的作业实例数
rules:
- exists: # 当项目中存在 Dockerfile 或者 Jenkinsfile 文件时,才会执行 deploy 的 job
- Dockerfile
- Jenkinsfile
script:
- echo "我是部署阶段"
test:
stage: test
script:
- echo "我是测试阶段"
实际项目中使用 rules 的场景
下面几个例子是我们公司实际项目中 gitlab ci 的场景
例子一:在合 pr 的时候触发 job
static_check:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # 是合 pr 的时候才执行该 job
tags:
- docker
stage: verify
script: # 执行的操作
- make clean
- make genproto
- go mod vendor
- make lint
interruptible: true
verify_import_alias:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # 是合 pr 的时候才执行该 job
stage: verify
tags:
- k8s
script:
- make verify-import-alias
interruptible: true
演示
在我们的 main 分支下的 .gitlab-ci.yml 里写入下面内容
stages: # 指定运行的顺序
- test
- deploy
variables:
name: haha
deploy:
tags:
- k8s
stage: deploy
retry:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # 合 pr 时触发
script:
- echo "我是部署阶段"
test:
stage: test
script:
- echo "我是测试阶段"
基于 main 分支创建一个 demo 分支,修改 demo 分支上的文件,然后提交到 demo 分支上,也可以使用 git 提交
提交后查看流水线,发现只有一个 test 的 job 触发了(要保证 demo 分支的和 main 分支的 .gitlab-ci.yml 里的文件内容一样,如果不一样会以 demo 分支的为准)
这时候我们在提交一个 pr 到 main 分支
可以看到,提交 pr 只会跑 '$CI_PIPELINE_SOURCE == "merge_request_event"'
的 job ,我们的 test job 没有触发
例子二:满足某个条件时执行
unit_test:
rules: # 合 pr 或者提交到的分支是 main 分支。或者是创建 tag,只要满足某一个,都会触发该 job
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAG'
stage: test
tags:
- docker
script:
- make genproto
- go mod vendor
- make test
interruptible: true
coverage: '/total:\s+\(statements\)\s+\d+.\d+%/'
例子三:当往 main 分支 push 时触发
build_to_release_ci:
rules: # 提交的分支是 main 分支并且是 push 操作时才触发该流水线,&& 条件都要满足
- if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"' # trigger when a branch was merged into main
retry:
max: 2
tags:
- docker
before_script:
- docker -v #override the global before_script
- make genall
- go mod vendor
stage: build
script:
- |
# set envirment varible when new release publish by new tag created
export REGISTRY_USER_NAME=$CI_REGISTRY_USER_NAME
export REGISTRY_PASSWORD=$CI_REGISTRY_PASSWORD
export REGISTRY_REPO="release-ci.daocloud.io/amamba"
export REGISTRY_SERVER_ADDRESS="release-ci.daocloud.io"
export HELM_REPO="https://release-ci.daocloud.io/chartrepo/amamba"
make release -j2 #REGISTRY_USER_NAME and REGISTRY_PASSWORD config as Gitlab Variables
export NPM_TOKEN=$NPM_TOKEN;make push-grpc-ts #NPM_TOKEN has been configured as Gitlab Variable
例子四:创建 tag 或者往 main 分支上 merge 时触发
build_to_release_ci:
rules: # 往 main 分支上 merge 或者创建 tag 的时候触发
- if: '($CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "merge_request_event") || $CI_COMMIT_TAG'
tags:
- docker
before_script:
- docker -v
stage: build
script:
- |
# set envirment varible when new release publish by new tag created
export REGISTRY_USER_NAME=$CI_REGISTRY_USER_NAME
export REGISTRY_PASSWORD=$CI_REGISTRY_PASSWORD
export REGISTRY_REPO="release-ci.daocloud.io/amamba"
export REGISTRY_SERVER_ADDRESS="release-ci.daocloud.io"
make release #REGISTRY_USER_NAME and REGISTRY_PASSWORD config as Gitlab Variables