gitlab-jenkins-ci-cd-groovy-deploy-script-part-3.md
devcondadevopsgitlab-jenkins-ci-cd-groovy-deploy-script-part-3.md

GitLab + Jenkins CI/CD: Groovy Deploy Script (Part 3)

Written by

in

Backup post for a company build and deploy script I set up earlier.

Related GitLab Jenkins CI/CD series:

  • GitLab Jenkins CI/CD Pipeline Setup (1/3)
  • GitLab Jenkins CI/CD Pipeline Setup (2/3)
  • GitLab Jenkins CI/CD Pipeline Nexacro Setup (3/3)

Unlike the Nexacro project, this one does not even use Maven, so I had to write a Groovy pipeline script. The source component accepts at most 5,000 characters, so the script is split across sections below.

Pipeline script

  • 1. Fetch repository source
  • 2. Diff against the last deployed source and find changes
  • 3. Build Java files and copy them to the deploy folder (longest stage)
  • 4. Apply changes to the deploy path
  • 5. Save the final deployed commit ID to a file
  • 6. Restart WAS
  • 7. Write logs

1. Fetch repository source / 2. Find changes

node {
    def lastDeployCommitId  // last successfully deployed commit ID (stored in lastDeployCommitId file)
    def nowDeployCommitId   // current git HEAD commit ID to deploy
    def workDir = 'D:\\jenkins\\deploy\\'   // local path where files are prepared for deploy
    def libDir = 'sgerp.war\\WEB-INF\\lib'  // local build lib path
    def classesDir = 'D:\\jenkins\\build\\classes'  // local build output path
    def logDir = 'D:\\jenkins\\log'  // log dir
    def target_server = 'jbossnatg@192.168.50.222'
    def target_server_root = 'root@192.168.50.222'
    def wasPath = '/oradata/jbossnatg/jboss6.1.0/server/NATGERP/deploy/sgerp.war/'  // replace NATGERP with wasList
    //def wasList = ['natgerp1', 'natgerp2', 'natgpos1', 'natgpos2', 'natgint1', 'natgint2', 'natgwms1', 'natgwms2']
    def wasList = ['natgerp1']
    def wasBinPath = '/oradata/jbossnatg/jboss6.1.0/bin/NATGERP.sh'  // replace NATGERP with wasList
    def username
    def commitmsg

    // 1. Fetch repository source
    stage('Connect source') {
        // Get some code from a GitHub repository
        // Pull source from the git repository
        git url: 'http://192.168.0.111/natgerp/natgerp.git',
            branch: 'develop',
            credentialsId: 'GITLAB_ROOT'
    }

    // 2. Diff against last deployed source and find changes
    stage('Inspect changes') {
        // Check file exists
        // Check whether the file that stores the last deployed commit ID exists
        def existsFile = fileExists 'lastDeployCommitId'
        if( existsFile ) {
            lastDeployCommitId = (readFile(file: 'lastDeployCommitId', encoding: 'UTF-8')).trim()
        } else {
            lastDeployCommitId = powershell(script:'git rev-parse HEAD', returnStdout: true).trim()
        }

        nowDeployCommitId = powershell(script:'git rev-parse HEAD', returnStdout: true).trim()
        username = powershell(script:' git log -1 --pretty=format:"%an"', returnStdout: true).trim()
        commitmsg = powershell(script:' git log -1 --pretty=format:"%s"', returnStdout: true).trim()

        println('lastCommit='+lastDeployCommitId)
        println('currentCommit='+nowDeployCommitId)

        // Detect modified files and save the list
        bat(script: """
            git diff --name-only --output=modifiedList --diff-filter=AM ${lastDeployCommitId}..${nowDeployCommitId}
        """)

        // Detect deleted files and save the list
        bat(script: """
            git diff --name-only --output=deletedList --diff-filter=D ${lastDeployCommitId}..${nowDeployCommitId}
        """)
    }

3. Build Java files and copy to deploy folder

    // 3. Build Java files and copy to build/deploy folders
    stage('Build and copy deploy files') {
        // Process modified files
        // Read the file and apply modified content
        isModified = (readFile(file: 'modifiedList', encoding: 'UTF-8')).trim()
        if(isModified) {
            println("Modified files exist")
            dir("""${classesDir}""") {
                withAnt(jdk: 'jdk1.6') {
                    def lines = isModified.readLines()
                    // Exception handling for Douzone batch job services deploying together
                    // bat(script: """
                    //     javac -d D:\\jenkins\\build\\classes -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;C:\\ProgramData\\Jenkins\\.jenkins\\workspace\\NATGERP_TEST\\sgerp.war\\WEB-INF\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; C:\\ProgramData\\Jenkins\\.jenkins\\workspace\\NATGERP_TEST\\sgerp.war\\WEB-INF\\src\\com\\schedule\\Schedule.java
                    //     javac -d D:\\jenkins\\deploy\\ -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;C:\\ProgramData\\Jenkins\\.jenkins\\workspace\\NATGERP_TEST\\sgerp.war\\WEB-INF\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; C:\\ProgramData\\Jenkins\\.jenkins\\workspace\\NATGERP_TEST\\sgerp.war\\WEB-INF\\src\\com\\schedule\\Schedule.java
                    //
                    // """
                    // )
                    for(line in lines) {
                        line = line.replace('/', '\\')
                        if(line.substring(line.length()-5) == '.java' && line.substring(line.length()-12) != 'Command.java' && line.substring(line.length()-12) != 'Service.java'){
                            println("Build core Java file")
                            bat(script: """
                                javac -d ${classesDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${line}
                                javac -d ${workDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${line}
                            """
                            )
                        }
                    }
                    for(line in lines) {
                        line = line.replace('/', '\\')
                        println(line)
                        if(line.length() > 12 && line.substring(line.length()-12) == 'Command.java'){
                            println("Build Java file")
                            def service = line.replace('\\command\\', '\\service\\').replace('Command.java', 'Service.java')
                            //emerge
                            bat(script: """
                                javac -d ${classesDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\sgerp.war\\WEB-INF\\src\\com\\erp\\service\\commonDS\\CommonDsService.java
                                javac -d ${workDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\sgerp.war\\WEB-INF\\src\\com\\erp\\service\\commonDS\\CommonDsService.java
                                javac -d ${classesDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\sgerp.war\\WEB-INF\\src\\com\\erp\\service\\fs\\dsdv\\Dsdv0010Service.java
                                javac -d ${workDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\sgerp.war\\WEB-INF\\src\\com\\erp\\service\\fs\\dsdv\\Dsdv0010Service.java
                            """
                            )
                            bat(script: """
                                javac -d ${classesDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${service}
                                javac -d ${workDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${service}
                            """
                            )
                            bat(script: """
                                javac -d ${classesDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${line}
                                javac -d ${workDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${line}
                            """
                            )
                        } else if(line.substring(line.length()-5) == '.java'){
                            println("Build Java file")
                            bat(script: """
                                javac -d ${classesDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${line}
                                javac -d ${workDir} -encoding UTF8 -cp D:\\NG_PROJECT\\bin\\jdk1.6\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\*;D:\\NG_PROJECT\\bin\\jdk1.6\\jre\\lib\\ext\\*;${env.WORKSPACE}\\${libDir}\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\common\\lib\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\server\\natgerp\\deployers\\resteasy.deployer\\*;D:\\NG_PROJECT\\bin\\jboss-6.1.0.Final\\client\\*; ${env.WORKSPACE}\\${line}
                            """
                            )
                        } else{
                            println('Not a Java file')
                            bat(script: """
                                echo f | xcopy /i /y "${env.WORKSPACE}\\${line}" "${workDir}${line}"
                            """
                            )
                        }
                    }
                }
            }
        }
    }

4. Apply changes to the deploy path

    // 4. Apply content to the deploy path
    stage('Apply to deploy path') {
        // Process deleted files
        // Read the file and apply deletions
        isDeleted = (readFile(file: 'deletedList', encoding: 'UTF-8')).trim()
        if(isDeleted) {
            println("Deleted files to apply exist")
            def lines = isDeleted.readLines()
            for(line in lines) {
                def deployFile = line.replace('\\', '/').replace('sgerp.war/', '')
                //println(line)
                for(was in wasList){
                    def wasName = wasPath.replace('NATGERP', was)
                    if(line.substring(line.length()-5) == '.java'){
                        def classDeployFileServer = deployFile.replace('src', 'classes').replace('.java', '.class')
                        bat(script: """
                            ssh ${target_server} "rm -vf ${wasName}/${classDeployFileServer}"
                        """
                        )
                    }else{
                        bat(script: """
                            ssh ${target_server} "rm -vf ${wasName}/${deployFile}"
                        """
                        )
                    }
                }
            }
        } else {
            println("No deleted files to apply")
        }

        // Process modified files
        // Read the file and apply modifications
        isModified = (readFile(file: 'modifiedList', encoding: 'UTF-8')).trim()
        if(isModified) {
            println("Modified files to apply exist")
            def lines = isModified.readLines()
            for(line in lines) {
                def deployFile = line.replace('\\', '/').replace('sgerp.war/', '')
                def splitPath = deployFile.split("/")
                def filename = splitPath[splitPath.length-1]
                def exceptFilename = deployFile.replace(filename, '')
                for(was in wasList){
                    def wasName = wasPath.replace('NATGERP', was)
                    if(line.substring(line.length()-5) == '.java'){
                        def classDeployFile = deployFile.replace('WEB-INF/src/', '').replace('src', 'classes').replace('.java', '.class')
                        def classDeployFileServer = deployFile.replace('src', 'classes').replace('.java', '.class')
                        def classSplitPath = classDeployFileServer.split("/")
                        def classFilename = classSplitPath[classSplitPath.length-1]
                        def exceptClassFilename = classDeployFileServer.replace(classFilename, '')
                        bat(script: """
                            ssh ${target_server} "mkdir -p ${wasName}/${exceptClassFilename}"
                            scp -r ${workDir}\\${classDeployFile} ${target_server}:${wasName}/${classDeployFileServer}
                        """
                        )
                    }else{
                        bat(script: """
                            ssh ${target_server} "mkdir -p ${wasName}/${exceptFilename}"
                            scp -r "${workDir}\\${line}" "${target_server}:${wasName}${deployFile}"
                        """
                        )
                    }
                }
            }
        } else {
            println("No modified files to apply")
        }
    }

5. Save final commit ID / 6. Restart WAS / 7. Write logs

    stage('Write final commit') {
        writeFile(file: 'lastDeployCommitId', text:nowDeployCommitId, encoding: 'UTF-8')
        bat(script: """
            rd /s /q ${workDir}
            md ${workDir}
        """
        )
    }

    // 6. restart was
    stage('Restart WAS') {
        // Process modified files
        // Read the file and apply modified content
        isModified = (readFile(file: 'modifiedList', encoding: 'UTF-8')).trim()
        if(isModified) {
            println("WAS restart required")
            for(was in wasList){
                def wasName = wasBinPath.replace('NATGERP', was)
                def wasStopName = wasBinPath.replace('NATGERP', was+'stop')
                bat(script: """
                    ssh ${target_server_root} "su - jbossnatg -c ${wasStopName};su - jbossnatg -c ${wasName}"
                """
                )
            }
            println("complete")
        } else {
            println("WAS restart not required")
        }
    }

    // 7. Write logs
    stage('Write logs') {
        isDeleted = (readFile(file: 'deletedList', encoding: 'UTF-8')).trim()
        if(isDeleted) {
            def lines = isDeleted.readLines()
            dir("""${logDir}""") {
                for(line in lines) {
                    bat(script: """
                        echo ${nowDeployCommitId}, %date% %time%, ${username}, [DEL], ${line}, ${commitmsg} >> natgerp_develop.txt
                    """
                    )
                }
            }
        }
        isModified = (readFile(file: 'modifiedList', encoding: 'UTF-8')).trim()
        if(isModified) {
            def lines = isModified.readLines()
            dir("""${logDir}""") {
                for(line in lines) {
                    bat(script: """
                        echo ${nowDeployCommitId}, %date% %time%, ${username}, [MOD], ${line}, ${commitmsg} >> natgerp_develop.txt
                    """
                    )
                }
            }
        }
    }
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *