1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00
sap-jenkins-library/vars/piperPipelineStageConfirm.groovy
2020-05-18 12:21:05 +02:00

102 lines
4.2 KiB
Groovy

import com.sap.piper.ConfigurationHelper
import com.sap.piper.GenerateStageDocumentation
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
@Field String STEP_NAME = getClass().getName()
@Field Set GENERAL_CONFIG_KEYS = [
/**
* Specifies if a manual confirmation is active before running the __Promote__ and __Release__ stages of the pipeline.
* @possibleValues `true`, `false`
*/
'manualConfirmation',
/** Defines message displayed as default manual confirmation. Please note: only used in case pipeline is in state __SUCCESSFUL__ */
'manualConfirmationMessage',
/** Defines how many hours a manual confirmation is possible for a dedicated pipeline. */
'manualConfirmationTimeout'
]
@Field STAGE_STEP_KEYS = []
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus(STAGE_STEP_KEYS)
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
/**
* In this stage a manual confirmation is requested before processing subsequent stages like __Promote__ and __Release__.
*
* This stage will be active in two scenarios:
* - manual activation of this stage
* - in case of an 'UNSTABLE' build (even when manual confirmation is inactive)
*/
@GenerateStageDocumentation(defaultStageName = 'Confirm')
void call(Map parameters = [:]) {
def script = checkScript(this, parameters) ?: this
def stageName = parameters.stageName?:env.STAGE_NAME
Map config = ConfigurationHelper.newInstance(this)
.loadStepDefaults()
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
.mixin(parameters, PARAMETER_KEYS)
.use()
String unstableStepNames = script.commonPipelineEnvironment.getValue('unstableSteps') ? "${script.commonPipelineEnvironment.getValue('unstableSteps').join(', ')}" : ''
boolean approval = false
def userInput
timeout(
unit: 'HOURS',
time: config.manualConfirmationTimeout
){
if (currentBuild.result == 'UNSTABLE') {
def minReasonLength = 10
def acknowledgementText = 'I acknowledge that for traceability purposes the approval reason is stored together with my user name / user id'
def reasonDescription = "Please provide a reason for overruling the failed steps ${unstableStepNames}, with ${minReasonLength} characters or more:".toString()
def acknowledgementDescription = "${acknowledgementText}:".toString()
while(!approval) {
userInput = input(
message: 'Approve continuation of pipeline, although some steps failed.',
ok: 'Approve',
parameters: [
text(
defaultValue: '',
description: reasonDescription,
name: 'reason'
),
booleanParam(
defaultValue: false,
description: acknowledgementDescription,
name: 'acknowledgement'
)
]
)
approval = validateApproval(userInput.reason, minReasonLength, userInput.acknowledgement, acknowledgementText, unstableStepNames)
}
} else {
input message: config.manualConfirmationMessage
}
}
}
private boolean validateApproval(reason, minReasonLength, acknowledgement, acknowledgementText, unstableStepNames) {
def reasonIsLongEnough = reason?.length() >= minReasonLength
approved = acknowledgement && reasonIsLongEnough
if (approved) {
echo "Failed steps\n------------\n${unstableStepNames}"
echo "Reason\n------\n${reason}"
echo "Acknowledgement\n---------------\n☑ ${acknowledgementText}"
} else {
if (!acknowledgement) {
echo "Rejected the approval because the user didn't acknowledge that his user name or id is logged"
}
if (!reasonIsLongEnough) {
echo "Rejected the approval because the provided reason has less than ${minReasonLength} characters"
}
}
return approved
}