Datageek
Datageek

Reputation: 26739

Run the Jenkins pipeline nightly and after every commit

We would like to run the Jenkins pipeline:

With the caveat that nightly build should also tigger additional step (long-running integration tests).

Is it possible? How can we configure this in Jenkinsfile?

Upvotes: 0

Views: 2426

Answers (1)

MaratC
MaratC

Reputation: 6899

So, your question boils down to several:

  1. How can I run a nightly build?
  2. How can I stop a build if no commits were made in the last 24 hours?
  3. How can I run a "long-running" stage, but not always?

Let's address these one by one.

  1. You can have a nightly build by using cron or parameterizedCron, if you install the ParameterizedCron plugin. As you seem to want to run your job in all the branches, this may look like e.g.
pipeline {
    agent any
    triggers {
        // schedule a nightly build at random time after 0am on dev branch, 1am on master
        cron(env.BRANCH_NAME == 'dev' ? '0 * * * *' : '') 
        cron(env.BRANCH_NAME == 'master' ? '1 * * * *' : '') 
  1. To address the other points, you need to know why your build is running. It may be triggered by a person, or cron, or a commit. Once you make sure it's cron that triggered the build, you may want to explore git log for the time of the latest commit.
def currentBuildReason() {
    def timerCause = currentBuild.rawBuild.getCause(hudson.triggers.TimerTrigger.TimerTriggerCause)
    if (timerCause) { echo "Build reason: Build was started by timer"; return "TIMER" }
    timerCause = currentBuild.rawBuild.getCause(org.jenkinsci.plugins.parameterizedscheduler.ParameterizedTimerTriggerCause)
    if (timerCause) { echo "Build reason: Build was started by parameterized timer"; return "TIMER" }
    def userCause = currentBuild.rawBuild.getCause(hudson.model.Cause$UserIdCause)
    if (userCause) { echo "Build reason: Build was started by user"; return "USER" }
    println "here are the causes"
    echo "${currentBuild.buildCauses}"
    return "UNKNOWN"
}

and later:

if ( currentBuildReason() == "TIMER" and env.BRANCH == "master" ) {
   def gitLog = sh script: "git log", returnStdout: true
   // look for the date, and stop the build
  1. Finally, you can run steps on condition. One way to do it is to define a parameter for your job, indicating whether the integration tests should run. This will allow a person to run them even if not nightly, when they select the box. E.g.
pipeline {
    parameters {
        booleanParam(name: 'RUN_LONG_TEST', defaultValue: false,
            description: "Should long-running tests execute?")
    }

and later

        stage('Integration tests') {
            agent { node { label "integration_test_slave" }}
            when {
                beforeAgent true
                expression {params.RUN_LONG_TEST}
            }
            steps {
                // run integration test
            }
       }

To schedule the nightly with the param selected, you need the parameterizedCron plugin:

pipeline {
    agent any
    triggers {
        // schedule a nightly build at random time after 0am on dev branch, 1am on master
        parameterizedCron(env.BRANCH_NAME == 'dev' ? '0 * * * *  % RUN_LONG_TEST=true' : '') 
        parameterizedCron(env.BRANCH_NAME == 'master' ? '1 * * * *  % RUN_LONG_TEST=true'' : '') 

Alternatively, you may disregard the parameter if only the nightlies should run it, and analyze the value of currentBuildReason(). When it equals to TIMER, these tests should run.

Upvotes: 3

Related Questions