How to update Parameters in a Jenkins job, then abort and show a success.
Let’s say you have a Jenkinsfile with user parameters. You don’t always want to set the parameters each time you run the job since they only change rarely. And when you do change them, it’s annoying having to run the job and then abort it just to refresh the parameter inputs. WHat if the job could do it on its own?
To solve this annoyance, I like to have a stage which only sets parameters, and then have a checkbox parameter that runs that stage in the beginning of the Job, with a conditional:
stages{
stage('Setup parameters') {
//run only if REFRESH_PARAMETERS checked
when {
environment (name: 'SKIP_STAGES', value: 'true')
}
steps {
script {
println('INFO: This run will not run other stages')
currentBuild.description = "REFRESH PARAMETERS"
properties([
parameters([
sharedParameters.refreshParameters(),
sharedParameters.branchName('main'), // specifies what branch of a jenkinsfile will be run
string(name: 'SERVER_NAME'),
].flatten())
])
jenkinsGeneric.haltBuildWithSuccess('Refreshed parameters and quit')
}
}
}
As one might assume, sharedParameters is a shared library vars file which returns parameters which are used in many jobs:
def userSeparator(styling = 'color: whitesmoke; background: PaleVioletRed; text-align: center; font-weight: bold;', text = 'User Parameters'){
[$class: 'ParameterSeparatorDefinition',
name: 'USER_HEADER',
sectionHeader: text,
separatorStyle: 'border: 0;',
sectionHeaderStyle: styling
]
}
def refreshParameters() {
[booleanParam(
name: 'REFRESH_PARAMETERS',
defaultValue: false,
description: 'Read Jenkinsfile and exit.'
)]
}
def branchName(String defaultBranch = 'master') {
[
[
string(
name: 'BRANCH_NAME',
defaultValue: defaultBranch,
description: 'Which branch of Jenkins pipeline to deploy'
)
],
paramValidator('BRANCH_NAME')
]
}
By the way, paramValidator is super useful, but that is a topic for another post.
Notice the function at the end of the parameters stage:
jenkinsGeneric.haltBuildWithSuccess('Message')
This function jenkinsGeneric is where the magic happens:
def haltBuildWithSuccess(String stopReason = 'Build halted programmatically with SUCCESS status') {
currentBuild.rawBuild.@result = Result.SUCCESS
def cause = new CauseOfInterruption.UserInterruption(stopReason)
throw new FlowInterruptedException(Result.SUCCESS, false, cause)
}
Now when you check the REFRESH_PARAMETERS checkbox, the build will read the Jenkinsfile and abort while showing the run as a success.
Big thanks to https://stackoverflow.com/users/10025322/barel-elbaz For helping me out with the haltBuildWithSuccess function!