Jenkins pipeline with a conditional trigger - jenkins

My Jenkins pipeline is as follow:
pipeline {
triggers {
cron('H */5 * * *')
}
stages {
stage('Foo') {
...
}
}
}
The repository is part of a Github Organization on Jenkins - every branch or PR pushed results in a Jenkins job being created for that branch or PR.
I would like the trigger to only be run on the "main" branch because we don't need all branches and PRs to be run on a cron schedule; we only need them to be run on new commits which they already do.
Is it possible?

yes - it's possible. To schedule cron trigger only for a specific branch you can do it like this in your Jenkinsfile:
String cron_string = (scm.branches[0].name == "main") ? 'H */5 * * *' : ''
pipeline {
triggers {
cron(cron_string)
}
// whatever other code, options, stages etc. is in your pipeline ...
}
What it does:
Initialize a variable based on a branch name. For main branch it sets requested cron configuration, otherwise there's no scheduling (empty string is set).
Use this variable within pipeline
Further comments:
it's possible to use it also with parameterizedCron (in a case you'd want / need to).
you can use also some other variables for getting branch name, e.g: env.BRANCH_NAME instead of scm.branches[0].name. Whatever fits your needs...
This topic and solution is discussed also in Jenkins community: https://issues.jenkins.io/browse/JENKINS-42643?focusedCommentId=293221#comment-293221
EDIT: actually a similar question that leads to the same configuration - here on Stack: "Build Periodically" with a Multi-branch Pipeline in Jenkins

You can simply add a when condition to your pipeline.
when { branch 'main' }

Related

conditional branch in groovy code based on state

I have a webhook in gitlab, that triggers a Jenkins job which run a groovy script.
Now I want that the branch to checkout will be conditional:
If the state is merged to take the target_branch and if not that the source_branch
I couldn't find exactly how to do it in the groovy code. The triggers are different for one is note and for the other is merge request
There are gitlab variables that are passed: https://github.com/jenkinsci/gitlab-plugin#defined-variables
so the following solved my issue:
// Distniguish between 2 types of webhook triggers
if(env.gitlabMergeRequestState != null) {
merge_status = "merged"
if (merge_status.equalsIgnoreCase(env.gitlabMergeRequestState)) {
echo "Merged Trigger, using: ${env.gitlabTargetBranch} branch"
branch = env.gitlabTargetBranch
} else {
echo "Note Trigger, using: ${env.gitlabSourceBranch} branch"
branch = env.gitlabSourceBranch
}
}

Jenkins Parameterized Project For Multiple Parameters

I have Jenkins Pipeline which is triggering for different projects. However the only difference in all the pipelines is just the name.
So I have added a parameter ${project} in parameter of jenkins and assigned it a value of the name of the project.
We have a number of projects and I am trying to find a better way through which I can achieve this.
I am thinking how can we make the parameter run with different parameters for all the projects without actually creating different projects under jenkins.
I am pasting some screenshot for you to understand what exactly I want to achieve.
As mentioned here, this is a radioserver project, having a pipeline which has ${project} in it.
How can I give multiple values to that {project} from single jenkins job?
IF you have any doubts please message me or add a comment.
You can see those 2 projects I have created, it has all the contents same but just the parameterized value is different, I am thinking how can I give the different value to that parameter.
As you can see the 2 images is having their default value as radioserver, nrcuup. How can I combine them and make them run seemlessly ?
I hope this will help. Let me know if any changes required in answer.
You can use conditions in Jenkins. Based on the value of ${PROJECT}, you can then execute the particular stage.
Here is a simple example of a pipeline, where I have given choices to select the value of parameter PROJECT i.e. test1, test2 and test3.
So, whenever you select test1, jenkins job will execute the stages that are based on test1
Sample pipeline code
pipeline {
agent any
parameters {
choice(
choices: ['test1' , 'test2', 'test3'],
description: 'PROJECT NAME',
name: 'PROJECT')
}
stages {
stage ('PROJECT 1 RUN') {
when {
expression { params.PROJECT == 'test1' }
}
steps {
echo "Hello, test1"
}
}
stage ('PROJECT 2 RUN') {
when {
expression { params.PROJECT == 'test2' }
}
steps {
echo "Hello, test2"
}
}
}
}
Output:
when test1 is selected
when test2 is selected
Updated Answer
Yes, it is possible to trigger the job periodically with a specific parameter value using the Jenkins plugin Parameterized Scheduler
After you save the project with some parameters (like above mentioned pipeline code), go back again to the Configure and under Build Trigger, you can see the option of Build periodically with parameters
Example:
I will here run the job for PROJECT=test1 every even minutes and PROJECT=test2 every uneven minutes. So, below is the configuration
*/2 * * * * %PROJECT=test1
1-59/2 * * * * %PROJECT=test2
Please change the crontab values according to your need
Output:

