Jenkins Pipeline 流水线 简单示例

本文介绍了如何在Ubuntu 20.04上使用Jenkins 2.319.1进行持续交付。通过声明式和脚本式Pipeline,结合Bitbucket,实现自动化构建和部署流程。示例展示了使用Groovy语法编写脚本式Pipeline,包括设置构建触发器、执行Maven打包、部署应用以及在构建成功或失败时发送钉钉通知。此外,还讲解了如何获取和格式化提交日志。

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

一、系统环境

组件版本
Ubuntu20.04
Jenkins2.319.1
Bitbucket

二、相关资料

官方文档-Jenkins用户手册

三、简单入门

Jenkins Pipeline 提供了一套可扩展的工具,用于将“简单到复杂”的交付流程实现为“持续交付即代码”。
Pipeline包含声明式脚本式流水线都是 DSL 语言,用来描述软件交付流水线的一部分。

脚本式流水线是用一种限制形式的 Groovy 语法编写的,Groovy语法与Java语法类似,对Java开发人员友好,甚至有书直言会Java就会Groovy~

流水线创建方式包括:经典UIBlueOceanJenkinsfile

官方教程-经典UI
官方教程-BlueOcean
官方教程-Jenkinsfile
官方教程-流水线语法

四、简单示例

全局变量文档 jenkins地址/pipeline-syntax/globals
官方教程-钉钉机器人
官方教程-build user vars插件

pipeline {
	//代理,通常是一个机器或容器
	agent any
    
    //环境变量,类似全局变量
    environment {
    	//构建执行者
    	BUILD_USER = ""
    }
    
    //构建触发器,Jenkins自动构建条件
    triggers{
        //每3分钟判断一次代码是否有变化
        pollSCM('H/3 * * * *')
    }

    stages {
    	//构建阶段
        stage('Build') {
        	//使用build user vars插件,获取构建执行者
            steps {
                wrap([$class: 'BuildUser']) {
                    script {
                    	//将构建执行者注入到环境变量中,方便最后通知使用
                        BUILD_USER = "${env.BUILD_USER}"
                    }
                }
                /* 从Bitbucket上拉取分支
                * @url git地址
                * @branch 分支名称
                * @credentialsId Jenkins凭证Id,用于远程访问
                */
                git(url: 'https://demo@bitbucket.org/demo/demo.git', branch: 'master', credentialsId: 'Bitbucket')
                //执行maven打包
                //-B --batch-mode 在非交互(批处理)模式下运行(该模式下,当Mven需要输入时,它不会停下来接受用户的输入,而是使用合理的默认值);
                //打包时跳过JUnit测试用例,
                //-DskipTests 不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下
                //-Dmaven.test.skip=true,不执行测试用例,也不编译测试用例类
                sh 'mvn -B -DskipTests clean package'
            }
        }
        
        //部署阶段
        stage('Deliver') {
            steps {
            	//解决杀掉了所有子进程问题
                withEnv(['JENKINS_NODE_COOKIE=background_job']) {
                	//执行脚本
                    sh '''
						# 服务器名称(pom文件定义)
						SERVER_NAME=police-tools
						# 生成的jar包名称
						JAR_NAME=${SERVER_NAME}-0.0.1-SNAPSHOT.jar
						# 分支名称
						BRANCH=master
						# 生成的jar包路径
						JAR_PATH=/var/lib/jenkins/workspace/${SERVER_NAME}/target
						# 运行jar的工作路径,统一管理,并需要提前创建好
						JAR_WORK_PATH=/usr/local/jenkins/maven/jar/${SERVER_NAME}/${BRANCH}

						# 停止服务并杀死进程
						pid=$(ps -ef | grep ${JAR_NAME} | grep -v grep | awk '{ print $2 }')
						if [ -z "$pid" ]
						then
							echo ${JAR_NAME} is already stopped
						else
							echo kill ${JAR_NAME}
							echo kill -15 ${pid}
							kill -15 ${pid}
						fi

						# kill需要一定时间,等待10秒,线上环境请增加判断
						sleep 10

						# 创建默认路径
						mkdir -p ${JAR_WORK_PATH}
						# 移动打包文件
						cp -f ${JAR_PATH}/${JAR_NAME} ${JAR_WORK_PATH}
						# 移动到工作目录下,否则log日志会打印到当期工作目录
						cd ${JAR_WORK_PATH}
						# /dev/null 所有写入它的内容都会永远丢失
						nohup java -jar ${JAR_WORK_PATH}/${JAR_NAME} >/dev/null 2>>${JAR_WORK_PATH}/sys_error.log &
						'''
                }
            }
        }
    }
    //根据流水线或阶段的完成情况而运行,包含always、changed、failure、success、unstable、aborted状态
    post {
    		//成功
            success {
            	//DingTalk插件,钉钉通知
                dingtalk (
                	//机器人ID
                    robot: "dev1_robot",
                    //通知类型,整体跳转
                    type:'ACTION_CARD',
                    //通知所有人,如果想要通知一些人则可用at
                    atAll: false,
                    //标题
                    title: "构建成功:${env.JOB_NAME}",
                    //通知内容
                    text: [
                        "### [${env.JOB_NAME}](${env.JOB_URL}) ",
                        '---',
                        "- 任务:[${currentBuild.displayName}](${env.BUILD_URL})",
                        '- 状态:<font color=#00CD00 >成功</font>',
                        "- 持续时间:${currentBuild.durationString}".split("and counting")[0],
                        "- 执行人:${BUILD_USER}",
                        "- 提交日志: ${changeString}",
                    ]
                )
            }
            failure{
                dingtalk (
                    robot: "dev1_robot",
                    type:'ACTION_CARD',
                    atAll: false,
                    title: "构建失败:${env.JOB_NAME}",
                    //messageUrl: 'xxxx',
                    text: [
                        "### [${env.JOB_NAME}](${env.JOB_URL}) ",
                        '---',
                        "- 任务:[${currentBuild.displayName}](${env.BUILD_URL})",
                        '- 状态:<font color=#EE0000 >失败</font>',
                        "- 持续时间:${currentBuild.durationString}".split("and counting")[0],
                        "- 执行人:${BUILD_USER}",
                        "- 提交日志: ${changeString}",
                    ]
                )
            }
    }
}

//从changeSets中格式化获取提交日志
@NonCPS
def getChangeString() {
    MAX_MSG_LEN = 100
    # 提交日志
    def changeString = ""

    echo "Gathering SCM changes"
    def changeLogSets = currentBuild.changeSets
    for (int i = 0; i < changeLogSets.size(); i++) {
        def entries = changeLogSets[i].items
        for (int j = 0; j < entries.length; j++) {
            def entry = entries[j]
            truncated_msg = entry.msg.take(MAX_MSG_LEN)
            changeString += " -${entry.author} : ${truncated_msg} \n"
        }
    }
    if (!changeString) {
        changeString = " - No new changes"
    }
    return changeString
}

五、参考鸣谢

Jenkins流水线获取提交日志
Jenkins Pipeline 手记(1)—— 什么是CPS编程

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值