Cron job executing in Jenkins DSL - jenkins

I am trying to create a cron job which run some smoke tests every 10 minutes, my seedjob looks like this :
multiBranchJobs.each { currentJob ->
multibranchPipelineJob(currentJob.name) {
branchSources {
git {
remote(currentJob.projectGitUrl)
credentialsId(currentJob.credentials)
includes(currentJob.includes)
}
}
orphanedItemStrategy {
discardOldItems {
numToKeep(20)
}
}
triggers {
cron "H/5 * * * *"
periodic 60
}
}
}
the problem with the current approach is that it will get executes only if it detects changes in the SCM, which is not the case for the smoke tests. I need to run it every 5 minutes regardless of commits in source control. Any clue ?

I'm not entirely sure how to solve your problem, but I think the cron trigger you have is not doing what you think it is. I THINK this will set this trigger on the multibranch indexing job itself. In the UI that is not even an option. Apparently it isn't throwing an error, but I have to wonder if it is actually setting the trigger.
The jobs that get created from the multibranch job must have a Jenkinsfile, right? You can set the triggers in those Jenkinsfiles.
I haven't built jobs using code, so take that into consideration when you review my answer. But it SEEMS to me that you are setting the trigger in the wrong place.

Related

Can scheduled (cron) Jenkins jobs access previous job status

Below is a simplified case.
I have one node named comp01. And I have a Jenkins job named Compatibility.
Compatibility is scheduled as follows:
0 12 * * 1 %IntegrationNode=Software_1
0 17 * * 1 %IntegrationNode=Software_2
0 22 * * 1 %IntegrationNode=Software_3
0 2 * * 2 %IntegrationNode=Software_4
0 7 * * 2 %IntegrationNode=Software_5
The jobs start as scheduled. But sometimes, because of some verification failure, the previous job takes more than expected time. So, the next job starts before the completion of the previous job.
Is there a way available in Jenkins, in which the next scheduled job stays in a queue until previous job is complete? Or can we schedule based on previous job status?
We have tried limiting executors for this job, but when more than a couple of jobs are queued, then the expected behavior is not observed.
We have also tried by creating resource-groups and adding multiple nodes to it, but still, expected behavior is not observed when multiple jobs are in queue.
EDIT-1:
We can't use options { disableConcurrentBuilds() } since we start the job concurrently on different nodes. Here we are struggling to ensure that when a job is started on a node, then the other scheduled jobs for the same node should wait till the current job completes.
Have you tried setting the below option?
options { disableConcurrentBuilds() }
Update
AFAIK there is no OOB solution for your problem. But you can definitely implement something. Without seeing your actual Pipelines I can't give a concrete answer. But here ae some options.
Option 01
Use Lockable Resources and create a resource per Jenkins IntegrationNode and acquire it when running the Job, the next build will wait until the lock is released.
lock(resource: 'IntegrationNode1', skipIfLocked: false) {
echo "Run your logic"
}
Option 02
You can implement a waiting logic to check the status of the previous Build. Here is an sample Pipeline and possible Groovy code you can leverage.
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
echo "Waiting"
def jobName = "JobA"
def buildNum = "92"
waitUntil { !isPending(jobName, buildNum) }
echo "Actual Run"
}
}
}
}
}
def isPending(def JobName, def buildNumber) {
def buildA = Jenkins.instance.getItemByFullName(JobName).getBuild(buildNumber)
return buildA.isInProgress()
}

Executing multiple jenkins jobs

Can someone please let me know how i can trigger multiple Jenkins jobs? We have 5-6 jobs that we need to trigger manually post some technical upgrades. We are having to navigate to these jobs manually and click on 'Build'. Is there anyway i can create a new job or shell script that will help me in triggering all of these jobs with a single click/run.
Simplest approach will be creating a new pipeline which will trigger other pipelines.
You can also make stages parallel to faster execution if order is not issue.
You can find detailed answer and approach here
Yes, you can do it in both ways that you mentioned. Creating a new job that will run all these other jobs as downstream jobs is the fastest and easiest.
To do this, create a new job, and if you are using declarative Jenkins, then specify the jobs to be triggered:
stage ('trigger-multiple-jobs') {
parallel {
stage ('first job') {
steps {
build([
job : 'JobName',
wait : false,
parameters: [
string(name: 'PARAM_1', value: "${PARAM_1}")
]
])
}
}
stage ('second job') {
steps {
build([
job : 'JobName2',
wait : false
])
}
}
}
}
You can alternatively create a freestyle job, navigate down to the Trigger downstream jobs section, and set the jobs you want to be triggered from the drop down.
If you want to use a shell script, then you can trigger the jobs using API calls. This is described well in this answer.

