Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to schedules jobs with specific parameters in a Jenkins multibranch pipeline

We were having 2 FreeStyle projects on Jenkins:

One to generate builds(daily builds+manual builds), one other to execute tests.

We are moving to a Multibranch pipeline on jenkins, so my understanding is that we have one project per repository, and that we should use options to have different behavior.

So I can create parameters, to indicate if we want to run the tests, if we want to build the setups, that part I'm ok with it.

My issue is that I need that by default, the tests are NOT executed(because they take a lot of time to generate, and I don't want that developers can by mistake just let the "Execute tests" option checked.

And I need that this option is checked when executing the daily build in the night.

So 2 questions:

  1. How to schedule?
  2. How to provide the parameters value used for this schedule?
like image 763
J4N Avatar asked Jun 15 '18 06:06

J4N


People also ask

How do you trigger another job in Jenkins using pipeline with parameters?

Use build job plugin for that task in order to trigger other jobs from jenkins file. You can add variety of logic to your execution such as parallel ,node and agents options and steps for triggering external jobs.

How do you add parameters in Multibranch pipeline Jenkins?

If you want to add new parameters you have to do it using properties in Jenkinsfile - goto <JENKINS URL>/pipeline-syntax and generate code for the properties step.

How do I schedule a job in Jenkins pipeline?

Add a Schedule to a Jenkins JobHead back to the job configuration and click the Build Triggers tab. Now, check the Build periodically box in the Build Triggers section. This will open the scheduling text area. Next, let's set the job to run every five minutes.


2 Answers

To keep this in the same job is going to require a little bit of groovy coding. Since your using MultiBranch pipeline this can all live in your Jenkinsfile

First, Set your cron as Vitalii mentions, this will kick of the job on schedule.

properties([
    pipelineTriggers([cron('0 0 * * *')])
])

Next, when this job is triggered by the schedule, we want to adjust the params its running with. So first we need to check what caused the build. This will probably require Security script approval.

List causes = currentBuild.rawBuild.getCauses().collect { it.getClass().getCanonicalName().tokenize('.').last() }

If this contains 'TimerTriggerCause' then we want to update the parameter.

if (causes.contains('TimerTriggerCause') { 
    setBooleanParam("EXECUTE_TESTS", true)
}

We wrote a function in a shared lib for this, you can put it in the same Jenkinsfile if you wish (At the bottom outside the pipeline logic):

/**
 * Change boolean param value during build
 *
 * @param paramName new or existing param name
 * @param paramValue param value
 * @return nothing
 */
Void setBooleanParam(String paramName, Boolean paramValue) {
    List<ParameterValue> newParams = new ArrayList<>();
    newParams.add(new BooleanParameterValue(paramName, paramValue))
    try {
        $build().addOrReplaceAction($build().getAction(ParametersAction.class).createUpdated(newParams))
    } catch (err) {
        $build().addOrReplaceAction(new ParametersAction(newParams))
    }
}

And let the job continue as normal. When it gets to evaluating params.EXECUTE_TESTS, this will now be true (instead of the default false).

Note: May need to import model for the value

import hudson.model.BooleanParameterValue

Putting that all together (Just cobbled the bits together quickly for an overall picture), Your jenkinsfile would end up something like this

#!groovy
import hudson.model.BooleanParameterValue


List paramsList = [
    choice(name: 'ACCOUNT_NAME', choices: ['account1', 'account2'].join('\n'), description: 'A choice param'),
    string(name: 'PARAM', defaultValue: 'something', description: 'A string param'),
    booleanParam(defaultValue: false, name: 'EXECUTE_TESTS', description: 'Checkbox'),
]

properties([
    buildDiscarder(logRotator(numToKeepStr: '20')),
    pipelineTriggers([cron('0 18 * * *')]), // 4am AEST/5am AEDT
    disableConcurrentBuilds(),
    parameters(paramList)
])


ansiColor {
    timestamps {
        node {
            try {
                causes = currentBuild.rawBuild.getCauses().collect { it.getClass().getCanonicalName().tokenize('.').last() }
                if (causes.contains('TimerTriggerCause') { 
                    setBooleanParam("EXECUTE_TESTS", true)
                }
                stage('Do the thing') {
                    // Normal do the things like build
                }
                stage('Execute tests if selected') {
                    if (params.EXECUTE_TESTS == true) {
                        // execute tests
                    } else {
                        echo('Tests not executed (Option was not selected/False)')
                    }
                }
            } catch (err) {
                throw err
            } finally {
                deleteDir()
            }
        }
    }
}

/**
 * Change boolean param value during build
 *
 * @param paramName new or existing param name
 * @param paramValue param value
 * @return nothing
 */
Void setBooleanParam(String paramName, Boolean paramValue) {
    List<ParameterValue> newParams = new ArrayList<>();
    newParams.add(new BooleanParameterValue(paramName, paramValue))
    try {
        $build().addOrReplaceAction($build().getAction(ParametersAction.class).createUpdated(newParams))
    } catch (err) {
        $build().addOrReplaceAction(new ParametersAction(newParams))
    }
}
like image 127
metalisticpain Avatar answered Oct 30 '22 12:10

metalisticpain


You can create a separate multi-branch job that will run by schedule and trigger your main job overriding all necessary parameters. It will look something like this

pipeline {
    agent any
    triggers {
        pollSCM('0 0 * * *')
    }
    stages {
        stage('Triggering the main job') {
            steps {
                build job: "main/${BRANCH_NAME.replace('/', '%2F')}", 
                      parameters: [string(name: 'RUN_TESTS', value: 'true')]
            }
        }
    }
}

You should put this file along with your main Jenkinsfile in the repository and configure a separate multi-branch pipeline job to use this file.

like image 30
Vitalii Vitrenko Avatar answered Oct 30 '22 12:10

Vitalii Vitrenko