Jenkins 流水线 获取git 分支列表_Jenkins多分支流水线

Jenkins 流水线 获取git 分支列表_Jenkins多分支流水线_第1张图片

Jenkins+Docker+git实现多环境快速交付-compose优化升级一文中我们使用docker-compose对项目的环境校验、发版/回滚/重启、操作校验等步骤进行了优化。但是由于job使用的是“自由风格项目”或“mvn项目”,因此都是一个分支对应一个job,虽然也可以通过参数化构建方式实现一个job对应多个分支,常此以往一个项目需要建立很多job,管理非常不便。

解决方案:

Jenkin多分支流水线,允许Jenkinsfile与需要 Jenkins 构建的应用程序代码放在一起,然后 Jenkins 从源代码管理系统中检出 Jenkinsfile 文件作为流水线项目构建过程的一部分并接着执行你的流水线。

下面我们就来体验下Jenkins多分支的构建过程吧。

Jenkinsfile

Jenkins流水线的定义通常需要写入到一个文本文件(称为 Jenkinsfile )中,该文件可以被放入项目的源代码版本库中。

注意:Jenkinsfile放到项目版本库的根路径下。

在此我们还是延续使用helloworld的java项目。

Jenkins 流水线 获取git 分支列表_Jenkins多分支流水线_第2张图片

Jenkinsfile的代码如下:

