2019-05-22 10:42:59 +02:00
import com.sap.piper.ConfigurationHelper
import com.sap.piper.GenerateStageDocumentation
2020-08-28 16:11:35 +02:00
import com.sap.piper.StageNameProvider
2019-05-22 10:42:59 +02:00
import groovy.transform.Field
import static com . sap . piper . Prerequisites . checkScript
@Field String STEP_NAME = getClass ( ) . getName ( )
2020-08-28 16:11:35 +02:00
@Field String TECHNICAL_STAGE_NAME = 'confirm'
2019-05-22 10:42:59 +02:00
@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'
]
2019-07-03 10:13:26 +02:00
@Field STAGE_STEP_KEYS = [ ]
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS . plus ( STAGE_STEP_KEYS )
2019-05-22 10:42:59 +02:00
@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
2020-08-28 16:11:35 +02:00
def stageName = StageNameProvider . instance . getStageName ( script , parameters , this )
2019-05-22 10:42:59 +02:00
Map config = ConfigurationHelper . newInstance ( this )
. loadStepDefaults ( )
. mixinGeneralConfig ( script . commonPipelineEnvironment , GENERAL_CONFIG_KEYS )
. mixinStageConfig ( script . commonPipelineEnvironment , stageName , STEP_CONFIG_KEYS )
. mixin ( parameters , PARAMETER_KEYS )
. use ( )
2020-05-18 12:21:05 +02:00
String unstableStepNames = script . commonPipelineEnvironment . getValue ( 'unstableSteps' ) ? "${script.commonPipelineEnvironment.getValue('unstableSteps').join(', ')}" : ''
2019-05-22 10:42:59 +02:00
boolean approval = false
def userInput
2020-10-07 10:56:25 +02:00
milestone ( )
2019-05-22 10:42:59 +02:00
timeout (
unit: 'HOURS' ,
time: config . manualConfirmationTimeout
) {
if ( currentBuild . result = = 'UNSTABLE' ) {
2020-05-18 12:21:05 +02:00
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 ( )
2019-05-22 10:42:59 +02:00
while ( ! approval ) {
userInput = input (
message: 'Approve continuation of pipeline, although some steps failed.' ,
ok: 'Approve' ,
parameters: [
text (
2020-05-18 12:21:05 +02:00
defaultValue: '' ,
description: reasonDescription ,
2019-05-22 10:42:59 +02:00
name: 'reason'
) ,
booleanParam (
defaultValue: false ,
2020-05-18 12:21:05 +02:00
description: acknowledgementDescription ,
2019-05-22 10:42:59 +02:00
name: 'acknowledgement'
)
]
)
2020-05-18 12:21:05 +02:00
approval = validateApproval ( userInput . reason , minReasonLength , userInput . acknowledgement , acknowledgementText , unstableStepNames )
2019-05-22 10:42:59 +02:00
}
} else {
input message: config . manualConfirmationMessage
}
}
}
2020-05-18 12:21:05 +02:00
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
}