demo-springboot-simple中Jenkinsfile详解

demo-springboot-simple 仓库地址为:https://github.com/MingGH/demo-springboot-simple

这里详细的给大家说明一下,先放一下完整的Jenkinsfile。

pipeline {
    agent {
        docker {
            image 'maven:3.8-openjdk-17'
            args '-v /root/.m2:/root/.m2 -v /root/.ssh:/root/.ssh'
        }
    }
    stages {
        stage('Build') {
            steps {
                sh 'mvn -B -DskipTests clean package'
            }
        }
        stage('Unit Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
        stage('Push Nexus') {
            steps {
                script {
                    POM_VERSION = sh (
                        script: 'mvn spring-boot:build-info | grep Building | awk \'{split(\$0,r," "); print r[4]}\'',
                        returnStdout: true
                    ).trim()

                    //update version for prod env, remove -SNAPSHOT
                    if ("${params.ENV_INFO}" == "prod") {
                        JAR_VERSION_WITHOUT_SNAPSHOT = sh (
                            script: "echo ${POM_VERSION} | awk '{split(\$0,r,\"-\"); print r[1]}' ",
                            returnStdout: true
                        ).trim()
                        sh "mvn versions:set -DnewVersion=${JAR_VERSION_WITHOUT_SNAPSHOT}"

                        JAR_FINAL_VERSION = sh (
                            script: "echo ${JAR_VERSION_WITHOUT_SNAPSHOT} ",
                            returnStdout: true
                        ).trim()
                    }else {
                        JAR_FINAL_VERSION = sh (
                            script: "echo ${POM_VERSION} ",
                            returnStdout: true
                        ).trim()
                    }
                }
                sh 'mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests'
            }
        }
        stage('Package Image') {
            steps {
                script {
                    sh 'mvn clean package dockerfile:build -DskipTests'
                }
            }
        }
        stage('Push Image') {
            steps {
                script {
                    sh "sh deploy_docker.sh push ${JAR_FINAL_VERSION} ${params.ENV_INFO} "
                }
            }
        }
        stage('Deploy') {
            steps {
                script {
                    //
                    if ("${params.Deploy_Port}" == "default") {
                        sh "sh deploy_docker.sh restart ${JAR_FINAL_VERSION} ${params.ENV_INFO} "
                    }else{
                        sh "sh deploy_docker.sh restart ${JAR_FINAL_VERSION} ${params.ENV_INFO} ${params.Deploy_Port}"
                    }
                }
            }
        }
        stage('Update version') {
            steps {
                script {
                    JAR_FINAL_VERSION = sh (
                        script: 'mvn spring-boot:build-info | grep Building | awk \'{split(\$0,r," "); print r[4]}\'',
                        returnStdout: true
                    ).trim()
                    MAJOR_VERSION = sh (
                        script: "echo ${JAR_FINAL_VERSION} | awk '{split(\$0,r,\"-\"); print r[1]}' | awk '{split(\$0,r,\".\"); print r[1] \".\" r[2]}\' ",
                        returnStdout: true
                    ).trim()
                    UPDATED_VERSION = sh (
                        script: "echo ${JAR_FINAL_VERSION} | awk '{split(\$0,r,\"-\"); print r[1]}' | awk '{split(\$0,r,\".\"); print r[3]}' | awk '{value=1+\$1} END{print value}' ",
                        returnStdout: true
                    ).trim()

                    sh "git branch -D ${params.GIT_Branch} || true"
                    sh "git checkout -b ${params.GIT_Branch} || true"
                    sh "mvn versions:set -DnewVersion=${MAJOR_VERSION}.${UPDATED_VERSION}-SNAPSHOT"
                    sh "git config user.email [email protected]"
                    sh "git config user.name xxxxx"
                    sh "git commit -a -m 'Triggered Build: update pom version'"
                    sh "git push -u origin ${params.GIT_Branch}"
                }
            }
        }
    }
}

Jenkins agent

首先是Jenkins agent部分,因为Jenkins采用的是“master+agent(slave)”架构。Jenkins master负责提供界面、处理HTTP请求及管理构建环境;构建的执行则由Jenkins agent负责。Jenkins agent作为一个负责执行任务的程序。

这里定义的agent是一个maven的Docker 容器,当Jenkins运行时会通过宿主机的docker创建一个maven的容器,并且映射宿主机的/root/.m2目录和/root/.ssh目录,获取到GitHub权限

agent {
    docker {
        image 'maven:3.8-openjdk-17'
        args '-v /root/.m2:/root/.m2 -v /root/.ssh:/root/.ssh'
    }
}

Build stage,

使用agent中的maven进行build,这里是跳过unit test的

stage('Build') {
    steps {
        sh 'mvn -B -DskipTests clean package'
    }
}

Unit Test stage

这里的 [junit](https://www.jenkins.io/doc/pipeline/steps/junit/#code-junit-code-archive-junit-formatted-test-results) step (由 JUnit Plugin 提供)用于归档JUnit XML报告(由上面的 mvn test 命令生成) 并通过Jenkins接口公开结果。在Blue Ocean中,可以在流水线运行的 Tests 页面获取结果。 而post的 always 条件包含了这个 junit step, 保证了这个step总是在 Test 阶段 结束后 执行,不论该阶段的运行结果如何。

stage('Unit Test') {
      steps {
          sh 'mvn test'
      }
      post {
          always {
              junit 'target/surefire-reports/*.xml'
          }
      }
  }

Push Nexus Stage

  • POM_VERSION = sh (script: 'shell script', returnStdout: true).trim() 可以通过执行shell,并且把shell的输出结果返回给定义的变量,名称是自定义的。
  • mvn spring-boot:build-info 可以通过maven获取到当前项目的版本信息,长这样
asher@Ashers-Mac demo-springboot-simple % mvn spring-boot:build-info
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------< run.runnable:demo-springboot-simple >-----------------
[INFO] Building demo-springboot-simple 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- spring-boot-maven-plugin:3.0.1:build-info (default-cli) @ demo-springboot-simple ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.430 s
[INFO] Finished at: 2023-01-04T18:59:54+08:00
[INFO] ------------------------------------------------------------------------

所以还需要一些操作来进行版本的提取,通过grep Building | awk '{split($0,r," "); print r[4]}' 来完成。

再接着就是判断Jenkins执行时传入的参数是dev还是prod来推送到具体的maven仓库。

  • ${params.ENV_INFO}表示可以通过${params.<jenkins上定义的参数>} 获取到Jenkins pipline上配置的参数。
  • mvn versions:set -DnewVersion= 可以更新当前项目的版本号

在这步stage中,完成的操作是拿到项目的版本号,然后判断Jenkins执行的是dev还是prod,如果是prod,那么则更新版本号为不带-SNAPSHOT 的版本号,则会推送到生产库。并把这个最后确认的版本号赋值给JAR_FINAL_VERSION。

stage('Push Nexus') {
    steps {
        script {
            POM_VERSION = sh (
                script: 'mvn spring-boot:build-info | grep Building | awk \'{split(\$0,r," "); print r[4]}\'',
                returnStdout: true
            ).trim()

            //update version for prod env, remove -SNAPSHOT
            if ("${params.ENV_INFO}" == "prod") {
                JAR_VERSION_WITHOUT_SNAPSHOT = sh (
                    script: "echo ${POM_VERSION} | awk '{split(\$0,r,\"-\"); print r[1]}' ",
                    returnStdout: true
                ).trim()
                sh "mvn versions:set -DnewVersion=${JAR_VERSION_WITHOUT_SNAPSHOT}"

                JAR_FINAL_VERSION = sh (
                    script: "echo ${JAR_VERSION_WITHOUT_SNAPSHOT} ",
                    returnStdout: true
                ).trim()
            }else {
                JAR_FINAL_VERSION = sh (
                    script: "echo ${POM_VERSION} ",
                    returnStdout: true
                ).trim()
            }
        }
        sh 'mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests'
    }
}

Package Image Stage

mvn clean package dockerfile:build -DskipTests 可以通过maven构建docker镜像。需要搭配pom.xml中的plugin,在之后会讲到。

stage('Package Image') {
    steps {
        script {
            sh 'mvn clean package dockerfile:build -DskipTests'
        }
    }
}

Push Image Stage

Push Nexus Stage确定的版本号JAR_FINAL_VERSION将在这一步推送给到Docker容器镜像仓库, 需要结合另一个配置文件deploy_docker.sh来进行使用。

stage('Push Image') {
    steps {
        script {
            sh "sh deploy_docker.sh push ${JAR_FINAL_VERSION} ${params.ENV_INFO} "
        }
    }
}

Deploy Stage

这个stage需要和3.1步中的一个参数Deploy_Port关联起来,如果是default,则端口使用deploy_docker.sh中配置的,如果有值,则覆盖deploy_docker.sh中的配置

stage('Deploy') {
    steps {
        script {
            //
            if ("${params.Deploy_Port}" == "default") {
                sh "sh deploy_docker.sh restart ${JAR_FINAL_VERSION} ${params.ENV_INFO} "
            }else{
                sh "sh deploy_docker.sh restart ${JAR_FINAL_VERSION} ${params.ENV_INFO} ${params.Deploy_Port}"
            }
        }
    }
}

Update Version Stage

在这个stage中需要修改你的git邮箱地址和username,因为在步骤2.4中已经配置了公钥在GitHub上,**且在Jenkins agent 中配置了/root/.ssh的目录映射,**所以这里只需要配置用户名和邮箱就行。

使用之前获取到的JAR_FINAL_VERSION,拿到最小的那个版本号,比如当前版本是:1.2.3-SNAPSHOT,那么MAJOR_VERSION=**1.2 ,**UPDATED_VERSION=1+3=4

最后通过git进行提交到GitHub,在当中需要配置你的用户名和邮箱

stage('Update version') {
    steps {
        script {
            JAR_FINAL_VERSION = sh (
                script: 'mvn spring-boot:build-info | grep Building | awk \'{split(\$0,r," "); print r[4]}\'',
                returnStdout: true
            ).trim()
            MAJOR_VERSION = sh (
                script: "echo ${JAR_FINAL_VERSION} | awk '{split(\$0,r,\"-\"); print r[1]}' | awk '{split(\$0,r,\".\"); print r[1] \".\" r[2]}\' ",
                returnStdout: true
            ).trim()
            UPDATED_VERSION = sh (
                script: "echo ${JAR_FINAL_VERSION} | awk '{split(\$0,r,\"-\"); print r[1]}' | awk '{split(\$0,r,\".\"); print r[3]}' | awk '{value=1+\$1} END{print value}' ",
                returnStdout: true
            ).trim()

            sh "git branch -D ${params.GIT_Branch} || true"
            sh "git checkout -b ${params.GIT_Branch} || true"
            sh "mvn versions:set -DnewVersion=${MAJOR_VERSION}.${UPDATED_VERSION}-SNAPSHOT"
            sh "git config user.email [email protected]"
            sh "git config user.name xxxxx"
            sh "git commit -a -m 'Triggered Build: update pom version'"
            sh "git push -u origin ${params.GIT_Branch}"
        }
    }
}
# Jenkins 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×