gitlab-CI 代码管理自动化部署及消息推送
(1) 通过在项目根目录下配置**.gitlab-ci.yml**文件,可以控制ci流程的不同阶段,gitlab平台会扫描.gitlab-ci.yml文件,并据此处理ci流程。
(2) ci流程在每次团队成员push/merge后之后触发。每当你push/merge一次,gitlab-ci都会检查项目下有没有.gitlab-ci.yml文件,如果有,它会执行你在里面编写的脚本,并完整地走一遍流水线定义的流程。
(3)gitlab-ci提供了指定ci运行平台的机制,它提供了一个叫gitlab-runner的软件,只要在对应的平台(机器或docker)上下载并运行这个命令行软件,并输入从gitlab交互界面获取的token,就可以把当前机器和对应的gitlab-ci流程绑定,也即:每次跑ci都在这个平台上进行。
(4).gitlab-ci的所有流程都是可视化的,每个流程节点的状态可以在gitlab的交互界面上看到,包括执行成功或失败。如下图所示,因为它的执行看上去就和多节管道一样,所以我们通常用“pipeLine”来称呼它。
(5).不同push/merge所触发的CI流程不会互相影响,也就是说,你的一次push引发的CI流程并不会因为接下来另一位同事的push而阻断,它们是互不影响的。这一个特点方便让测试同学根据不同版本进行测试。
(6)pipeline不仅能被动触发,也是可以手动触发的。
自动化部署给我们带来的好处
提高前端的开发效率和开发测试之间的协调效率
如果按照传统的流程,在项目上线前的测试阶段,前端同学修复bug之后,要手动把代码部署之后。才能通知测试同学在测试环境进行测试。
这会造成几个问题:本身手动部署服务的工作是比较繁琐的,占用了开发时间。同时开发-测试之间的环节的耦合问题,则会增加团队沟通成本。
通过gitlab-ci,前端开发在提交代码之后就不用管了,ci流程会自动部署到测试或集成环境的服务器。很大程度上节约了开发的时间。
同时,因为开发和测试人员可以共用gitlab里的pipeline界面, 测试同学能够随时把握代码部署的情况,同时还可以通过交互界面手动启动pipeline,自己去部署测试,从而节约和开发之间的沟通时间。
从更细的粒度把握代码质量
我们可以代码检查加到pipeline流程中,每当团队成员提交和合并一次,pipeline都会触发一次并对代码做一次全面检测,这样就从一个更细的粒度上控制代码质量了。
gitlab-ci涉及的抽象概念
Pipeline & Job
Pipeline是Gitlab根据项目的.gitlab-ci.yml文件执行的流程,它由许多个任务节点组成, 而这些Pipeline上的每一个任务节点,都是一个独立的Job。
Job在YML中的配置我们将会在下面介绍,现在需要知道的是:每个Job都会配置一个stage属性,来表示这个Job所处的阶段。
一个Pipleline有若干个stage,每个stage上有至少一个Job,如下图所示:
Runner
Runner可以理解为:在特定机器上根据项目的**.gitlab-ci.yml文件,对项目执行pipeline的程序**。Runner可以分为两种: Specific Runner 和 Shared Runner。
- Shared Runner是Gitlab平台提供的免费使用的runner程序,它由Google云平台提供支持,每个开发团队有十几个。对于公共开源项目是免费使用的,如果是私人项目则有每月2000分钟的CI时间上限。
- Specific Runner是我们自定义的,在自己选择的机器上运行的runner程序,gitlab给我们提供了一个叫gitlab-runner的命令行软件,只要在对应机器上下载安装这个软件,并且运行gitlab-runner register命令,然后输入从gitlab-ci交互界面获取的token进行注册, 就可以在自己的机器上远程运行pipeline程序了。
Executor
什么是Executor? 我们上面说过 Specific Runner是在我们自己选择的平台上执行的,这个平台就是我们现在说到的“Executor”,我们在特定机器上通过gitlab-runner这个命令行软件注册runner的时候,命令行就会提示我们输入相应的平台类型。可供选择的平台一共有如下几种,下面是一张它们各方面特点的比较表格。
GItlabCI实战——CI环境安装
以下以Windows平台为例:
下载并安装Gitlab-runner,
初始化gitlab-runner
以管理员身份运行cmd命令行,进入到Runner的所在目录下
gitlab-runner install
gitlab-runner start
注册Runner
gitlab-runner register
token如下:
激活Runner
gitlab-runner verify
这时候回去看Gitlab面板里的Runner参数:
是绿色就说明激活成功了
运行Runner
gitlab-runner run
停止Runner
gitlab-runner stop
卸载Runner
gitlab-runner uninstall
其他注意事项
需要把Share Runner禁用掉
shell脚本接入钉钉SDK
#!/bin/bash
webhook='https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxxxxx'
#为你的钉钉机器人的hook
function SendMsgToDingding() {
curl $webhook -H 'Content-Type: application/json' -d "
{
'msgtype': 'text',
'text': {
'content': 'CI Test Print\n'
#如果设置为自定义关键词的方式,所以在推送的报文中就必须至少包含一项设置的关键词
},
'at': {
"atMobiles": [
"xxxxxxxxxxx",
],
'isAtAll': false
}
}"
}
SendMsgToDingding
gitlab.yml脚本基本语法
stages
前面提到,我们可以定义一系列任务(job)去执行我们想要的指令,但怎样指定先后顺序呢,这就需要用到stages关键字了。
stages关键字有两个特性:
1.如果两个任务对应的stage名相同,则这两个任务会并行运行
2.下一个stage关联的任务会等待上一个stage执行成功后才继续运行,失败则不运行
image: python:3.6
stages:
- build
- test
- deploy
# build-job1和build-job2会并行执行
build-job1:
stage: build
script:
- echo $PWD
build-job2:
stage: build
script:
- echo $PWD
# 这个任务会在build-job1和build-job2执行成功后再运行
test-job:
stage: test
script:
- echo $PWD
# 注意定义的stage都需要用到
deploy-job:
stage: deploy
script:
- echo $PWD
效果图如下:
如果想要控制某一个stage在最开始,或者最后执行,可以使用.pre
和 .post
关键字
only / except
为了更好地说明,我们还需引入一个Pipelines
的概念,Pipelines就是我们在Gitlab的UI界面看到一行行记录:
如上图,一共有三个Pipelines,每个Pipelines内部就是我们定义的任务的执行情况,就是这么简单。
前面提到,通过stages关键字可以控制任务执行的先后顺序,而通过only/except
关键字控制的是任务的触发条件。
only/except关键字包含了一些子关键字(或者你可以理解为策略),当符合定义的策略时才会触发Pipelines的执行,except则相反。
only关键字的默认策略是[‘branches’, ‘tags’],即你提交了一个分支或者打了标签,就会触发,
除此之外,only/except关键字还有基础特性和高级特性之分,所包含的子关键字也各不相同。
only/except(basic):
- branches: 当你的Git Refs对应的是一个分支时触发
- tags: 当你的Git Refs对应的是一个标签时触发
- pushes: 当你使用
git push
时触发 - web: 当你使用Web界面的
Run Pipeline
时触发 - merge_requests: 当你创建或者更新一个merge_requests时触发
- …
only/except(advanced):
- refs: 注意异或关系
- variables
- changes
- kubernetes
下面是一些示例,希望能给你带来帮助
1.当提交的分支为master才会触发Pipelines
image: python:3.6
# 第一种方式
job1:
only:
- master
script:
- echo $PWD
# 第二种方式
job2:
only:
refs:
- master
script:
- echo $PWD
# 第三种方式
job3:
only:
variables:
- $CI_COMMIT_REF_NAME == "master"
script:
- echo $PWD
2.当打了tag才会触发Pipelines(正常的提交不会)
image: python:3.6
# 第一种方式
job1:
only:
- tags
script:
- echo $PWD
# 第二种方式
job2:
only:
refs:
- tags
script:
- echo $PWD
3.当提交的分支为master或者打了tags触发Pipelines
image: python:3.6
# 举这个例子是想说明only关键字之间的关系是”或“关系
job1:
only:
- master
- tags
script:
- echo $PWD
tags
该关键字指定了使用哪个Runner(哪个机器)去执行我们的任务,注意与上文only关键字的tags进行区分。
image: python:3.6
# 举这个例子是想说明only关键字之间的关系是”或“关系
job1:
only:
- dev
tags:
- machine1
script:
- echo $PWD
when
前面说过,stages关键字可以控制每个任务的执行顺序,且后一个stage会等待前一个stage执行成功后才会执行,那如果我们想要达到前一个stage失败了,后面的stage仍然能够执行的效果呢?
这时候when关键字就可以发挥作用了,它一共有五个值:
- on_success:只有前面stages的所有工作成功时才执行,这是默认值。
- on_failure:当前面stages中任意一个jobs失败后执行
- always:无论前面stages中jobs状态如何都执行
- manual:手动执行
- delayed:延迟执行
# 官方示例
stages:
- build
- cleanup_build
- test
- deploy
- cleanup
build_job:
stage: build
script:
- make build
# 如果build_job任务失败,则会触发该任务执行
cleanup_build_job:
stage: cleanup_build
script:
- cleanup build when failed
when: on_failure
test_job:
stage: test
script:
- make test
deploy_job:
stage: deploy
script:
- make deploy
when: manual
# 总是执行
cleanup_job:
stage: cleanup
script:
- cleanup after jobs
when: always
cache
该关键字指定了需要缓存的文件夹或者文件,目的是为了加快执行速度。
值得注意的是,cache不能缓存工作路径以外的文件。比如你的用户是yangan,项目是helloworld,默认的工作路径就是/build/yangan/helloworld, 如果你想缓存/root下的某个文件,就会出现“找不到文件”的错误。
另外,cache并不能保证每次都能命中,而且如果缓存的文件较大,有时候反而会适得其反,导致速度变慢。
image: python:3.6
cache:
# 注意是相对路径
paths:
- cache_dir/
job1:
script: echo $PWD
# 针对单个任务
cache:
- binaries/
artifacts
类似cache关键字,也可以缓存文件或者文件夹,不同的是,这些文件可以在Gitlab的UI界面中下载,一般可用来存储Android打包生成的apk。
image: python:3.6
job1:
artifacts:
paths:
- binaries/
# 设置过期时间
expire_in: 1 week
变量
Gitlab-CI的变量有几种,分别为预先定义的环境变量,比如CI_COMMIT_SHA
, CI_COMMIT_MESSAGE
; 通过Web界面Settings/CI-CD设置的变量,以及自己在.gitlab-ci.yml
定义的变量。
通过预先定义的环境变量,我们可以获取分支名,提交的消息,从而判断任务是否需要执行;而Web界面Settings/CI-CD设置的变量,则非常适合用于存储像公私钥,账号密码这些不便公开的数据。因为只有Owner和Maintainer能够查看。
如下图就定义了一个SSH_PRIVATE_KEY
来存储私钥:
variables关键字: docs.gitlab.com/ee/ci/varia…
Gitlab预定义的变量: docs.gitlab.com/ce/ci/varia…
环境变量: docs.gitlab.com/ce/ci/varia…
官方文档
CI接入钉钉自动化消息推送Sample
当完成一次代码合并时调用钉钉机器人的sdk推送消息:
CI脚本
before_script:
- echo "Before script section"
- echo "For example you might run an update here or install a build dependency"
- echo "Or perhaps you might print out some debugging details"
after_script:
- echo "After script section"
- echo "For example you might do some cleanup here"
stages:
- build
- test
- deploy
build-job1:
stage: build
script:
- chcp 65001
- sh Test.sh
- echo "Do your build-job1 here"
build-job2:
stage: build
script:
- echo "Do your build-job2 here"
test-job:
stage: test
script:
- echo "test-job"
deploy-job:
stage: deploy
script:
- echo "deploy-job"
shell脚本
#!/bin/bash
##################
# 钉钉通知
# 自动化部署脚本中使用
##################
#!/bin/bash
webhook='https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxx'
function SendMsgToDingding() {
curl $webhook -H 'Content-Type: application/json' -d "
{
'msgtype': 'text',
'text': {
'content': '[CI/CD]
Branch: ${CI_COMMIT_REF_NAME}
User: ${GITLAB_USER_EMAIL}
[Pipeline #${CI_PIPELINE_ID}]'
},
'at': {
"atMobiles": [
"xxxxxxxxx",
],
'isAtAll': false
}
}"
}
SendMsgToDingding
参考链接: