Pipeline as a Code using Jenkins 2

Pipeline as a Code using Jenkins 2

What we will be covering in this post:

Overview of Jenkins 2

Jenkins Pipeline Features

Jenkins Deployment/Environment

Pipeline as a Code using Jenkins 2
Ephemeral Jenkins Environment

Ideal Pipeline Flow

Pipeline as a Code using Jenkins 2
Ideal Jenkins Pipeline Flow

Pipeline — Jenkinsfile Sample

#!groovypipeline {agent {
  docker {
    image 'jenkinsslave:latest'
    registryUrl 'http://8598567586.dkr.ecr.us-west-2.amazonaws.com'
    registryCredentialsId 'ecr:us-east-1:3435443545-5546566-567765-3225'
    args '-v /home/centos/.ivy2:/home/jenkins/.ivy2:rw -v jenkins_opt:/usr/local/bin/opt -v jenkins_apijenkins:/home/jenkins/config -v jenkins_logs:/var/logs -v jenkins_awsconfig:/home/jenkins/.aws --privileged=true -u jenkins:jenkins'
  }
}
environment {
    APP_NAME = 'billing-rest'
    BUILD_NUMBER = "${env.BUILD_NUMBER}"
    IMAGE_VERSION="v_${BUILD_NUMBER}"
    GIT_URL="git@github.yourdomain.com:mpatel/${APP_NAME}.git"
    GIT_CRED_ID='izleka2IGSTDK+MiYOG3b3lZU9nYxhiJOrxhlaJ1gAA='
    REPOURL = 'cL5nSDa+49M.dkr.ecr.us-east-1.amazonaws.com'
    SBT_OPTS='-Xmx1024m -Xms512m'
    JAVA_OPTS='-Xmx1024m -Xms512m'
    WS_PRODUCT_TOKEN='FJbep9fKLeJa/Cwh7IJbL0lPfdYg7q4zxvALAxWPLnc='
    WS_PROJECT_TOKEN='zwzxtyeBntxX4ixHD1iE2dOr4DVFHPp7D0Czn84DEF4='
    HIPCHAT_TOKEN = 'SpVaURsSTcWaHKulZ6L4L+sjKxhGXCkjSbcqzL42ziU='
    HIPCHAT_ROOM = 'NotificationRoomName'
}

