Search code examples
jenkinsjenkins-pipelinejenkins-groovycicd

Use same jenkinsfile for different global timeout options


I have a situation where i have to run same pipeline (set of stages) daily and weekly. But the catch is timeout option.

  • For nightly build, we have strict timeout of 4 hours
  • For Weekly build, we have timeout of 48 hours (as retrying some stages in pipeline multiple times)
  • We can differentiate build using BUILD_TAGS, but stuck with global timeout option.
  • Don't want to go with stage timeout option, as it calculates even waiting for node time.
pipeline {
    agent any
    options {
        // Timeout counter starts AFTER agent is allocated
        timeout(time: 4, unit: 'HOURS')
    }
    stages {
        stage('Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Test') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

Have anyone tried similar scenario? Any guidance would be appreciated.


Solution

  • Once you can figure out why your job is running — namely, is it a weekly or nightly (or none of these) — this becomes fairly easy.

    This solution includes ParameterizedCron plugin to pass the reason as parameter:

    pipeline {
        agent any
        parameters {
            booleanParam(name: 'IS_NIGHTLY', defaultValue: false)
            booleanParam(name: 'IS_WEEKLY', defaultValue: false)
        }
        triggers {
            parameterizedCron("H 1 * * 1-7 % IS_NIGHTLY=true")
            parameterizedCron("H 1 * * 6 % IS_WEEKLY=true")
        }
        options {
            // Once you have indication of why your build is running:
            timeout(time: IS_NIGHTLY ? 4 : (IS_WEEKLY ? 48 : 1), unit: 'HOURS')
        }
        stages {
            stage('Build') {
                steps {
                    echo 'Hello World'
                }
            }
            stage('Test') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
    

    Another solution would include running a little code before pipeline starts to dig in BuildCauses:

    import groovy.transform.Field
    @Field
    TIMEOUT = 4
    try {
        if (currentBuild.getBuildCauses()[0].shortDescription.contains("timer")) {
            TIMEOUT = 48 // deciphering between nightly and weekly left as excercise
        }
    } catch (error) {
        echo error.getMessage()
    }
    
    pipeline {
        agent any
        options {
            // Timeout counter starts AFTER agent is allocated
            timeout(time: TIMEOUT, unit: 'HOURS')
    // etc.