def call()

in vars/slingOsgiBundleBuild.groovy [3:136]


def call(Map params = [:]) {

    def globalConfig = [
        availableJDKs : [ 8: 'jdk_1.8_latest', 9: 'jdk_1.9_latest', 10: 'jdk_10_latest', 11: 'jdk_11_latest',
                          12: 'jdk_12_latest', 13: 'jdk_13_latest', 14: 'jdk_14_latest', 15: 'jdk_15_latest',
                          16: 'jdk_16_latest', 17: 'jdk_17_latest', 18: 'jdk_18_latest', 19: 'jdk_19_latest', 
                          20: 'jdk_20_latest', 21: 'jdk_21_latest', 22: 'jdk_22_latest'],
        mvnVersion : 'maven_3_latest',
        // maps values to node labels (available ones in https://cwiki.apache.org/confluence/display/INFRA/ci-builds.apache.org)
        availableOperatingSystems : ['windows' : 'Windows', 'linux': 'ubuntu', 'linux-arm': 'arm', 'ubuntu': 'ubuntu'],
        mainNodeLabel : 'ubuntu',
        githubCredentialsId: 'sling-github-token'
    ]

    def jobConfig = [
        jdks: [11,17],
        operatingSystems: ['linux','windows'],
        upstreamProjects: [],
        archivePatterns: [],
        mavenGoal: '',
        additionalMavenParams: '',
        rebuildFrequency: '@weekly',
        enabled: true,
        emailRecipients: [],
        sonarQubeEnabled: true,
        sonarQubeUseAdditionalMavenParams: true,
        sonarQubeAdditionalParams: ''
    ]
    boolean shouldDeploy = false
    node(globalConfig.mainNodeLabel) {
        timeout(time:5, unit: 'MINUTES') {
            stage('Init') {
                checkout scm
                def url
                if (isUnix()) {
                    sh "git clean -fdx"
                    url = sh(returnStdout: true, script: 'git config remote.origin.url').trim()
                } else {
                    bat "git clean -fdx"
                    url = bat(returnStdout: true, script: 'git config remote.origin.url').trim()
                }
                jobConfig.repoName = url.substring(url.lastIndexOf('/') + 1).replace('.git', '');
                if ( fileExists('.sling-module.json') ) {
                    overrides = readJSON file: '.sling-module.json'
                    echo "Jenkins overrides: ${overrides.jenkins}"
                    overrides.jenkins.each { key,value ->
                        jobConfig[key] = value;
                    }
                }
                echo "Final job config: ${jobConfig}"
                shouldDeploy = getShouldDeploy()
            }
        }
    }

    node(globalConfig.mainNodeLabel) {
        timeout(time:30, unit: 'MINUTES', activity: true) {
            stage('Configure Job') {
                def upstreamProjectsCsv = jobConfig.upstreamProjects ?
                    jsonArrayToCsv(jobConfig.upstreamProjects) : ''
                def jobTriggers = []
                if ( isOnMainBranch() )
                    jobTriggers.add(cron(jobConfig.rebuildFrequency))
                if ( upstreamProjectsCsv )
                    jobTriggers.add(upstream(upstreamProjects: upstreamProjectsCsv, threshold: hudson.model.Result.SUCCESS))

                properties([
                    pipelineTriggers(jobTriggers),
                    buildDiscarder(logRotator(numToKeepStr: '10'))
                ])
            }
        }
    }

    if ( jobConfig.enabled ) {
        def helper = new SlingJenkinsHelper()
        helper.runWithErrorHandling(jobConfig, {
            // the reference build is always the first one, and the only one to deploy, archive artifacts, etc
            // usually this is the build done with the oldest JDK version, to ensure maximum compatibility
            boolean isReferenceStage = true

            // contains the label as key and a closure to execute as value
            def stepsMap = [failFast: true] // fail-fast, https://stackoverflow.com/a/37356318
            def referenceJdkVersion
            // parallel execution of all build jobs
            jobConfig.jdks.each { jdkVersion -> 
                jobConfig.operatingSystems.each { operatingSystem ->
                    stageDefinition = defineStage(globalConfig, jobConfig, jdkVersion, operatingSystem, isReferenceStage, shouldDeploy)
                    if ( isReferenceStage ) {
                        referenceJdkVersion = jdkVersion
                    }
                    stepsMap["Build (Java ${jdkVersion} on ${operatingSystem})"] = stageDefinition
                    isReferenceStage = false
                    currentBuild.result = "SUCCESS"
                }
            }

            // do a quick sanity check first without tests if multiple parallel builds are required
            // the stepsMap has at least one entry due to the failFast entry
            if ( stepsMap.size() > 2 ) {
                node(globalConfig.mainNodeLabel) {
                    stage("Sanity Check") {
                        checkout scm
                        withMaven(maven: globalConfig.mvnVersion,
                            jdk: jenkinsJdkLabel(referenceJdkVersion, globalConfig),
                            publisherStrategy: 'EXPLICIT') {
                                String mvnCommand = "mvn -U -B -e clean compile ${additionalMavenParams(jobConfig)}"
                                if (isUnix()) {
                                    sh mvnCommand
                                } else {
                                    bat mvnCommand
                                }
                            }
                    }
                }
            }

            // execute the actual Maven builds
            parallel stepsMap

            // last stage is deploy
            def goal = jobConfig.mavenGoal ?: "deploy"
            if ( goal == "deploy" && shouldDeploy ) {
                node(globalConfig.mainNodeLabel) {
                    stage("Deploy to Nexus") {
                        deployToNexus(globalConfig)
                    }
                }
            }
        })
    } else {
        echo "Job is disabled, not building"
    }
}