add build parameter in jenkins build schedule - jenkins

I have a jenkins job. i want to build my job in a specific time with a build parameter.
I want to do this by using the Build periodically option.
I have input like this:
*/1 * * * * Parameter1
If I do this, jenkins show an error.
Is this possible without using any plugin.
if not, than which plugin will be better
Alternatively is there a way to give parameter's here in the schedule?
My actual requirement is like this:
build in morning using one parameter
build in evening using another parameter.

Basically, with the 'Build periodically' option you can't schedule a Jenkins job with parameters.
However, to schedule a job at different times that needs to use different environments, you have to use the parameterized-scheduler plugin or search for it in
(Manage Jenkins -> Manage Plugins -> Parameterized Scheduler).
Examples:
# Parameter1
H/15 * * * * %Parameter1
# Parameter2
H/30 * * * * %Parameter2
Remember you have to have your parameters already setup because the plugin is visible only for jobs with parameters.
The Node and Label parameter plugin can help since it allows you to select individual nodes assuming your different servers qa1 and qa2 are already configured. Hope that clarifies things for you.

With the native Jenkins crontab, it's not possible.
But it should be possible with this plugin:
https://github.com/jwmach1/parameterized-scheduler
You have to fork the repo and build this plugin + do a manual installation.
This tutorial explains how to build a custom plugin:
https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial
(Setting Up Environment + Building a Plugin)

Maybe not exactly what you want, but it is an interesting hack I found out so I decided to share. You can programmatically set parameters of Jenkins job depending on the environment.
# check if job was trigered by timer
if [ $(env | grep -E '^BUILD_CAUSE=TIMERTRIGGER$') ] ; then
# your logic here, utilise the power of bash
if [ $(date +"%H") -eq 16 ] ; then PARAM=VALUE_1 ; fi
if [ $(date +"%H") -eq 17 ] ; then PARAM=VALUE_2 ; fi
fi

Without plugins, you can try cloning the job, and creating a build schedule with different parameter values. I.e. you might have job_morning and job_evening.
See How do I clone a job in jenkins?

Scheduling parameterized job is possible if there is a default value.
Here I will give an example using Jenkinsfile. Suppose in your pipeline script you have a param testUserName defined:
pipeline {
parameters {
string(name: 'testUserName', defaultValue: 'defaultTestUser',
description: 'Username to use for test scenarios')
}
stages {
stage('Run tests') {
steps {
sh "mvn verify --batch-mode -Dtest.user=${params.testUserName}"
}
}
}
}
When you press the "Build now" button, the job will run for the first time without asking for params (defaultValue will be used). After downloading and processing Jenkinsfile within that first run, the button name will change to "Build with Parameters". You click the button and type another user (not the default one defined in Jenkinsfile). The problem is that the value you typed will not persist between job runs. It will always reset to defaultValue.
To prevent value reset between job runs replace
defaultValue: 'defaultTestUser'
to
defaultValue: params.testUserName ?: 'defaultTestUser'
Now the job will always run with a value previously specified on "Build with Parameters". Found this solution on dev.to

Related

Build Jenkins job with Build periodically option with different argument

I have a Jenkins job which accepts only BranchName(bitbucket) as an input parameter.
I have scheduled this Job to run every morning 7 AM with Build periodically option H 7 * * *.
On triggering automatically, it takes default input parameter as development.
Now my requirement is that I need to pass few other branch names as input parameter automatically.
One option I tried it Down stream job with other branch name, but that works only from one branch and not a sophisticated solution.
Is there an easy way I can achieve this?
Job Configuration
If you only want to run a known set of branches you can either:
Create an upstream job for every branch that triggers the build with different parameters.
Create one upstream job, that utilize an list, loop over that list and execute the jobs in parallel.
If you need to get the list of branches dynamically, I would assume, that running sh script: 'git branch', returnStdout: true and some Groovy string split operation is the easiest way to archive that.

How to disable "build now" option?