vim Jenkinsfilepipeline {    options {        ansiColor('xterm')        timestamps()    }    agent {        label 'docker-slave-java'    }    triggers {      GenericTrigger (causeString: 'Generic Cause', genericVariables: [[defaultValue: 'deploy', key: 'deploy_env', regexpFilter: '', value: '']], regexpFilterExpression: '', regexpFilterText: '', token: '123456')    }    environment {        APP_NAME = "helloworld"        IMAGE_NAME = "helloworld/helloworld"        MONITOR_URL = "http://127.0.0.1:8080"        JAVA_OPTS = "-Xmx128m -Xms128m -Dspring.profiles.active=branch"        PORT = "9080:8080"    }    parameters {        choice choices: ['deploy', 'rollback', 'restart'], description: '''deploy:发布    rollback:回滚    restart:重启    注意:restart 参数只适用与docker环境''', name: 'deploy_env'        string defaultValue: '0', description: '''回滚版本号,发版时忽略    注意:    版本号为git commitid,如7e2c56522188c98f6294d91c8568dfcedf994e42。''', name: 'version', trim: false    }    stages {        stage('操作校验') {            steps {                sh label: '', script: '''                echo ${APP_NAME}                #操作校验                if [ "${deploy_env}" = "deploy" ];then                    echo -e "033[34mstart ${deploy_env}033[0m"                    echo ${GIT_PREVIOUS_SUCCESSFUL_COMMIT}                    echo ${GIT_COMMIT}                    [ "${GIT_PREVIOUS_SUCCESSFUL_COMMIT}" != "${GIT_COMMIT}" ] && echo -e "033[34mstart maven package033[0m" || {                        #版本未更新,停止发版                        echo -e "033[31mRepositories not update, stop ${deploy_env}033[0m"                        exit 1                    }                    /usr/local/maven/bin/mvn clean package docker:build -DdockerImageTags=${GIT_COMMIT} -Dmaven.test.skip=true -DpushImageTag                    [ $? -eq 0 ] && echo -e "033[32mmaven package success033[0m" || {                        echo -e "033[31mmaven package fail033[0m"                        exit 1                    }                elif [ "${deploy_env}" = "rollback" ];then                    echo -e "033[34mstart ${deploy_env}033[0m"                    echo ${GIT_PREVIOUS_SUCCESSFUL_COMMIT}                    echo ${GIT_COMMIT}                    #查看远程分支是否有此版本                    git branch -r --contains $version                    [ $? -eq 0 ] && echo -e "033[34mstart docker steps033[0m" || {                        echo -e "033[31mverison is wrong,please check version033[0m"                        exit 1                    }                fi'''            }        }        stage('开发部署') {            when {                branch 'develop'            }            steps {                sshPublisher(publishers: [sshPublisherDesc(configName: 'test-3.63', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: """                #!/bin/bash                IN_FACE=`/sbin/route -n |awk '{if($4~/UG/){print $8}}'|head -n 1`                LOCAL_IP=`/sbin/ip addr show "${IN_FACE}" | grep -w 'inet' | awk '{print $2}'`                CONTAINER_NAME=`echo ${IMAGE_NAME} | awk -F/ '{print $2}'`                #删除老镜像                DEL_IMAGE() {                    echo -e "033[34mrm image ${IMAGE_NAME}:$1033[0m"                    sudo docker image rm harbor.cityre.cn/${IMAGE_NAME}:$1 --no-prune                    [ $? -eq 0 ] && echo -e "033[32mrm ${IMAGE_NAME}:$1 succss 033[0m" || {                        echo -e "033[31mrm ${IMAGE_NAME}:$1 fail 033[0m"                        exit 1                    }                }                #健康检查                HEALTHCHECK() {                    timeout=180                    echo -e "033[34mhealth check033[0m"                    for (( i=1;i<=$timeout;i++ ))                    do                        status=$(sudo docker inspect --format='{{json .State.Health}}' ${CONTAINER_NAME}|grep -Po '"Status[":]+K[^"]+')                        echo $status                        if [ $status = 'healthy' ];then                           echo -e "033[32m${LOCAL_IP} ${CONTAINER_NAME}  status is ${status}033[0m"                           [ ${deploy_env} != "restart" ] && DEL_IMAGE ${OLD_VERSION}                           exit 0                        elif [ $status = 'starting' ];then                           sleep 23                        else                           echo -e "033[31m${LOCAL_IP} ${CONTAINER_NAME} status is ${status}033[0m"                           exit 1                        fi                    done                }                #定义docker-compose变量,注意第一步清空env,后续追加env                INIT_VAR() {                    echo -e "033[34minit docker-compose variable033[0m"                    echo "IMAGE_NAME=${IMAGE_NAME}" > .env                    echo "CONTAINER_NAME=${CONTAINER_NAME}" >> .env                    echo "APP_NAME=${APP_NAME}" >> .env                    echo "MONITOR_URL=${MONITOR_URL}" >> .env                    echo "PORT=${PORT}" >> .env                    echo "JAVA_OPTS=$(echo ${JAVA_OPTS}|sed 's/branch/test/')" >> .env                }                #进入项目目录                cd /App/java_app_tmp/${APP_NAME}                #提前读取env文件中的老版本号,用于删除老镜像                [ -f .env ] && OLD_VERSION=$(grep VERSION .env|awk -F= '{print $2}')                case ${deploy_env} in                deploy)                    echo -e "033[34mstart ${deploy_env} steps033[0m"                    INIT_VAR                    echo "VERSION=${GIT_COMMIT}" >> .env                    sudo docker-compose up -d --build                    HEALTHCHECK                    ;;                rollback)                    echo -e "033[34mstart ${deploy_env} steps033[0m"                    INIT_VAR                    echo "VERSION=${version}" >> .env                    sudo docker-compose up -d --build                    HEALTHCHECK                    ;;                restart)                    sudo docker-compose restart                    HEALTHCHECK                    ;;                *)                    exit 1                    ;;                esac""", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])            }        }        stage('测试部署') {            when {                branch 'develop'            }            steps {                sh 'uname -a'            }        }    }    post {        unstable {            emailext (                body: """项目名称:${JOB_NAME}构建编号:${BUILD_NUMBER}构建日志:${BUILD_URL}console""",                subject: '【Jenkins构建通知】:$JOB_NAME - Build # $BUILD_NUMBER - Unstable!',                to: '[email protected]',                from: '[email protected]'            )        }        success {            emailext (                body: """项目名称:${JOB_NAME}构建编号:${BUILD_NUMBER}构建日志:${BUILD_URL}console""",                subject: '【Jenkins构建通知】:$JOB_NAME - Build # $BUILD_NUMBER - Successful!',                to: '[email protected]',                from: '[email protected]'            )        }        failure {            emailext (                body: """项目名称:${JOB_NAME}构建编号:${BUILD_NUMBER}构建日志:${BUILD_URL}console""",                subject: '【Jenkins构建通知】:$JOB_NAME - Build # $BUILD_NUMBER - Failure!',                to: '[email protected]',                from: '[email protected]'            )        }    }}

我们在git版本中分了dev、test、master三个分支,分别对应开发、测试、生产三个环境,Jenkinsfile中通过when+branch来分别匹配不同的分支执行的操作。如下:

when {    branch 'develop'}

本次实验我们设置:

  1. 开发部署实现开发分支的docker构建。
  2. 测试部署实现测试分支的输出内核信息。
  3. 邮件通知实现失败/成功/不稳定等3个维度的邮件通知。

Jenkins构建

Jenkins流水线使用Blue Ocean效果更佳哦。

  1. 新建多分支流水线项目

我们的项目为docker-test-java3

287a18f7327099bacfb11494f5f14647.png
  1. 配置多分支流水线
Jenkins 流水线 获取git 分支列表_Jenkins多分支流水线_第3张图片

我们只需配置git代码库即可,此时会自动检测分支。如果代码库中没有Jenkinsfile会提示报错。

Jenkins 流水线 获取git 分支列表_Jenkins多分支流水线_第4张图片

我们只需在对应分支直接构建即可。

  1. 构建
3d37e3f896e30ddf69071e406df6bca4.png

总结

从以上过程我们可以看出,多分支流水线的重点在于Jenkinsfile文件,但是由于多分支流水线需要Jenkins放在版本库中,因此运维也要像开发一样维护Jenkinsfile,容易导致版本冲突。

因此对于此种情况,我认为还是需要扩展共享库的,这样可以进一步优化为多个项目使用同一套流水线,运维只需维护扩展共享库即可。

你可能感兴趣的:(Jenkins,流水线,获取git,分支列表,jenkins使用哪个版本号)