setting and accessing global environment variable in Jenkins - jenkins

I have a Jenkins pipeline view. Say for example the first job is BUILD followed by DEPLOY and TEST job. What I'm trying to achieve here is to have a 'rollback logic' in the test job, meaning when the test job is run and it is successful I want to set current build no as a global environment variable (so that I can potentially access build number from any job) possibly called TESTED_BUILD_NO. But if test fails then I want to trigger DEPLOY job by passing TESTED_BUILD_NO which will deploy last test build.
There is a plugin called promotion builds plugin, it mentions PROMOTION_BUILD_NO variable but when I look at /env-vars.html it is not listed there. I tired looking at api/xml as well but no mention of any promotion variables. Can this logic I mention here be achieved using this plugin? If not how is global environment set and accessed in Jenkins?

Instead of using global variables, you can always use lastStableBuild, which is automatically set by jenkins. In DEPLOY job, use link to lastStableBuild from TEST job, which form is : http://JENKINS_ADDRESS/job/JENKINS_JOB/lastStableBuild/
According to jenkins wiki:
Stable build A build is stable if it was built successfully and no publisher reports it as unstable.

You are best advised to manage global variables from the system management screens:
Manage Jenkins -> Configure System -> Global Properties
Much more reliable compared to setting these externally to Jenkins.
this can be changed using script or via execute shell/batch.
Or you can use simple groovy scrip to change the value based on Previous command/build status.

Related

Global Jenkins script that will be executed before a build is started

I'm searching for a way to execute automatically a global configured script BEFORE a Jenkins job will be started.
My use case is, all Jenkins jobs are only allowed to start if a specific environment variable is set.
If a variable is not set, the build should be aborted.
I found the Global Post Plugin https://wiki.jenkins.io/display/JENKINS/Global+Post+Script+Plugin, i only need the oposite what this Plugin does.
Maybe there's another solution?
I needed to chmod my /data/jenkins/.npm and /data/jenkins/.sbt directories before running all my builds.
I could either add a prebuild step to every job (redundant and messy) or I could go under Manage Jenkins -> Configure System.
We have a Cloud -> Amazon EC2 configuration section with "Init script" - you can add what you want to run there on slave startup.
However, if you really want something to run something for every job (not enough to run on jenkins slave startup) then you probably don't want to manually configure it for each job.
I suggest you look into Jenkins DSL as you can define preBuildSteps section on any/all job(s) which can then reference a common snippet (eg. a shell script to run).
Partial Solution:
Take a look at the Global Pre Script plugin. This plugin is less feature-rich than the Global Post Script plugin, but it should do at least a part of what you want. It notably lacks the option to abort the build, but it is able to manipulate parameters or other preconditions that your jobs rely on. You may also be able to submit a PR to add some means of preventing the build from executing.
Some options:
Modify Global Pre Script to be able to cleanly abort the build from groovy.
Change your existing jobs to check for a precondition (manually or via script). This not the most scalable option.
Replace your existing jobs with Pipeline jobs and use Shared Libraries to bottleneck the logic. (This is what I do).
Generate your jobs using the Job DSL Plugin and enforce a pre build step in every generated job. (This is what I also do)
Limitations:
Something to keep in mind for both global plugins: neither plugin provides a proper build step. The groovy code executes on the master.
One use case that neither plugin will handle is a between-job slave cleanup/sanity check.

Using credentials in Jenkins Promoted Builds

Outside of chaining separate Jenkins builds together, is there a way within a single build to get credentials (via binding or otherwise) or Injected Passwords available for use within the Promoted Builds plugin?
I'm using other environment variables that I wrote to a file in my build step and then read in using the Inject environment variables, but I was not looking to repeat that for a secret used at deploy/promotion time.
Note: I am using Jenkins 2.45
Thanks!
Unfortunately, this doesn't look possible, it is marked as a bug in the Jenkins tracker:
JENKINS-14169 Injected env variables not available for use in processing promotion.

Jenkins: how to test the slaves

I am creating a list of Jenkins jobs for sanity test of our Jenkins build environment. I want to create layers of jobs. The first layer of jobs will check the environment, e.g. if all slaves are up, the 2nd layer then can check the integration to other tools such as GitHub, TFS, SonarQube, then the 3rd layer can run some typical build projects. This sanity test can also be used to verify the environment after any major changes to the Jenkins servers.
We have about 10 slaves created on two servers, one Windows and one Linux. I know I can create a job to run on a specific slave, therefore test if the slave is online, but this way I need to create 10 jobs just to test all slaves. Is there a best approach to check if all slaves are online?
One option is to use Jenkins Groovy scripting for a task like this. The Groovy plugin provides the Jenkins Script Console (a useful way to experiment) and the ability to run groovy scripts as build steps. If you're going to use the Script Console for periodic maintenance, you'll also want the Scriptler plugin which allows you to manage the scripts that you run.
From Manage Jenkins -> Script Console, you can write a groovy script that iterates through the slaves and checks whether they are online:
for (node in Jenkins.instance.nodes) {
println "${node.name}, ${node.numExecutors}"
def computer = node.computer
println "Online: ${computer.online}, ${computer.connectTime} (${computer.offlineCauseReason})"
}
Once you have the basic checks worked out, you can create either a standalone script in Scriptler, or a special build to run these checks periodically.
It often takes some iteration to figure out the right set of properties to examine. As I describe in another answer, you can write functions to introspect the objects available to scripting. And so with some trial and error, you can develop a script performs the checks you want to run.

How to retrieve jenkins build pipeline number?

In Jenkins I would like to build my test environment based on the "Build Pipeline Number" to make tests and deployment repeatable (on the same source version), but I didn't find any environment variable to retrieve this number. I tried to use the BUILD_ID but it is different for each job (downstream project).
Is it possible to retrieve the Build Pipeline Number? Or is there any other control number that I can use that is the same for all the jobs (increases on a new build)?
If you are using the less popular Delivery pipeline plugin there is a PIPELINE_VERSION environment variable. Otherwise, with the Build pipeline plugin you would probably have to use your VCS revision number and pass it downstream with Parameterized Trigger Plugin
If you would like to see the list of all current available environment variables just run a batch command SET from your build step (or if linux in shell env)

How to get the latest promoted build number for a dependency in Jenkins

I have a grails app that depends on a custom grails plugin. In Jenkins, I want the release build for the app to depend on the latest promoted release build of the plugin. So, I thought I'd put a conditional in the BuildConfig.groovy to use an environment variable that has that value. So now I need a way to set an environment variable in Jenkins to the latest build number of that other job. Is there a way to do that?
If you can do the envisioned workflow manually (e.g. going into the main configuration and change a environment variable there), then you should be able to automate it using the Jenkins Command Line Interface. However, you can not directly change an environment variable in one job and read that changed value in another job.

Resources