options {
    buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '10', numToKeepStr: '20'))
    timestamps()
    retry(3)
    timeout time:10, unit:'MINUTES'
}
parameters {
    string(defaultValue: "develop", description: 'Branch Specifier', name: 'SPECIFIER')
    booleanParam(defaultValue: false, description: 'Deploy to QA Environment ?', name: 'DEPLOY_QA')
    booleanParam(defaultValue: false, description: 'Deploy to UAT Environment ?', name: 'DEPLOY_UAT')
    booleanParam(defaultValue: false, description: 'Deploy to PROD Environment ?', name: 'DEPLOY_PROD')
}stages {
    stage("Initialize") {
        steps {
            script {
                notifyBuild('STARTED')
                echo "${BUILD_NUMBER} - ${env.BUILD_ID} on ${env.JENKINS_URL}"
                echo "Branch Specifier :: ${params.SPECIFIER}"
                echo "Deploy to QA? :: ${params.DEPLOY_QA}"
                echo "Deploy to UAT? :: ${params.DEPLOY_UAT}"
                echo "Deploy to PROD? :: ${params.DEPLOY_PROD}"
                sh 'rm -rf target/universal/*.zip'
            }
        }
    }
stage('Checkout') {
    steps {
        git branch: "${params.SPECIFIER}", url: "${GIT_URL}"
    }
}stage('Build') {
            steps {
                echo 'Run coverage and CLEAN UP Before please'
                sh '/usr/local/bin/opt/bin/sbtGitActivator; /usr/local/bin/opt/play-2.5.10/bin/activator -Dsbt.global.base=.sbt -Dsbt.ivy.home=/home/jenkins/.ivy2 -Divy.home=/home/jenkins/.ivy2 compile coverage test coverageReport coverageOff dist'
            }
        }stage('Publish Reports') {
    parallel {
        stage('Publish FindBugs Report') {
            steps {
                step([$class: 'FindBugsPublisher', canComputeNew: false, defaultEncoding: '', excludePattern: '', healthy: '', includePattern: '', pattern: 'target/scala-2.11/findbugs/report.xml', unHealthy: ''])
            }
        }
        stage('Publish Junit Report') {
            steps {
                junit allowEmptyResults: true, testResults: 'target/test-reports/*.xml'
            }
        }
        stage('Publish Junit HTML Report') {
            steps {
                publishHTML target: [
                        allowMissing: true,
                        alwaysLinkToLastBuild: false,
                        keepAll: true,
                        reportDir: 'target/reports/html',
                        reportFiles: 'index.html',
                        reportName: 'Test Suite HTML Report'
                ]
            }
        }
        stage('Publish Coverage HTML Report') {
            steps {
                publishHTML target: [
                        allowMissing: true,
                        alwaysLinkToLastBuild: false,
                        keepAll: true,
                        reportDir: 'target/scala-2.11/scoverage-report',
                        reportFiles: 'index.html',
                        reportName: 'Code Coverage'
                ]
            }
        }
        stage('Execute Whitesource Analysis') {
            steps {
                whitesource jobApiToken: '', jobCheckPolicies: 'global', jobForceUpdate: 'global', libExcludes: '', libIncludes: '', product: "${env.WS_PRODUCT_TOKEN}", productVersion: '', projectToken: "${env.WS_PROJECT_TOKEN}", requesterEmail: ''
            }
        }
        stage('SonarQube analysis') {
            steps {
                sh "/usr/bin/sonar-scanner"
            }
        }
        stage('ArchiveArtifact') {
            steps {
                archiveArtifacts '**/target/universal/*.zip'
            }
        }
    }
}

 stage('Docker Tag & Push') {
     steps {
         script {
             branchName = getCurrentBranch()
             shortCommitHash = getShortCommitHash()
             IMAGE_VERSION = "${BUILD_NUMBER}-" + branchName + "-" + shortCommitHash
             sh 'eval $(aws ecr get-login --no-include-email --region us-west-2)'
             sh "docker-compose build"
             sh "docker tag ${REPOURL}/${APP_NAME}:latest ${REPOURL}/${APP_NAME}:${IMAGE_VERSION}"
             sh "docker push ${REPOURL}/${APP_NAME}:${IMAGE_VERSION}"
             sh "docker push ${REPOURL}/${APP_NAME}:latest"

             sh "docker rmi ${REPOURL}/${APP_NAME}:${IMAGE_VERSION} ${REPOURL}/${APP_NAME}:latest"
         }
     }
 }stage('Deploy') {
    parallel {
        stage('Deploy to CI') {
            steps {
                echo "Deploying to CI Environment."
            }
        }

        stage('Deploy to QA') {
            when {
                expression {
                    params.DEPLOY_QA == true
                }
            }
            steps {
                echo "Deploy to QA..."
            }
        }
        stage('Deploy to UAT') {
            when {
                expression {
                    params.DEPLOY_UAT == true
                }
            }
            steps {
                echo "Deploy to UAT..."
            }
        }
        stage('Deploy to Production') {
            when {
                expression {
                    params.DEPLOY_PROD == true
                }
            }
            steps {
                echo "Deploy to PROD..."
            }
        }
    }
}}

    post {
        /*
         * These steps will run at the end of the pipeline based on the condition.
         * Post conditions run in order regardless of their place in the pipeline
         * 1. always - always run
         * 2. changed - run if something changed from the last run
         * 3. aborted, success, unstable or failure - depending on the status
         */
        always {
            echo "I AM ALWAYS first"
            notifyBuild("${currentBuild.currentResult}")
        }
        aborted {
            echo "BUILD ABORTED"
        }
        success {
            echo "BUILD SUCCESS"
            echo "Keep Current Build If branch is master"
//            keepThisBuild()
        }
        unstable {
            echo "BUILD UNSTABLE"
        }
        failure {
            echo "BUILD FAILURE"
        }
    }}def keepThisBuild() {
    currentBuild.setKeepLog(true)
    currentBuild.setDescription("Test Description")
}