The Configure block for the Job DSL scan by webhook is not working

I am using the below Configure block for the scan by webhook functionality in Jenkins Job DSL.
Environment: Jenkins and Bitbucket
traits << 'com.igalg.jenkins.plugins.mswt.trigger.ComputedFolderWebHookTrigger' {
token("TEST_HOOK")
}
The above block is not working.
But the below periodic trigger syntax is working with out any issues.
it / 'triggers' << 'com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger'{
spec '* * * * *'
interval "60000"
}
As we want to use the scan by webhook functionality. Kindly correct my scan by webhook syntax
The Job DSL Pipeline provides some declarative Parts for triggering a job either on changes or scheduled.
Another case can be the Multibranch Pipeline, where any branch is configured by the included Jenkinsfile. In order to create Jobs for a new branch, the Task "Scan Multibranch Pipeline Now" has to be executed either manually or scheduled. This can be programmatically(schedule) done via the configure block inside the Multibranch Pipeline Job:
multibranchPipelineJob("JobName") {
...
configure { node ->
def periodicFolderTrigger = node / triggers / 'com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger' {
spec('H H * * *')
//4 hours (60000(Milliseconds)*60(Minutes)*4(hours)
interval(60000*60*4)
}
}
}
The webhook Solution, is more elegant, but you need the Jenkins plugin https://plugins.jenkins.io/multibranch-scan-webhook-trigger/ to be installed. Programmatically you can activate this via the following way:
multibranchPipelineJob("JobName") {
...
configure { node ->
def webhookTrigger = node / triggers / 'com.igalg.jenkins.plugins.mswt.trigger.ComputedFolderWebHookTrigger' {
spec('')
token("TESTTOKEN")
}
}
}

How i can trigger build from jenkinsfile using cron syntax?

im using multibranch jenkins style each branch has its own jenkinsfile, i have added triggers in jenkinsfile but it didnt trigger anything on the specified time (8pm), im not sure if im missing something
agent {
node {
label 'master'
}
}
triggers {
cron(env.APP_NAME == 'DICTIONARY' ? '00 20 * * *' : '')
}
stages {
stage('SCM Checkout') {
steps {
git(branch: 'test', url: 'https://gitlab.testral.ba/amramework.git', poll: true, credentialsId: 'GitlabCred')
}
}
For the change in cron to catch, you need to run your Jenkinsfile once manually in the correct branch. After that, check in "View Configuration" that your cron succeeded ("Build periodically" should be checked and contain the schedule).
If it has not, it could be that, at the time when triggers are evaluated, your env.APP_NAME differs from 'DICTIONARY'.
To debug the env, you may add the following:
println "env.APP_NAME is ${env.APP_NAME}" // will run before pipeline
pipeline {
agent {
node {
As a side-note, it's recommended using H instead of minutes, so not all hourly builds fall exactly on the hour:
triggers {
cron(env.APP_NAME == 'DICTIONARY' ? 'H 20 * * *' : '')
}

How can I parameterize Jenkinsfile jobs

I have Jenkins Pipeline jobs, where the only difference between the jobs is a parameter, a single "name" value, I could even use the multibranch job name (though not what it's passing as JOB_NAME which is the BRANCH name, sadly none of the envs look suitable without parsing). It would be great if I could set this outiside of the Jenkinsfile, since then I could reuse the same jenkinsfile for all the various jobs.
Add this to your Jenkinsfile:
properties([
parameters([
string(name: 'myParam', defaultValue: '')
])
])
Then, once the build has run once, you will see the "build with parameters" button on the job UI.
There you can input the parameter value you want.
In the pipeline script you can reference it with params.myParam
Basically you need to create a jenkins shared library example name myCoolLib and have a full declarative pipeline in one file under vars, let say you call the file myFancyPipeline.groovy.
Wanted to write my examples but actually I see the docs are quite nice, so I'll copy from there. First the myFancyPipeline.groovy
def call(int buildNumber) {
if (buildNumber % 2 == 0) {
pipeline {
agent any
stages {
stage('Even Stage') {
steps {
echo "The build number is even"
}
}
}
}
} else {
pipeline {
agent any
stages {
stage('Odd Stage') {
steps {
echo "The build number is odd"
}
}
}
}
}
}
and then aJenkinsfile that uses it (now has 2 lines)
#Library('myCoolLib') _
evenOrOdd(currentBuild.getNumber())
Obviously parameter here is of type int, but it can be any number of parameters of any type.
I use this approach and have one of the groovy scripts that has 3 parameters (2 Strings and an int) and have 15-20 Jenkinsfiles that use that script via shared library and it's perfect. Motivation is of course one of the most basic rules in any programming (not a quote but goes something like): If you have "same code" at 2 different places, something is not right.
There is an option This project is parameterized in your pipeline job configuration. Write variable name and a default value if you wish. In pipeline access this variable with env.variable_name

Resources