Jenkins build frequency based on previous build status

I have a Jenkins pipeline which is scheduled to trigger every 4 hours. However, my requirements is that once the build fails, I want the builds to happen more frequently and keep sending constant reminders that the build is broken. In short, the build schedule must depend on the status of the previous build.
Is that possible in Jenkins?
Thanks,
In Scripted Pipeline, you can do something like this :
def triggers = []
if(currentBuild.getPreviousBuild().result != 'SUCCESS') {
triggers << cron('0 */1 * * *') // every hour
} else {
triggers << cron('0 */4 * * *') // every 4 hours
}
properties ([
pipelineTriggers(triggers)
])
node {
...
}
I can't think of a direct way but you can have a workaround. You can have a replica of the same job(let's call it job 'B') and trigger it when the build of the first job fails(let's call it job 'A'). Now if B fails again then you can retrigger it(B) (adding some wait time) and send a notification after it fails, keep doing it until it passes. This will be done in a much easier way if you are using the scripted Jenkins pipeline. Hope this answer helps you in some way.

Jenkins project generated by Job DSL is not triggered.

I have a project, named Demo, which doesn't do anything in particular.
I have a DSL script, like the following:
def gitUrl = 'GIT_URL'
job('unit-tests') {
scm {
git(gitUrl)
}
triggers {
buildResult('H/* * * * *') {
combinedJobs()
triggerInfo('Demo', BuildResult.SUCCESS, BuildResult.UNSTABLE)
}
}
}
Now what I'm wanting to do, is that when the Demo project runs successfully (it checks out a PHP application from Github), I want the unit-tests job to run.
Currently, when the Demo project is built, the unit-tests job never gets run.
I'm guessing my DSL script is incorrect, but I'm not sure why
I can reproduce your problem. The check box is not set when running the seed job for the first time. But it's set after running the seed job a second time. Must be a problem in the BuildResultTrigger plugin. Please file a bug report in the Jenkins JIRA: https://issues.jenkins-ci.org/projects/JENKINS
But you do not necessarily need to use the BuildResultTrigger plugin. You can use the built-in "Build after other projects are built" option, see https://jenkinsci.github.io/job-dsl-plugin/#path/job-triggers-upstream.
job('unit-tests') {
triggers {
upstream('Demo', 'UNSTABLE')
}
}
Use upstream which adds the "Build after other projects are built" trigger. see https://jenkinsci.github.io/job-dsl-plugin/#path/job-triggers-upstream
def gitUrl = 'GIT_URL'
job('unit-tests') {
scm {
git(gitUrl)
}
triggers {
buildResult('H/* * * * *') {
upstream('Demo', 'UNSTABLE')
}
}
}

How can I delete a job using Job DSL plugin(script) in Jenkins?

I am very new to Jenkins and Job DSL plugin. After a little research, I found how to create a job using DSL and now I am trying to delete a job using DSL.
I know to disable a job using this following code:
//create new job
//freeStyleJob("MyJob1", closure = null);
job("MyJob1"){
disabled(true);
}
It is working perfectly fine. But, I couldn't find any method to delete another job in jenkins.
Please help!
Thanks!
To delete a job, you have to set the "Action for removed jobs" option to "Delete" in the "Process Job DSLs" build step configuration. Then remove the job from your script and run the seed job.
Each instance of the Job Dsl plugin tracks what jobs (and views) it creates. When it is run again, you can configure what it does to jobs (and views) that were present the previous time this instance was run, but are not present this time.
Let's a assume you have two files you use to create jobs.
seed_jobdsl.groovy:
job('seed_all') {
steps {
dsl {
external('*_jobdsl.groovy')
// default behavior
// removeAction('IGNORE')
}
}
}
test_jobdsl.groovy:
job('test_stuff') {
steps {
shell('echo "I live!")
}
}
This will leave jobs created by seed_all unchanged even if they are not present in the list of job created the next time seed is run.
To get jobs to be deleted, change your seed job code:
seed_jobdsl.groovy:
job('seed_all') {
steps {
dsl {
external('*_jobdsl.groovy')
removeAction('DELETE')
}
}
}
Now, run seed_all job to apply your change (seed_all overwrites its own configuration when run). Then make the following change:
test_jobdsl.groovy:
job('test_other') {
steps {
shell('echo "The job is dead, long live the new job!"')
}
}
Run seed_all again. You notice test_stuff will be deleted and test_other will be created. If you remove test_jobdsl.groovy and then run seed_all, test_other will be deleted.

Resources