Jenkins 实现Pipeline生产审批

您所在的位置:网站首页 Jenkins脚本如何检测节点上线 Jenkins 实现Pipeline生产审批

Jenkins 实现Pipeline生产审批

2024-06-10 10:42| 来源: 网络整理| 查看: 265

如果你想实现以下内容,请看此文: 1、代码一提交,就自动发布测试环境 ---jenkins触发器实现 2、可以指定版本号、分支名,拉取代码 ---git命令实现 3、部署生产之前,发一份邮件给老板,请他审核同意发布 --jenkins的邮件功能实现 4、不依赖harbor,加快镜像的io传输速度 ---scp和ssh命令实现 前提 1、部署好你的jenkins https://www.jenkins.io/zh/doc/book/installing/ 2、容器内安装好maven 3、下载好下图的红框的插件 4、配置好ssh、email插件,配置好git凭证 下载好以下插件

在这里插入图片描述

设置构建时输入的参数 发布模式参数

在这里插入图片描述

分支参数

在这里插入图片描述

代码提交的版本号

在这里插入图片描述

部署的测试机器列表参数

在这里插入图片描述

部署的生产机器列表参数

在这里插入图片描述

审核人邮件参数

其实建议审核人邮件写死,但为了快速测试,所有使用手填 在这里插入图片描述

构建页面展示

配置好上面这些构建参数后,你的界面应该如下所示: 在这里插入图片描述

流水线jenkinsfile文件

我自己写的jenkinsfile,仅供参考