def getShortCommitHash() {
    return sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
}

def getChangeAuthorName() {
    return sh(returnStdout: true, script: "git show -s --pretty=%an").trim()
}

def getChangeAuthorEmail() {
    return sh(returnStdout: true, script: "git show -s --pretty=%ae").trim()
}

def getChangeSet() {
    return sh(returnStdout: true, script: 'git diff-tree --no-commit-id --name-status -r HEAD').trim()
}

def getChangeLog() {
    return sh(returnStdout: true, script: "git log --date=short --pretty=format:'%ad %aN <%ae> %n%n%x09* %s%d%n%b'").trim()
}

def getCurrentBranch () {
    return sh (
            script: 'git rev-parse --abbrev-ref HEAD',
            returnStdout: true
    ).trim()
}

def isPRMergeBuild() {
    return (env.BRANCH_NAME ==~ /^PR-\d+$/)
}

def notifyBuild(String buildStatus = 'STARTED') {
    // build status of null means successful
    buildStatus = buildStatus ?: 'SUCCESS'

    def branchName = getCurrentBranch()
    def shortCommitHash = getShortCommitHash()
    def changeAuthorName = getChangeAuthorName()
    def changeAuthorEmail = getChangeAuthorEmail()
    def changeSet = getChangeSet()
    def changeLog = getChangeLog()

    // Default values
    def colorName = 'RED'
    def colorCode = '#FF0000'
    def subject = "${buildStatus}: '${env.JOB_NAME} [${env.BUILD_NUMBER}]'" + branchName + ", " + shortCommitHash
    def summary = "Started: Name:: ${env.JOB_NAME} \n " +
            "Build Number: ${env.BUILD_NUMBER} \n " +
            "Build URL: ${env.BUILD_URL} \n " +
            "Short Commit Hash: " + shortCommitHash + " \n " +
            "Branch Name: " + branchName + " \n " +
            "Change Author: " + changeAuthorName + " \n " +
            "Change Author Email: " + changeAuthorEmail + " \n " +
            "Change Set: " + changeSet

    if (buildStatus == 'STARTED') {
        color = 'YELLOW'
        colorCode = '#FFFF00'
    } else if (buildStatus == 'SUCCESS') {
        color = 'GREEN'
        colorCode = '#00FF00'
    } else {
        color = 'RED'
        colorCode = '#FF0000'
    }

    // Send notifications
    hipchatSend(color: color, notify: true, message: summary, token: "${env.HIPCHAT_TOKEN}",
        failOnError: true, room: "${env.HIPCHAT_ROOM}", sendAs: 'Jenkins', textFormat: true)if (buildStatus == 'FAILURE') {
        emailext attachLog: true, body: summary, compressLog: true, recipientProviders: [brokenTestsSuspects(), brokenBuildSuspects(), culprits()], replyTo: 'noreply@yourdomain.com', subject: subject, to: 'mpatel@yourdomain.com'
    }
}

Images in the following section display a visual representation of Pipeline using Classic or Blue Ocean view.

Pipeline as a Code using Jenkins 2
Classic Pipeline Stage View
Pipeline as a Code using Jenkins 2
Blue Ocean Pipeline Stage View

Pipeline plugin also provides a nice tool for snippet generator for each of your plugins. Displayed in below diagram.

Pipeline as a Code using Jenkins 2
Pipeline Snippet Generator

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/241053.html

(0)
上一篇 2022年3月28日 14:34
下一篇 2022年3月28日 15:18

相关推荐

发表回复

登录后才能评论