How to fast fail Jenkins Build Flow Plugin job? - jenkins

I'm trying to fail a Build Flow Plugin job if a parameter isn't set. When I try:
final parameter = params['PARAMETER']
if (parameter.isEmpty()) {
out.println('Error: PARAMETER must be defined')
System.exit(1)
}
the entire Jenkins master dies (double plus ungood).
How do I get the job to fail without killing Jenkins?

Set the Result on build.state then return so as not to execute anything else:
import hudson.model.Result
final parameter = params['PARAMETER']
if (parameter.isEmpty()) {
out.println('Error: PARAMETER must be defined')
build.state.setResult(Result.FAILURE)
return
}

Related

How to call a method inside triggers block in Jenkinfile

I have a pipeline which needs to be scheduled to run at a particular time. There are some dynamic parameters that needs to be passed while running the pipeline.
I have created a function that gives me the desired parameter value. However this pipeline does not get triggered as the function value is not getting resolved inside trigger block & is getting treated as string.
getlatest is the method I created which takes in 3 parameters. The value of this method is not getting resolved & instead treated as string. The pipeline rund as expected if I hardcode some value for version.
triggers{
parameterizedCron("H/5 * * * * % mod=test; version=getlatest('abc','xyz','lmn');")
}
The problem is that the code that calculates the parameter — just like any other code in Jenkins — needs an executor to run. To get an executor, you need to run your pipeline. To run your pipeline, you need to give Jenkins the parameters. But to give Jenkins the parameters, you need to run your code.
So there's a chicken and egg problem, there.
To break out of this cycle, you may want to run scripted pipeline before you run the declarative one:
node('built-in') { // or "master", or any other
def version = getlatest('abc','xyz','lmn')
def cron_parameters = "H/5 * * * * % mod= test; version=${version}"
println "cron_parameters is ${cron_parameters}"
env.CRON_PARAM = cron_parameters
}
pipeline {
agent { node { label "some_label" } }
triggers {
parameterizedCron(env.CRON_PARAM)
}
// ...
}
I've never seen this being tried before so I don't know if what you are doing is something Jenkins is capable of. Instead, remove the parameter and create an environment variable called version and assign the function result to that:
environment {
VERSION = getlatest('abc','xyz','lmn')
}
And reference this VERSION variable instead of your input parameter.
How to reference:
env.VERSION or ${VERSION} or ${env.VERSION}
Examples:
currentBuild.displayName=env.VERSION
env.SUBJECT="Checkout Failure on ${VERSION}"
string(name: 'VERSION', value: "${env.VERSION}")

How can i stop a remote build in Jenkins if a parameter in the url is not valid?

I run remote builds in Jenkins as follows:
JENKINS_URL/job/JOBNAME/build?token=TOKEN
If i add an extra parameter on the query string as follows:
JENKINS_URL/job/JOBNAME/build?token=TOKEN&User=test#test.com&Key=Wxfder$324
As the first step in the build I want to extract these values ie token, User and Key and do some validation and if not valid , then stop the job.
Is there a Build Step i can use, how can i do this ?
One way to do this is by passing the data you need appending to the build cause. Refer to the following example.
The URL
Note the content assigned to cause= parameter
http://localhost:8080/job/Scripted/build?token=12345678&cause=User:test#test.com,Key:Wxfder$324
The Pipeline
pipeline {
agent any
stages {
stage('Test') {
steps {
script {
def cause = currentBuild.getBuildCauses()[0]
def note = cause.getString("note")
echo "${note}"
}
}
}
}
}
Above will give you the following Output.
[Pipeline] echo
User:test#test.com,Key:Wxfder$324

Jenkins: Parameters disappear from pipeline job after running the job