def skipProd = true //是否跳过生产部署 def timeout_mins = 5 //超时时间 def input_message //提示语 def randomToken //发布秘钥 //系统个人信息 def Applier_id def Applier_name def Applier_mail // 项目信息 def project_name = "test" def version = "0.1.0" // 系统凭证 def git_auth = "git_auth" pipeline{ agent any options { //调用颜色插件 ansiColor('xterm') skipDefaultCheckout(true) } environment { Applier_name = "" Applier_mail = "" Operator_mail = "" input_message = "" } stages{ stage('构建初始化') { parallel { stage("拉取代码"){ steps{ withCredentials([usernamePassword(credentialsId: "${git_auth}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { echo "\033[32m ******开始拉取代码${branch}分支代码,revision为${commit}的代码(revision为空时拉取该分支最新代码)****** \033[0m" sh "rm -rf zzw; mkdir zzw;cd zzw;rm -rf test;git clone https://${USERNAME}:${PASSWORD}@gitee.com/mylittlebrother/test.git;cd test;git pull origin ${branch};git reset --hard ${commit} " } } } stage("是否发送token邮件"){ steps{ wrap([$class: 'BuildUser']) { script { //获取当前登录用户账户、姓名、邮箱 Applier_id = "${BUILD_USER_ID}" Applier_name = "${env.BUILD_USER}" Applier_mail = "${env.BUILD_USER_EMAIL}" } } script{ // 判断是否需要审批 if ("$Mode" == "test" || "$Mode" == "" ){ echo "\033[32m ******发布测试操作无需审批,待自动执行测试****** \033[0m" skipProd = true }else{ skipProd = false echo "\033[32m ******发布生产操作需审批,待自动执行测试环境后,同时还将执行生产审批流程****** \033[0m" randomToken = sh (script: "echo \$RANDOM" , returnStdout: true).trim() input_message = " $Applier_name 申请发布生产" emailext( subject:"【请审批】${env.JOB_NAME}(#${env.BUILD_NUMBER})生产部署任务", body:"""$input_message,随机验证码是:${randomToken}!!! 请点击该链接登录后审批填入token发布或者将token值${randomToken}告诉${Applier_name},让其输入token""", to:"${emails}" ) echo "\033[32m ******申请邮件已经发送,待$adminUser 审批****** \033[0m" } } } } } } stage('编译测试镜像') { steps{ sh "source /etc/profile;java -version;mvn -v;cd zzw/test; mvn clean package -P test dockerfile:build -Dmaven.test.skip=true" } } stage('上传测试镜像') { steps{ script{ def imageName = "${project_name}-test:${version}" sh "docker tag ${project_name}:latest ${imageName}" try { //删除镜像 sh "docker images|grep none|awk '{print \$3 }'|xargs docker rmi" }catch(err) { echo "\033[31m 警告!!!该镜像可能不存在 \033[0m" } sh "pwd; docker save -o ${project_name}-test.tar ${imageName};ls" //生成测试镜像 echo "\033[32m ******测试机器输入是 ${testMachines}****** \033[0m" def host = "$testMachines".split('@') echo "\033[32m ******测试机器ip是 ${host}****** \033[0m" for (machine in host){ if(machine!=null && machine !=''){ def ip = machine.split(':')[0] sh " scp -r ${project_name}-test.tar root@${ip}:/opt/" echo "\033[32m ******${ip}拷贝镜像文件${project_name}-test.tar完成****** \033[0m" } } } } } stage('发布测试') { steps{ script{ def imageName = "${project_name}-test:${version}" //测试镜像 def delete_running_container = "docker rm -f \$(docker ps | grep ${project_name}-test | awk '{print \$1}')" //删除指定镜像的容器 def delete_iamge = "docker rmi -f \$(docker images | grep ${project_name}-test | awk '{print \$3}')" //删除指定镜像 def load_image = "cd /opt; docker load -i ${project_name}-test.tar " //加载指定image def run_test = "docker run -di -p 1993:1993 ${imageName} " try { //停止镜像 sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${delete_running_container}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) }catch(err) { echo "\033[31m 警告!!!该容器可能不存在 \033[0m" } try { //停止镜像 sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${delete_iamge}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) }catch(err) { echo "\033[31m 警告!!!该镜像可能不存在 \033[0m" } try { // 加载镜像 sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${load_image}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) }catch(err) { } echo "******开始发布测试环境*****" sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${run_test}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } } stage("请输入生产token"){ when { expression {!skipProd}} steps{ script{ def isAbort = false //取消按钮 timeout(timeout_mins){ //等待审批人审批,并通过timeout设置任务过期时间,防止任务永远挂起 try { def userInput = input( id: 'inputap', message: "$input_message", ok:"确认token", submitter:"$adminUser", parameters: [ [$class: 'StringParameterDefinition',defaultValue: "", name: 'token',description: '请输入发布的秘钥' ] ]) if (userInput == randomToken) { skipProd = false } else { skipProd = true echo "\033[31m 秘钥错误 \033[0m" } echo "\033[31m 当前输入秘钥为: ${userInput} \033[0m" }catch(err) { // input false echo "******主动拒绝*****" skipProd = true } } } } } stage('编译生产镜像') { when { expression {!skipProd} } steps{ sh "source /etc/profile;java -version;mvn -v;cd zzw/test; mvn clean package -P prod dockerfile:build -Dmaven.test.skip=true" } } stage("上传生产镜像"){ when { expression {!skipProd} } steps{ script{ def imageName = "${project_name}-prod:${version}" sh "docker tag ${project_name}:latest ${imageName}" try { //删除镜像 sh "docker images|grep none|awk '{print \$3 }'|xargs docker rmi" }catch(err) { echo "\033[31m 警告!!!该镜像可能不存在 \033[0m" } sh "pwd; docker save -o ${project_name}-prod.tar ${imageName};ls" //生成生产镜像 def host = "$prodMachines".split('@') echo "\033[32m ******测试机器ip是 ${host}****** \033[0m" for (machine in host){ if(machine!=null && machine !=''){ def ip = machine.split(':')[0] sh " scp -r ${project_name}-prod.tar root@${ip}:/opt/" echo "\033[32m ******${ip}拷贝镜像文件${project_name}-prod.tar完成****** \033[0m" } } } } } stage("发布生产"){ when { expression {!skipProd} } steps{ script{ def imageName = "${project_name}-prod:${version}" //测试镜像 def delete_running_container = "docker rm -f \$(docker ps | grep ${project_name}-prod | awk '{print \$1}')" //删除指定镜像的容器 def delete_iamge = "docker rmi -f \$(docker images | grep ${project_name}-prod | awk '{print \$3}')" //删除指定镜像 def load_image = "cd /opt; docker load -i ${project_name}-prod.tar " //加载指定image def run_prod = "docker run -di -p 1999:1999 ${imageName} " try { //停止镜像 sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${delete_running_container}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) }catch(err) { echo "\033[31m 警告!!!该容器可能不存在 \033[0m" } try { //停止镜像 sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${delete_iamge}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) }catch(err) { echo "\033[31m 警告!!!该镜像可能不存在 \033[0m" } try { // 加载镜像 sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${load_image}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) }catch(err) { } echo "******开始发布生产环境*****" sshPublisher(publishers: [sshPublisherDesc(configName: 'node01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${run_prod}", execTimeout: 60000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } } } } 执行情况

在这里插入图片描述

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3