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:
Related
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' }
Start jenkins job immediately after creation by seed job
I can start a job from within the job dsl like this:
queue('my-job')
But how do I start a job with argument or parameters? I want to pass that job some arguments somehow.
Afaik, you can't.
But what you can do is creating it from a pipeline (jobDsl step), then run it. Something more or less like...
pipeline {
stages {
stage('jobs creation') {
steps {
jobDsl targets: 'my_job.dsl',
additionalParameters: [REQUESTED_JOB_NAME: "my_job's_name"]
build job: "my_job's_name",
parameters: [booleanParam(name: 'DRY_RUN', value: true)]
}
}
}
}
With a barebones 'my_job.dsl'...
pipelineJob(REQUESTED_JOB_NAME) {
definition {
// blah...
}
}
NOTE: As you see, I explicitly set the name of the job from the calling pipeline (the REQUESTED_JOB_NAME var) because otherwise I don't know how to make the jobDSL code to return the name of the job it creates back to the calling pipeline.
I use this "trick" to avoid the "job params go one run behind" problem. I use the DRY_RUN param of the job (I use a hidden param, in fact) to run a "do-nothing" build as its name implies, so by the time others need to use the job for "real stuff" its params section has already been properly parsed.
I would like to set a parameter in Jenkins Declarative Pipeline enabling the user to select one of the jobs defined on Jenkins. Something like:
parameters {
choice(choices: getJenkinsJobs())
}
How can this be achieved?
Background info: I would like to implement a generic manual promotion job with the Pipeline, where the user would select a build number and the job name and the job would get promoted.
I dislike the idea of using the input step as it prevents the job from completing and I can't get e.g. the junit reports on tests.
You can iterate over all existing hudson.model.Job instances and get their names. The following should work
#NonCPS
def getJenkinsJobs() {
Jenkins.instance.getAllItems(hudson.model.Job)*.fullName.join('\n')
}
pipeline {
agent any
parameters {
choice(choices: getJenkinsJobs(), name: 'JOB')
}
//...
}
Use http://wiki.jenkins-ci.org/display/JENKINS/Extended+Choice+Parameter+plugin
and use basic groovy script as a input.
Refer the below URL for how to list the build/jobs.
https://themettlemonkey.wordpress.com/2013/01/29/jenkins-build-number-drop-down/
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
We're considering using the Jenkins Pipeline plugin for a rather complex project consisting of several deliveries that need to be build using different tools (on different machines) before being merged. Still, it seems to be easy enough to do a complete build with a single Jenkinsfile, and I like the automatic discovery of git branches that comes with Pipeline.
However, at this point, we have jobs for each of the deliveries and use a build-flow based "meta" job to orchestrate the individual jobs. The nice thing about this is that it also allows starting just one individual job if only small changes were made, just to see whether this delivery still compiles.
To emulate this, some ideas came to mind:
Use different Jenkinsfiles for the deliveries and load them in the top-level Jenkinsfile; it seems that the Multibranch Pipeline job does not allow configuring the Jenkinsfile to use yet (https://issues.jenkins-ci.org/browse/JENKINS-35415), however, so creating the jobs for the individual deliveries is still open.
Provide a configuration option for the "top-level" job and have ifs for all deliveries in the Jenkinsfile to be able to select which should be build. This would mix different build types in one pipeline, though, and, at the very least, mess up the estimation of the build time.
Are those viable options, or is there a better one?
What you could do is to write a pipelining script that has has "if"-guards around the single stages, like this:
stage "s1"
if (theStage in ["s1","all"]) {
sleep 2
}
stage "s2"
if (theStage in ["s2", "all"]) {
sleep 2
}
stage "s3"
if (theStage in ["s3", "all"]) {
sleep 2
}
Then you can make a "main" job that uses this script and runs all stages at once by setting the parameter "theStage" to "all". This job will collect the statistics when all stages are run at once and give you useful estimation times.
Furthermore, you can make a "partial run" job that uses this script and that is parametrized with the stage that you want to run. The estimation will not be very useful, though.
Note that I put the stage itself to the main script and put only the execution code into the conditional, as suggested by Martin Ba. This makes sure that the visualization of the job is more reliable
As an expansion of the previous answer, I would propose something like that:
def stageIf(String name, Closure body) {
if (params.firstStage <= name && params.lastStage >= name) {
stage(name, body)
} else {
stage(name) {
echo "Stage skipped: $name"
}
}
}
node('linux') {
properties([
parameters([
choiceParam(
name: 'firstStage',
choices: '1.Build\n' +
'2.Docker\n' +
'3.Deploy',
description: 'First stage to start',
defaultValue: '1.Build',
),
choiceParam(
name: 'lastStage',
choices: '3.Deploy\n' +
'2.Docker\n' +
'1.Build',
description: 'Last stage to start',
defaultValue: '3.Deploy',
),
])
])
stageIf('1.Build') {
// ...
}
stageIf('3.Deploy') {
// ...
}
}
Not as perfect as I wish but at least its working.