跳到主要内容

multi-branch-pipeline

多分支流水线

官方示例

我们简化一下流程,假如使用develop分支作为开发分支,master分支作为集成测试分支,看一下如何使用多分支流水线来管理。

演示1:多分支流水线的使用
  1. 提交develop分支:
$ git checkout -b develop
$ git push --set-upstream origin develop
  1. 禁用pipeline项目

  2. Jenkins端创建多分支流水线项目

    • 增加git分支源
    • 发现标签
    • 根据名称过滤,develop|master|v.*
    • 高级克隆,设置浅克隆

保存后,会自动检索项目中所有存在Jenkinsfile文件的分支和标签,若匹配我们设置的过滤正则表达式,则会添加到多分支的构建视图中。所有添加到视图中的分支和标签,会默认执行一次构建任务。

演示2:美化消息通知内容
  • 添加构建阶段记录
  • 使用markdown格式,添加构建分支消息

jenkins/pipelines/p6.yaml

pipeline {
agent { label '172.21.65.227'}

environment {
IMAGE_REPO = "172.21.65.226:5000/eladmin/eladmin-api"
DINGTALK_CREDS = credentials('dingTalk')
TAB_STR = "\n \n                    "
}

stages {
stage('gitlog') {
steps {
script{
sh "git log --oneline -n 1 \> gitlog.file"
env.GIT_LOG = readFile("gitlog.file").trim()
}
sh 'printenv'
}
}
stage('checkout') {
steps {
checkout scm
script{
env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('mvn package') {
steps {
sh 'mvn clean package'
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('build-image') {
steps {
retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('push-image') {
steps {
retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('deploy') {
steps {
timeout(time: 1, unit: 'MINUTES') {
sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
sh "kubectl apply -f manifests/"
}
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
}
post {
success {
echo 'Congratulations!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"myblog",
"text": "😄👍 构建成功 👍😄 \n**项目名称**: luffy \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
failure {
echo 'Oh no!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"myblog",
"text": "😖❌ 构建失败 ❌😖 \n**项目名称**: luffy \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
always {
echo 'I will always say Hello again!'
}
}
}
演示3:通知gitlab构建状态

Jenkins端做了构建,可以通过gitlab通过的api将构建状态通知过去,作为开发人员发起Merge Request或者合并Merge Request的依据之一。

注意一定要指定gitLabConnection('gitlab'),不然没法认证到Gitlab端

pipeline {
agent { label '172.21.65.227'}

options {
buildDiscarder(logRotator(numToKeepStr: '10'))
disableConcurrentBuilds()
timeout(time: 20, unit: 'MINUTES')
gitLabConnection('gitlab')
}


environment {
IMAGE_REPO = "172.21.65.226:5000/eladmin/eladmin-api"
DINGTALK_CREDS = credentials('dingTalk')
TAB_STR = "\n \n                    "
}

stages {
stage('gitlog') {
steps {
script{
sh "git log --oneline -n 1 \> gitlog.file"
env.GIT_LOG = readFile("gitlog.file").trim()
}
sh 'printenv'
}
}
stage('checkout') {
steps {
checkout scm
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('mvn package') {
steps {
sh 'mvn clean package'
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('build-image') {
steps {
retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('push-image') {
steps {
retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('deploy') {
steps {
timeout(time: 1, unit: 'MINUTES') {
sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
sh "kubectl apply -f manifests/"
}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
}
post {
success {
echo 'Congratulations!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"myblog",
"text": "😄👍 构建成功 👍😄 \n**项目名称**: luffy \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
failure {
echo 'Oh no!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"myblog",
"text": "😖❌ 构建失败 ❌😖 \n**项目名称**: luffy \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
always {
echo 'I will always say Hello again!'
}
}
}

我们可以访问gitlab,然后找到commit记录,查看同步状态

提交merge request,也可以查看到相关的任务状态,可以作为项目owner合并代码的依据之一:

本章小节

优势:

  • 根据分支展示, 视图人性化
  • 自动检测各分支的变更

思考:

  • Jenkins的slave端,没有任务的时候处于闲置状态,slave节点多的话造成资源浪费
  • 是否可以利用kubernetes的Pod来启动slave,动态slave pod来执行构建任务