1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00
sap-jenkins-library/vars/piperExecuteBin.groovy
Stephan Aßmus 56699ab019
Run artifactPrepareVersion in maven container if necessary (#1634)
* The metadata for artifactPrepareVersion-go specifies a container for when the buildTool is maven.
* The alias to 'mavenExecute' was removed. The problem with this is that when a section containers is included in the metadata, dockerImage will always be picked up from mavenExecute, the conditional dependency on buildTool will not even be considered. Parameters such as m2Path, projectSettingsFile and globalSettingsFile should be configured in general/maven if necessary.
* When the step ends up being executed within dockerExecuteOnKubernetes, we need to preserve the .git folder. This folder would normally be excluded by the default excludes of the stash step. There was already a comment that suppressing this behavior by passing useDefaultExcludes: false was problematic (unfortunately without going into details), so I've added a new parameter to dockerExecute and dockerExecuteOnKubernetes named stashNoDefaultExcludes (note the reverted meaning to ease preserving the default behavior when this parameter is not provided). This parameter is passed to piperExecuteBin from the artifactPreferVersion groovy wrapper.
2020-06-08 17:08:05 +02:00

186 lines
7.1 KiB
Groovy

import com.sap.piper.BashUtils
import com.sap.piper.DebugReport
import com.sap.piper.DefaultValueCache
import com.sap.piper.JenkinsUtils
import com.sap.piper.MapUtils
import com.sap.piper.PiperGoUtils
import com.sap.piper.Utils
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
@Field String STEP_NAME = getClass().getName()
void call(Map parameters = [:], stepName, metadataFile, List credentialInfo, failOnMissingReports = false, failOnMissingLinks = false, failOnError = false) {
handlePipelineStepErrorsParameters = [stepName: stepName, stepParameters: parameters]
if (failOnError) {
handlePipelineStepErrorsParameters.failOnError = true
}
handlePipelineStepErrors(handlePipelineStepErrorsParameters) {
def stepParameters = [:].plus(parameters)
def script = checkScript(this, parameters) ?: this
stepParameters.remove('script')
def utils = parameters.juStabUtils ?: new Utils()
stepParameters.remove('juStabUtils')
def jenkinsUtils = parameters.jenkinsUtilsStub ?: new JenkinsUtils()
stepParameters.remove('jenkinsUtilsStub')
def piperGoPath = parameters.piperGoPath ?: './piper'
stepParameters.remove('piperGoPath')
def piperGoUtils = parameters.piperGoUtils ?: new PiperGoUtils(this, utils)
stepParameters.remove('piperGoUtils')
piperGoUtils.unstashPiperBin()
utils.unstash('pipelineConfigAndTests')
script.commonPipelineEnvironment.writeToDisk(script)
writeFile(file: ".pipeline/tmp/${metadataFile}", text: libraryResource(metadataFile))
// When converting to JSON and back again, entries which had a 'null' value will now have a value
// of type 'net.sf.json.JSONNull', for which the Groovy Truth resolves to 'true' in for example if-conditions
stepParameters = MapUtils.pruneNulls(stepParameters)
withEnv([
"PIPER_parametersJSON=${groovy.json.JsonOutput.toJson(stepParameters)}",
"PIPER_correlationID=${env.BUILD_URL}",
//ToDo: check if parameters make it into docker image on JaaS
]) {
String defaultConfigArgs = getCustomDefaultConfigsArg()
String customConfigArg = getCustomConfigArg(script)
echo "PIPER_parametersJSON: ${groovy.json.JsonOutput.toJson(stepParameters)}"
// get context configuration
Map config
handleErrorDetails(stepName) {
config = readJSON(text: sh(returnStdout: true, script: "${piperGoPath} getConfig --contextConfig --stepMetadata '.pipeline/tmp/${metadataFile}'${defaultConfigArgs}${customConfigArg}"))
echo "Context Config: ${config}"
}
if (parameters.stashNoDefaultExcludes) {
// Merge this parameter which is only relevant in Jenkins context
// (for dockerExecuteOnKubernetes step) and go binary doesn't know about
config.stashNoDefaultExcludes = parameters.stashNoDefaultExcludes
}
dockerWrapper(script, config) {
handleErrorDetails(stepName) {
credentialWrapper(config, credentialInfo) {
sh "${piperGoPath} ${stepName}${defaultConfigArgs}${customConfigArg}"
}
jenkinsUtils.handleStepResults(stepName, failOnMissingReports, failOnMissingLinks)
script.commonPipelineEnvironment.readFromDisk(script)
}
}
}
}
}
static String getCustomDefaultConfigs() {
// The default config files were extracted from merged library
// resources by setupCommonPipelineEnvironment.groovy into .pipeline/.
List customDefaults = DefaultValueCache.getInstance().getCustomDefaults()
for (int i = 0; i < customDefaults.size(); i++) {
customDefaults[i] = BashUtils.quoteAndEscape(".pipeline/${customDefaults[i]}")
}
return customDefaults.join(',')
}
static String getCustomDefaultConfigsArg() {
String customDefaults = getCustomDefaultConfigs()
if (customDefaults) {
return " --defaultConfig ${customDefaults} --ignoreCustomDefaults"
}
return ''
}
static String getCustomConfigArg(def script) {
if (script?.commonPipelineEnvironment?.configurationFile
&& script.commonPipelineEnvironment.configurationFile != '.pipeline/config.yml'
&& script.commonPipelineEnvironment.configurationFile != '.pipeline/config.yaml') {
return " --customConfig ${BashUtils.quoteAndEscape(script.commonPipelineEnvironment.configurationFile)}"
}
return ''
}
void dockerWrapper(script, config, body) {
if (config.dockerImage) {
dockerExecute(
script: script,
dockerImage: config.dockerImage,
dockerWorkspace: config.dockerWorkspace,
dockerOptions: config.dockerOptions,
stashNoDefaultExcludes : config.stashNoDefaultExcludes,
//ToDo: add additional dockerExecute parameters
) {
body()
}
} else {
body()
}
}
void credentialWrapper(config, List credentialInfo, body) {
if (credentialInfo.size() > 0) {
def creds = []
def sshCreds = []
credentialInfo.each { cred ->
switch(cred.type) {
case "file":
if (config[cred.id]) creds.add(file(credentialsId: config[cred.id], variable: cred.env[0]))
break
case "token":
if (config[cred.id]) creds.add(string(credentialsId: config[cred.id], variable: cred.env[0]))
break
case "usernamePassword":
if (config[cred.id]) creds.add(usernamePassword(credentialsId: config[cred.id], usernameVariable: cred.env[0], passwordVariable: cred.env[1]))
break
case "ssh":
if (config[cred.id]) sshCreds.add(config[cred.id])
break
default:
error ("invalid credential type: ${cred.type}")
}
}
if (sshCreds.size() > 0) {
sshagent (sshCreds) {
withCredentials(creds) {
body()
}
}
} else {
withCredentials(creds) {
body()
}
}
} else {
body()
}
}
void handleErrorDetails(String stepName, Closure body) {
try {
body()
} catch (ex) {
def errorDetailsFileName = "${stepName}_errorDetails.json"
if (fileExists(file: errorDetailsFileName)) {
def errorDetails = readJSON(file: errorDetailsFileName)
def errorCategory = ""
if (errorDetails.category) {
errorCategory = " (category: ${errorDetails.category})"
DebugReport.instance.failedBuild.category = errorDetails.category
}
error "[${stepName}] Step execution failed${errorCategory}. Error: ${errorDetails.error?:errorDetails.message}"
}
error "[${stepName}] Step execution failed. Error: ${ex}, please see log file for more details."
}
}