Stampy
Stampy

Reputation: 466

Run Jenkins pipeline nightly continuously

I'm using Jenkins for OnCommit and Nightly Builds. My Build Trigger is for example at the weekend:

H/25 * * * 0,6

or from Monday to Friday:

H/25 0-5 * * *

The nightly build runs every 25 minutes.

But this way I can't use the time effectively and if there are changes to the build length I always have to adjust it.

How can I make a build run permanently from 8pm to 6am for example. As soon as the first build is finished, the next one should start. Then at 6am the last build starts.

Upvotes: 1

Views: 1157

Answers (2)

Ian W
Ian W

Reputation: 4767

Q: How can I make a build run permanently from 8pm to 6am for example. As soon as the first build is finished, the next one should start. Then at 6am the last build starts

A: This step should work without jump through cron hoops. It triggers the build with a delay of quietPeriod which is the number of seconds to delay before starting. This avoids the use of a scheduled (cron) job and instead just keeps calling itself.

Essentially, the job will continuously trigger itself between hourStart .. hourEnd, but after hourEnd, will add a block delay of seconds to the next iteration. You can do your own time math for more precision.

pipeline {
    agent any
    options {
        disableConcurrentBuilds()
    }

    stages {
        stage('running') {
            steps {
                echo "running job"
                sleep 5
            }
        }
        stage('run again?') {
        steps {
            script {
                currHour = new Date().format("HH").toInteger()
                hourStart = 20  // Start hour of run window ie: 0600 hr
                hourStop = 6    // End hour of run window ie: 2000 hr
                sph = 60* 60    // seconds per hour
                if (currHour > hourStop && currHour < hourStart ) sleepInterval  = ( hourStart - currHour ) * sph
            }
            echo "quietPeriod: $sleepInterval"
            build wait: false, quietPeriod: sleepInterval, job: "${JOB_NAME}"
            }
        }
    }
}

The downside is if the system stops, the job will not start on it's own ( you can work around that via init.groovy* ). The benefits are when the last existing job completes, it frees the executor; and you can stop the job at any time and not worry about it launching via cron.

NOTE: In Jenkins > 2.277.1, the following warning appears, not sure why: JENKINS-65426 "message in pipeline: [withMaven] Infinite loop of job triggers" has been raised to address.

[withMaven] WARNING abort infinite build trigger loop. Please consider opening a Jira issue: Infinite loop of job triggers

* add to init.groovy: Jenkins.instance.getItemByFullName('folder_name/job_name').schedulebuild2(0)

Upvotes: 1

Chris Maggiulli
Chris Maggiulli

Reputation: 3824

Solution

I am not necessarily recommending this solution but you could create a pipeline with a stage that calls itself between certain hours. You would probably need to disable concurrent executions and configure the build declarative to not wait and not propagate errors.

pipeline {
    agent any

    options {
        disableConcurrentBuilds()
    }
    
    
    stages {
        stage('output') {
            steps {
                echo 'I am doing something'
            }
        }
        
        stage('run again?') {
            steps {
                script {
                    /*
                     * You will need to write the Groovy code for now, start, and end
                     * Then you can compare the times and build a self calling pipeline
                     */
                    if ( now.after(start.time) && now.before(end.time) ) {
                        build wait: false, propagate: false, job: "${env.JOB_NAME}"
                    }

                }
            }
        }
    }
}

Upvotes: 0

Related Questions