For a given scripted pipeline(jenkins), the pipeline should only get triggered through webhook from GitLab
Build Now option should be disabled for that pipeline.
Can we configure Jenkins, to disable Build Now option for a specific pipeline script job in jenkins?
EDIT: Here the solution with an scripted Pipeline:
node {
def userIdCause = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')
stage("Authorize Usage") {
if (userIdCause.size()) {
error('Aborting Build due to manual start - thats not permitted!')
}
}
}
How about the following solution without any extra plugin on an declarative pipeline:
pipeline {
...
stages {
stage ("Authorize Usage") {
when { expression { getCause() == "USER" } }
steps {
currentBuild.description = 'Aborting Build due to manual start - thats not permitted!'
error('Aborting Build due to manual start - thats not permitted!')
}
}
...
}
Have taken a look at this plug-in supplied on the Jenkin's site? Matrix Authorization Strategy Plugin :
Matrix Strategy
Specifically this sectionL Allow configuring per-agent permissions. This allows e.g. restricting per-agent build permissions when using the Authorize Project plugin (JENKINS-46654)
Not ideal, but if this is a 'freestyle pipeline job'
a quick workaround is to add a build step "Execute shell" as first step. You can use this to prevent a build, when noting has changed.
Every time your sources changes and you push to your repo, a build will have been triggered and as there are changes this script will not exit.
When you click the 'Build now', nothing should have changed in your repo (as the only way it can is through a push which would then trigger a build) it will causes an exit, and fail the build.
if [[ $GIT_COMMIT -eq $GIT_PREVIOUS_COMMIT ]]
then
echo "Exiting build - Nothing has changed"
echo "This is to prevent the usage of Jenkins 'build now'"
exit 1
fi
EDIT: This is the answer to the question of user #mohet in the comments of my other answer because it was to long for the comment section (https://stackoverflow.com/a/55058788/7746963).
The currentBuild variable, which is of type RunWrapper, may be used to refer to the currently running build...
Source: https://opensource.triology.de/jenkins/pipeline-syntax/globals .
hudson.model is the package name of most corresponding core jenkins classes. 'Hudson' because jenkins was once cloned from the codebase of his ancestor named 'hudson'.
You can look up them here: https://javadoc.jenkins.io/hudson/model/package-summary.html .
There you will also find https://javadoc.jenkins.io/hudson/model/Cause.UserIdCause.html . To specify directly the package$classname in some methods like getbuildcauses is the straightforward thought of jenkins dev Team. This reduces the failure potential and makes the code better readable and understandable.

Passing git changes to a file for use in later Jenkins jobs

ENVIRONMENT
I have a series of jobs in Jenkins where Job #1 is an initial build and job #n is deployment to production.
Only the first few jobs are connected, and all jobs are parameterized.
I only build the one time, and if that build is successful post build steps trigger a job to deploy that build to dev.
After deployment to dev I have to manually go to Jenkins and click to run the job to deploy to the next region/environment.
THE PROBLEM
I am able to successfully pass the $GIT_COMMIT to the downstream jobs because as a workspace based environment variable during job-run I can write it to a file for use later.
However, $CHANGES is an email-ext specific variable and I am having issues writing its contents to a file I can pass to downstream jobs for the purpose of tracking what the current build is deploying in a given environment.
My unfamiliarity with Groovy and my weak Google-fu have made trying pre-send script and post-send script difficult to work with to get the data I want passed to downstream jobs.
WHAT I HAVE TRIED
What works
I am able to send HTML emails using email-ext
I am able to pass $GIT_COMMIT to a file and use it in downstream jobs
I am able to load the contents of a file into an email using email-ext
What doesn't work
I cannot seem to use Groovy in a pre-send script to output the $CHANGES to a file for use.
Trying to output $CHANGES to a file in a post-send script also does not work, but probably wouldn't be best anyway since it would likely come after any opportunity to pass the file to a downstream job.
WHAT I HAVE NOT TRIED
I have seen suggestions to use the changelog registered by the SCM process, which apparently is recorded in XML which must then be parsed by either the initial build job or downstream jobs if it is to be formatted for inclusion in an HTML email.
HELP
If anyone has any suggestion on what to try next I would appreciate it. I'm pulling my hair out.
You can use this groovy script to access the build environment parameters of an arbitrary job on the same jenkins instance.
To execute the script you have to install the groovy plugin and execute the script as system groovy script.
import jenkins.model.Jenkins
job = Jenkins.instance.getJob("freestyle-test")
numbuilds = job.builds.size()
if (numbuilds == 0) { return }
lastbuild = job.builds[numbuilds - 1]
println 'JOB: ' + job.fullName
println ' -> lastbuild: ' + lastbuild.displayName + ' = ' + lastbuild.result
println ' -> lastbuild someEnv: ' + build.environment.get("SOME_ENV")
The coupling to the job is over the job name.
The selected build is the latest.

Jenkins - How to get and use upstream info in downstream

Executing upstream job called "A". On success of A executing test cases which is downstream project "B". But while sending mail from B we have to incorporate upstream project details (upstream project name, build no) in mail. So we can easily map / corelate the test run with respective upstream job.
In downstream project dashboard below details are displaying.
Started by upstream project Dev_RM_3.0_CI_Test build number 10
originally caused by:
I checked in https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project. but couldnt find anything to inherit in downstream.
Created sample job with below details to display the current job details.
echo $BUILD_NUMBER
echo $JOB_NAME
echo $BUILD_ID
But the output is
Building on master in workspace /var/lib/jenkins/workspace/env
[env] $ /bin/sh -xe /tmp/hudson970280339057643719.sh
+ echo 1
1
+ echo env
env
+ echo 1
1
Finished: SUCCESS
Any help to inherit upstream details in downstream job?
How to get current job details?
The message that you refer to your question "Started by upstream project "Chained/1-First" build number 34" for example, is available in the jenkins Cause.
Jenkins keeps the upstream build info in it's cause object. If your are using build DSL or Pipelines you may get it in groovy. Alternatively you can curl the job url and use jq to get the Cause
For example curl http://localhost:8080/job/Chained/job/2-Second/17/api/json
"_class": "org.jenkinsci.plugins.workflow.job.WorkflowRun",
"actions": [{
"_class": "hudson.model.CauseAction",
"causes": [{
"_class": "hudson.model.Cause$UpstreamCause",
"shortDescription": "Started by upstream project \"Chained/1-First\" build number 34",
"upstreamBuild": 34,
"upstreamProject": "Chained/1-First",
"upstreamUrl": "job/Chained/job/1-First/"
}]
}
Or from the pipeline for example:
node() {
stage('downstream') {
def upstream = currentBuild.rawBuild.getCause(hudson.model.Cause$UpstreamCause)
echo upstream?.shortDescription
}
}
You can get a bunch of information out of Cause, pending all the script approvals or a global shared step. You will get a null if a different cause triggers this build, eg commit, or user.
You can pass in the upstream variables via build parameters to the downstream job and then you can access them (in the downstream job) using things such as ${MyParameter1} and ${MyParameter2}.
You would need to:
Add build parameters to the downstream job. For example, a string parameter named "ParentJobName".
Add a post build "Trigger downstream parameterized builds on other projects" to the upstream job.
Add something like "Current Build parameters" or "Predefined parameters" to the #2 and pass in whatever you need. For example:
ParentJobName=${JOB_NAME}
Access the parameters as you would other build variables. e.g. ${ParentJobName}
You should be able to pass in the basic stuff that way. Anything more complicated than that and you will probably be better off using a plugin like Copy Artifacts Plugin to copy files or using the Jenkins API in a system groovy step to get/modify the upstream build, etc.
You can simply use params.variableName in your downstream job to retrieve the parameters passed from your upstream parameter job. Your downstream job need not necessarily be a parameterized job.
Extending #razboy answer:
this is good way if Cause cannot be whitelisted in sandbox. I forgot about Jenkins API and used current build console to look for string about trigger cause. You can try to fetch data from API as #razboy or get current console and grep it if you need simple stuff. Jenkins API is more flexible for more complex logic. To get API help,append /api to your build url: <jenkins_url>/job/<buildUrl>/<buildNumber>/api
def buildUrl = env.BUILD_URL
sh "wget $buildUrl -O currentConsole.txt"
statusCode = sh returnStatus: true,script: 'cat currentConsole.txt | grep -q "Started by upstream project"'
boolean startedByUpstream= statusCode==0
MeowRude's answer helped me. To repcap it, in upstream job:
build job: 'mail-test', parameters: [[$class: 'StringParameterValue', name: 'VERSION_NUMBER', value: '1.0.0.0']]
And in downstream job:
echo "${params.VERSION_NUMBER}"
You may have to have certain plugins installed, but
def causes = currentBuild.getBuildCauses()
will return an ArrayList of objects that will most likely provide the necessary details, for example upstreamProject for the full project name and upstreamBuild for the build number. Then you can correlate results between up- and downstream builds easily.
Source: link to pipeline-examples in razboy's comment above

Jenkins Promoted Build Parameter Value

I have a jenkins job that runs some tests and promotes the build if all tests pass.
I then have a second job that has a 'Promoted build parameter' which is used for deployments.
THe idea is that the deply job should let you pick one of the prompted builds for deploying. The issue I'm having is that I can pick a promoted build, but I have not idea how I access information about the build.
I've named the build parameter
SELECTED_BUILD
And according to the docs this should then be available via the environment.
The problem is that it doesn't seem to be bound to anything.
If I run a build step to exectute this sheel script:
echo $SELECTED_BUILD
echo ${SELECTED_BUILD}
The values are not interpolated / set.
Any idea how I can access the values of this param?
Many Thanks,
Vackar
Inject the information as variable user jenkins plugin (eject evn variable).
while triggering parameterized build on other job, pass above variable as parameter to next job.

Resources