1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00
sap-jenkins-library/vars/piperStageWrapper.groovy
Oliver Nocon e556fba950
add wrapper for stages contained in library (#341)
* add wrapper for stages contained in library

`piperStageWrapper` provides a wrapper for stages which we may include into the library.
It will take care about extension capabilities, locking, node handling, ... which should be a capability of every stage contained in the library.
2018-12-12 11:45:11 +01:00

109 lines
4.7 KiB
Groovy

import com.sap.piper.Utils
import com.sap.piper.ConfigurationHelper
import com.sap.piper.ConfigurationLoader
import com.sap.piper.k8s.ContainerMap
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
@Field String STEP_NAME = 'piperStageWrapper'
void call(Map parameters = [:], body) {
final script = checkScript(this, parameters) ?: this
def utils = parameters.juStabUtils ?: new Utils()
def stageName = parameters.stageName?:env.STAGE_NAME
// load default & individual configuration
Map config = ConfigurationHelper.newInstance(this)
.loadStepDefaults()
.mixin(ConfigurationLoader.defaultStageConfiguration(this, stageName))
.mixinGeneralConfig(script.commonPipelineEnvironment)
.mixinStageConfig(script.commonPipelineEnvironment, stageName)
.mixin(parameters)
.addIfEmpty('stageName', stageName)
.dependingOn('stageName').mixin('ordinal')
.use()
stageLocking(config) {
def containerMap = ContainerMap.instance.getMap().get(stageName) ?: [:]
if (Boolean.valueOf(env.ON_K8S) && containerMap.size() > 0) {
withEnv(["POD_NAME=${stageName}"]) {
dockerExecuteOnKubernetes(script: script, containerMap: containerMap) {
executeStage(script, body, stageName, config, utils)
}
}
} else {
node(config.nodeLabel) {
executeStage(script, body, stageName, config, utils)
}
}
}
}
private void stageLocking(Map config, Closure body) {
if (config.stageLocking) {
lock(resource: "${env.JOB_NAME}/${config.ordinal}", inversePrecedence: true) {
milestone config.ordinal
body()
}
} else {
body()
}
}
private void executeStage(script, originalStage, stageName, config, utils) {
boolean projectExtensions
boolean globalExtensions
def startTime = System.currentTimeMillis()
try {
//Add general stage stashes to config.stashContent
config.stashContent += script.commonPipelineEnvironment.configuration.stageStashes?.get(stageName)?.unstash ?: []
utils.unstashAll(config.stashContent)
/* Defining the sources where to look for a project extension and a repository extension.
* Files need to be named like the executed stage to be recognized.
*/
def projectInterceptorFile = "${config.projectExtensionsDirectory}${stageName}.groovy"
def globalInterceptorFile = "${config.globalExtensionsDirectory}${stageName}.groovy"
projectExtensions = fileExists(projectInterceptorFile)
globalExtensions = fileExists(globalInterceptorFile)
// Pre-defining the real originalStage in body variable, might be overwritten later if extensions exist
def body = originalStage
// First, check if a global extension exists via a dedicated repository
if (globalExtensions) {
Script globalInterceptorScript = load(globalInterceptorFile)
echo "[${STEP_NAME}] Found global interceptor '${globalInterceptorFile}' for ${stageName}."
// If we call the global interceptor, we will pass on originalStage as parameter
body = {
globalInterceptorScript(body, stageName, config)
}
}
// Second, check if a project extension (within the same repository) exists
if (projectExtensions) {
Script projectInterceptorScript = load(projectInterceptorFile)
echo "[${STEP_NAME}] Running project interceptor '${projectInterceptorFile}' for ${stageName}."
// If we call the project interceptor, we will pass on body as parameter which contains either originalStage or the repository interceptor
projectInterceptorScript(body, stageName, config)
} else {
//TODO: assign projectInterceptorScript to body as done for globalInterceptorScript, currently test framework does not seem to support this case. Further investigations needed.
body()
}
} finally {
echo "Current build result in stage $stageName is ${script.currentBuild.currentResult}."
//Perform stashing of selected files in workspace
utils.stashList(script, script.commonPipelineEnvironment.configuration.stageStashes?.get(stageName)?.stashes ?: [])
deleteDir()
def duration = System.currentTimeMillis() - startTime
utils.pushToSWA([eventType: 'library-os-stage', stageName: stageName, stepParam1: "${script.currentBuild.currentResult}", stepParam2: "${startTime}", stepParam3: "${duration}", stepParam4: "${projectExtensions}", stepParam5: "${globalExtensions}"], config)
}
}