2020-03-30 14:31:24 +02:00
|
|
|
import com.sap.piper.BashUtils
|
2020-04-28 07:42:02 +02:00
|
|
|
import com.sap.piper.DebugReport
|
2020-03-30 14:31:24 +02:00
|
|
|
import com.sap.piper.DefaultValueCache
|
2020-03-17 10:19:09 +02:00
|
|
|
import com.sap.piper.JenkinsUtils
|
2020-04-24 10:41:49 +02:00
|
|
|
import com.sap.piper.MapUtils
|
2020-03-17 10:19:09 +02:00
|
|
|
import com.sap.piper.PiperGoUtils
|
|
|
|
import com.sap.piper.Utils
|
|
|
|
|
|
|
|
import static com.sap.piper.Prerequisites.checkScript
|
|
|
|
|
|
|
|
void call(Map parameters = [:], stepName, metadataFile, List credentialInfo, failOnMissingReports = false, failOnMissingLinks = false) {
|
|
|
|
|
|
|
|
handlePipelineStepErrors(stepName: stepName, stepParameters: parameters) {
|
|
|
|
|
|
|
|
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')
|
|
|
|
|
|
|
|
new PiperGoUtils(this, utils).unstashPiperBin()
|
|
|
|
utils.unstash('pipelineConfigAndTests')
|
|
|
|
script.commonPipelineEnvironment.writeToDisk(script)
|
|
|
|
|
|
|
|
writeFile(file: ".pipeline/tmp/${metadataFile}", text: libraryResource(metadataFile))
|
|
|
|
|
2020-04-24 10:41:49 +02:00
|
|
|
// 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)
|
|
|
|
|
2020-03-17 10:19:09 +02:00
|
|
|
withEnv([
|
|
|
|
"PIPER_parametersJSON=${groovy.json.JsonOutput.toJson(stepParameters)}",
|
2020-04-28 07:42:02 +02:00
|
|
|
"PIPER_correlationID=${env.BUILD_URL}",
|
2020-03-17 10:19:09 +02:00
|
|
|
//ToDo: check if parameters make it into docker image on JaaS
|
|
|
|
]) {
|
2020-03-31 13:10:02 +02:00
|
|
|
String defaultConfigArgs = getCustomDefaultConfigsArg()
|
|
|
|
String customConfigArg = getCustomConfigArg(script)
|
|
|
|
|
2020-03-17 10:19:09 +02:00
|
|
|
// get context configuration
|
2020-03-31 13:10:02 +02:00
|
|
|
Map config = readJSON(text: sh(returnStdout: true, script: "./piper getConfig --contextConfig --stepMetadata '.pipeline/tmp/${metadataFile}'${defaultConfigArgs}${customConfigArg}"))
|
2020-03-17 10:19:09 +02:00
|
|
|
echo "Config: ${config}"
|
|
|
|
|
|
|
|
dockerWrapper(script, config) {
|
2020-04-28 07:42:02 +02:00
|
|
|
handleErrorDetails(stepName) {
|
|
|
|
credentialWrapper(config, credentialInfo) {
|
|
|
|
sh "./piper ${stepName}${defaultConfigArgs}${customConfigArg}"
|
|
|
|
}
|
|
|
|
jenkinsUtils.handleStepResults(stepName, failOnMissingReports, failOnMissingLinks)
|
|
|
|
script.commonPipelineEnvironment.readFromDisk(script)
|
2020-03-17 10:19:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-30 14:31:24 +02:00
|
|
|
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}"
|
|
|
|
}
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
|
|
|
static String getCustomConfigArg(def script) {
|
|
|
|
if (script?.commonPipelineEnvironment?.configurationFile
|
2020-03-31 15:16:18 +02:00
|
|
|
&& script.commonPipelineEnvironment.configurationFile != '.pipeline/config.yml'
|
2020-03-30 14:31:24 +02:00
|
|
|
&& script.commonPipelineEnvironment.configurationFile != '.pipeline/config.yaml') {
|
|
|
|
return " --customConfig ${BashUtils.quoteAndEscape(script.commonPipelineEnvironment.configurationFile)}"
|
|
|
|
}
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
2020-03-17 10:19:09 +02:00
|
|
|
void dockerWrapper(script, config, body) {
|
|
|
|
if (config.dockerImage) {
|
|
|
|
dockerExecute(
|
|
|
|
script: script,
|
|
|
|
dockerImage: config.dockerImage,
|
|
|
|
dockerWorkspace: config.dockerWorkspace,
|
2020-03-20 19:20:52 +02:00
|
|
|
dockerOptions: config.dockerOptions,
|
2020-03-17 10:19:09 +02:00
|
|
|
//ToDo: add additional dockerExecute parameters
|
|
|
|
) {
|
|
|
|
body()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
body()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void credentialWrapper(config, List credentialInfo, body) {
|
|
|
|
if (credentialInfo.size() > 0) {
|
|
|
|
def creds = []
|
2020-04-03 16:34:40 +02:00
|
|
|
def sshCreds = []
|
2020-03-17 10:19:09 +02:00
|
|
|
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
|
2020-04-03 16:34:40 +02:00
|
|
|
case "ssh":
|
|
|
|
if (config[cred.id]) sshCreds.add(config[cred.id])
|
|
|
|
break
|
2020-03-17 10:19:09 +02:00
|
|
|
default:
|
|
|
|
error ("invalid credential type: ${cred.type}")
|
|
|
|
}
|
|
|
|
}
|
2020-04-03 16:34:40 +02:00
|
|
|
|
|
|
|
if (sshCreds.size() > 0) {
|
|
|
|
sshagent (sshCreds) {
|
|
|
|
withCredentials(creds) {
|
|
|
|
body()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
withCredentials(creds) {
|
|
|
|
body()
|
|
|
|
}
|
2020-03-17 10:19:09 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
body()
|
|
|
|
}
|
|
|
|
}
|
2020-04-28 07:42:02 +02:00
|
|
|
|
|
|
|
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.message}"
|
|
|
|
}
|
|
|
|
error "[${stepName}] Step execution failed. Error: ${ex}"
|
|
|
|
}
|
|
|
|
}
|