I've been trying to construct multiple jobs from a list and everything seems to be working as expected. But as soon as I execute the first build (which works correctly) the parameters in the job disappears. This is how I've constructed the pipelineJob for the project.
import javaposse.jobdsl.dsl.DslFactory
def repositories = [
[
id : 'jenkins-test',
name : 'jenkins-test',
displayName: 'Jenkins Test',
repo : 'ssh://<JENKINS_BASE_URL>/<PROJECT_SLUG>/jenkins-test.git'
]
]
DslFactory dslFactory = this as DslFactory
repositories.each { repository ->
pipelineJob(repository.name) {
parameters {
stringParam("BRANCH", "master", "")
}
logRotator{
numToKeep(30)
}
authenticationToken('<TOKEN_MATCHES_WITH_THE_BITBUCKET_POST_RECEIVE_HOOK>')
displayName(repository.displayName)
description("Builds deploy pipelines for ${repository.displayName}")
definition {
cpsScm {
scm {
git {
branch('${BRANCH}')
remote {
url(repository.repo)
credentials('<CREDENTIAL_NAME>')
}
extensions {
localBranch('${BRANCH}')
wipeOutWorkspace()
cloneOptions {
noTags(false)
}
}
}
scriptPath('Jenkinsfile)
}
}
}
}
}
After running the above script, all the required jobs are created successfully. But then once I build any job, the parameters disappear.
After that when I run the seed job again, the job starts showing the parameter. I'm having a hard time figuring out where the problem is.
I've tried many things but nothing works. Would appreciate any help. Thanks.
This comment helped me to figure out similar issue with my .groovy file:
I called parameters property twice (one at the node start and then tried to set other parameters in if block), so the latter has overwritten the initial parameters.
BTW, as per the comments in the linked ticket, it is an issue with both scripted and declarative pipelines.
Fixed by providing all job parameters in each parameters call - for the case with ifs.
Though I don't see repeated calls in the code you've provided, please check the full groovy files for your jobs and add all parameters to all parameters {} blocks.

How to disable or remove multibranch pipeline trigger on existing jobs

I have hundreds of jenkins jobs(multibranch pipeline) with trigger enabled to periodically scan respective repositories every 5 mins. I'm trying to disable "scan multibranch pipeline triggers" on all the existing jobs in a particular folder(development/microservice). I'm running below script from Jenkins script console and getting exception at removeTrigger
import hudson.model.*
import hudson.triggers.*
import jenkins.model.*
import com.cloudbees.hudson.plugins.folder.Folder
for (it in Jenkins.instance.getAllItems(jenkins.branch.MultiBranchProject.class)) {
if(it.fullName.length() > 25 && it.fullName.substring(0,25) ==
'development/microservice/' && it.fullName.split("/").length == 3) {
println it.fullName
it.triggers.each { descriptor, trigger ->
it.removeTrigger(descriptor)
it.save()
}
}
}
Can someone please help me how to disable triggers on multibranch pipeline jobs programmatically.
It seems one just needs to iterate over the triggers, and pass the right part to removeTrigger(); that means passing the trigger rather than the descriptor:
for (p in Jenkins.instance.getAllItems(jenkins.branch.MultiBranchProject.class)) {
p.triggers.each { descriptor, trigger ->
//println descriptor
//println trigger
p.removeTrigger(trigger)
}
}
Output sample for a single trigger, when println statements are not commented out:
com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger$DescriptorImpl#30f35b28
com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger#3745f994
Many thanks for your question, your almost working code helped me a lot. ;)

Start jenkins job immediately after creation by seed job, with parameters?

Start jenkins job immediately after creation by seed job
I can start a job from within the job dsl like this:
queue('my-job')
But how do I start a job with argument or parameters? I want to pass that job some arguments somehow.
Afaik, you can't.
But what you can do is creating it from a pipeline (jobDsl step), then run it. Something more or less like...
pipeline {
stages {
stage('jobs creation') {
steps {
jobDsl targets: 'my_job.dsl',
additionalParameters: [REQUESTED_JOB_NAME: "my_job's_name"]
build job: "my_job's_name",
parameters: [booleanParam(name: 'DRY_RUN', value: true)]
}
}
}
}
With a barebones 'my_job.dsl'...
pipelineJob(REQUESTED_JOB_NAME) {
definition {
// blah...
}
}
NOTE: As you see, I explicitly set the name of the job from the calling pipeline (the REQUESTED_JOB_NAME var) because otherwise I don't know how to make the jobDSL code to return the name of the job it creates back to the calling pipeline.
I use this "trick" to avoid the "job params go one run behind" problem. I use the DRY_RUN param of the job (I use a hidden param, in fact) to run a "do-nothing" build as its name implies, so by the time others need to use the job for "real stuff" its params section has already been properly parsed.

Resources