Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Organizing Jenkins Libraries

We are using Jenkins Shared Libraries in our pipeline development. We have written quite a few libraries inside it and now we want to organize it little better. Is it possible to have folder structure within vars folder of jenkins shared libraries?

like image 323
IT-Sheriff Avatar asked Jun 03 '26 19:06

IT-Sheriff


1 Answers

1) Shared library project folder structure:

enter image description here

As above picture, you can organize folder structure in src folder, just like organize java package.

Then import them inside vars folder where we declare global variable.

2) Content of vars/acidReleaseProcess.groovy:

#!groovy

import com.fmr.pipeline.AcidReleaseProcess

def relProcess

/**
 * Create a instance of class: AcidReleaseProcess
 * 
 * @param  appName uDeploy Application Name
 * @param  compName uDeploy Component Name
 * @param  compVersion component version to deploy
 * @return A self reference
 */
def call(appName, compName, compVersion) {
    relProcess = new AcidReleaseProcess(this, appName, compName, compVersion)   
    return this
}

/**
 * Execute Install, Go Live and Stop process on specify env
 * 
 * @param  envName name of environment to delpoy, exmaple: 'DIT', 'PAC', 'XQ1'
 */
def blueGreenDeploy(envName) {
    relProcess.deployToPassive(envName)
    relProcess.swapPassiveToActive(envName)
    relProcess.stopPassive(envName)
}

3) com.fmr.pipeline.AcidReleaseProcess.groovy

class AcidReleaseProcess implements Serializable {

    def script, appName, uDeployVers, passiveGroup = [:]

    AcidReleaseProcess(script, appName, compName, compVersion) {
        this.script = script 
        this.appName = appName
        this.uDeployVers = compName + ":" + compVersion
    }

    def deployToPassive(envName) {

        script.echo "Checking uDeploy environment ${envName} group state"

        script.sh 'docker pull ...'

        script.withCredentials([script.string(credentialsId: '<...>', variable: 'UDEPLOY_AUTH_TOKEN')]) {

            def group1_state = script.sh(
                        returnStdout: true, 
                        script: "docker run --rm -i ... \
                                    -a ${appName} \
                                    -e ${envName}-${group1} " + '-t ${UDEPLOY_AUTH_TOKEN}'
                    ).trim()

            def group2_state = script.sh(
                        returnStdout: true, 
                        script: "docker run --rm -i ...y \
                                    -a ${appName} \
                                    -e ${envName}-${group2} " + '-t ${UDEPLOY_AUTH_TOKEN}'
                    ).trim()

            script.echo "${envName}-${group1} is ${group1_state}, ${envName}-${group2} is ${group2_state}"

            if("${group1_state}" == "Live" && "${group2_state}" == "Live") {

                script.echo "Environment: ${envName}, ${group1} and ${group2} both are Live," +  
                     "only allow install on Non-Live environment"

                script.sh 'exit 1'
            } 

            def groupName = "${group1_state}" != "Live" ? group1 : group2

            passiveGroup[envName] = groupName
        }


        def uDeployEnv = envName + '-' + passiveGroup[envName]

        script.echo "Install on ${uDeployEnv}"

        script.step([
            $class  : 'UCDeployPublisher',
            siteName: 'pi_udeploy_srvpiudupload',
            deploy  : [
                    $class:             'com.urbancode.jenkins.plugins.ucdeploy.DeployHelper$DeployBlock',
                    deployApp:          appName,
                    deployEnv:          uDeployEnv,
                    deployProc:         UDEPLOY_INSTALL_PROC_NAME,
                    deployVersions:     uDeployVers,
                    deployOnlyChanged:  false
            ]
        ])
    }
}

4) we should keep content of files in vars folder as simple as possible, and organize reuse-able or complex code into class file under src folder.

5) some tips:

  1. Pass-down pipeline object to class in src folder

    relProcess = new AcidReleaseProcess(this, appName, compName, compVersion) // this is the pipeline object

  2. Store the pipeline object in class contructor function AcidReleaseProcess(script, appName, compName, compVersion) { this.script = script // script here is the pipeline object

  3. All global name need prefix with the pipeline object: script

    sh -> script.sh echo -> script.echo with... -> script.with... string -> script.string etc...

like image 91
yong Avatar answered Jun 08 '26 00:06

yong



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!