"Build Periodically" with a Multi-branch Pipeline in Jenkins - jenkins

I'm running Jenkins 2 with the Pipeline plugin. I have setup a Multi-branch Pipeline project where each branch (master, develop, etc.) has a Jenkinsfile in the root. Setting this up was simple. However, I'm at a loss for how to have each branch run periodically (not the branch indexing), even when the code does not change. What do I need to put in my Jenkinsfile to enable periodic builds?

If you use a declarative style Pipeline and only want to trigger the build on a specific branch you can do something like this:
String cron_string = BRANCH_NAME == "master" ? "#hourly" : ""
pipeline {
agent none
triggers { cron(cron_string) }
stages {
// do something
}
}
Found on Jenkins Jira

If you are using a declarative style Jenkinsfile then you use the triggers directive.
pipeline {
agent any
triggers {
cron('H 4/* 0 0 1-5')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}

This is working for me:
triggers {
cron(env.BRANCH_NAME == 'development' ? 'H */12 * * *' : '')
}
See more in this article

I was able to find an example illustrating this an discarding old builds, which is also something I wanted.
Jenkinsfile in jenkins-infra/jenkins.io:
properties(
[
[
$class: 'BuildDiscarderProperty',
strategy: [$class: 'LogRotator', numToKeepStr: '10']
],
pipelineTriggers([cron('H/30 * * * *')]),
]
)

For Paramertized periodic runs or scheduled triggers, one could use as follows.
triggers{
parameterizedCron env.BRANCH_NAME == "develop" ? '''H 03 * * * % buildSlave=vm1;testSlave=vm2;HYPERVISOR=vbox;VERSION=10.5.0.0
H 03 * * * % buildSlave=vm1;testSlave=vm2;HYPERVISOR=workstation;VERSION=10.5.0.0''' : ""
}

I hit issues with the above solutions.
I'm not a Jenkins wizard so not sure if I am using an old format/syntax or something, but the following is working for me.
#!/usr/bin/env groovy
properties(
[
pipelineTriggers([
[
$class: 'TimerTrigger',
spec: 'H 7,19 * * *'
]
])
]
)
Determined from: https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/triggers/TimerTrigger.java

Related

Multiple jobs running the same pipeline

I have a project using a declarative pipeline for a c++ project.
I wish to have multiple jobs running the same pipeline with different configurations.
E.g. Release or Debug build. Using different compilers. Some jobs using the address sanitizer or thread sanitizer.
Some of these jobs should run on every commit. Other jobs should run once a day.
My idea was to control this by having the pipeline depend on environment variables or parameters.
I now have a JenkinsFile where all the stages depends on environment variables.
Unfortunately I can't find a place to control the variables from the outside.
Is there any way I can control these environment variables on a job level without violating the DRY principle?
A simplified example depending on two variables.
pipeline {
agent {
label 'linux_x64'
}
environment {
CC = '/usr/bin/gcc-4.9'
BUILD_CONF = 'Debug'
}
stages {
stage('Build') {
steps {
cmakeBuild buildDir: 'build', buildType: "${env.BUILD_CONF}", installation: 'InSearchPath', sourceDir: 'src', steps: [[args: '-j4']]
}
}
stage('Test') {
sh 'test.sh'
}
}
I now want two create a second job running the same pipeline but with CC='/usr/bin/clang' and BUILD_CONF='Release'.
In my real project I have more variables and want to test approximately ten combinations.
yes , It possible in one pipeline but it will be more easy with Jenkins scripted pipeline , like below example :
node {
def x=[
[CC: 10, DD: 15],
[CC: 11, DD: 16],
[CC: 12, DD: 17]
]
x.each{
stage("stage for CC - ${it.CC}") {
echo "CC = ${it.CC} & DD = ${it.DD}"
}
}
}
so on your case you can decorate your pipleine like below:
node {
// define all your expected key and value here like an array
def e = [
[CC: '/usr/bin/gcc-4.9', BUILD_CONF: 'Debug'],
[CC: '/usr/bin/clang', BUILD_CONF: 'Release']
]
// Iterate and prepare the pipeline
e.each {
stage("build - ${it.BUILD_CONF}") {
cmakeBuild buildDir: 'build', buildType: "${it.BUILD_CONF}", installation: 'InSearchPath', sourceDir: 'src', steps: [[args: '-j4']]
}
stgae("test - ${it.BUILD_CONF}") {
sh 'test.sh'
}
}
}
with this way , you can reuse your stages with defined array like e

Setting Cron Expression for Jenkins Pipeline via Script

I would like to run my Jenkins multibranch pipeline regulary during a week. Therefore I tried to set the Cron property for my pipeline directly in the Jenkinsfile as follows:
#Library('pipelines#master) _
properties([pipelineTriggers([cron('*/5 * * * *')])])
runPipeline()
In can see in the output of the build, that the properties step has been executed, but the pipeline does not start automatically.
Did I configure the Cron trigger correctly? How can I check if the trigger has been configured?
You can set the cron trigger in declarative way like below.
pipeline {
agent any
triggers{
cron('*/5 * * * *')
}
stages {
stage ("Test Stage1"){
steps {
script {
echo "Hello Test Stage1"
}
}
}
stage("Test Stage2"){
steps{
echo "Hello Test Stage2"
}
}
}
}

How to trigger a build on commit to branch in scripted pipeline

triggers { pollSCM('H */4 * * 1-5') } will this work for merge to branch
I see we have 3 options for triggers this seems to be fo declarative
corn
pollScm
upstream
where in for scripted pipeline is that something like this
properties([pipelineTrigger([triggers('gitPush')])])
OR
properties([pipelineTriggers([githubPush()])])// With this should I also enable a option on Jenkins instance
You can also use Generic Webhook Trigger plugin.
You will need to create a webhook in github and in Jenkins Pipeline something like below.
triggers {
GenericTrigger( genericVariables: [
[defaultValue: '', key: 'commit_author', regexpFilter: '', value: '$.pusher.name'],
[defaultValue: '', key: 'ref', regexpFilter: '', value: '$.ref']
],
causeString: '$commit_author committed to $ref',
printContributedVariables: false,
printPostContent: false,
regexpFilterText: '$ref',
regexpFilterExpression: 'refs/heads/develop',
token: '12345'
}
Hope this helps.
Use something like this in you Jenkinsfile. Use Only those option which you need. Remove which you don't want.
pipeline {
agent any
triggers {
github(
triggerOnPush: true,
triggerOnMergeRequest: true,
triggerOpenMergeRequestOnPush: "source",
branchFilterType: "All",
triggerOnNoteRequest: false)
}
stages {
...
}
}
NOTE: Make sure you have done all the webhook configuration bewteen github and jenkins. and installed webhook plaugin on jenkins

How to trigger build periodically in pipeline with different environment varaiables in jenkinsfile?

i have here one pipeline that running test against app with specific environment variable and triggers at specific time.
what i want to do is to use the same pipeline to be executed periodically at different times but each build is with different environment variable.
here is sample of my jenkinsfile the run against only set of environment available at certain one time
pipeline {
environment {
mvnHome = tool name: 'myMvn', type: 'maven'
mvnCMD = "${mvnHome}/bin/mvn"
APP_NAME = 'test'
APP_PACKAGE = 'test1'
APP_ACTIVITY = 'test2'
}
agent {
node {
label 'master'
}
}
triggers {
cron('15 20 * * *')
}
stages {
stage('SCM Checkout') {
steps {
git(branch: 'APP', url: 'https://gitlab.test.ba/amrka/framework.git', poll: true, credentialsId: 'GitlabCred')
}
}
stage('Testing') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh(label: 'Test Process', script: "${mvnCMD} test")
}
}
}
}
}
You can use parameterized-scheduler plugin. In Jenkins dashboard, goto
Manage Jenkins -> Manage Plugins -> Parameterized Scheduler.
To schedule a job at different times that needs to use different environments, you have to use the parameterized-scheduler plugin.
Parameter1
H/20 * * * * %Parameter1 where Parameter1 is your environment variable for a specific time you want.
Parameter2
H/30 * * * * %Parameter2 where Parameter2 is your a different environment variable for a specific time you want.
The parameters should be setup already for the parameterized-scheduler plugin to work. It can be used only for jobs with parameters.
Remember you have to have your parameters already setup because the plugin is visible only for jobs with parameters. See more documentation including usage examples in the README.

Run the Jenkins pipeline nightly and after every commit

We would like to run the Jenkins pipeline:
nightly, but only if there was any commit in the chosen branches (dev or master)
and after every commit
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?
So, your question boils down to several:
How can I run a nightly build?
How can I stop a build if no commits were made in the last 24 hours?
How can I run a "long-running" stage, but not always?
Let's address these one by one.
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 * * * *' : '')
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
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.

Resources