Retrieve builds triggered by the 'build' step after builds are finalized - jenkins

I am using a Pipeline job to trigger several freestyle jobs during its execution, using the native 'build' step.
Later, after all the runs are finalized, I'd like to read info about those runs (name, number, duration, timestamp...) to collect metrics/stats regarding the overall runs.
I'm using the Groovy Event Listener plugin for that task.
Now, I was thinking to read the WorkflowRun object's actions (looking for BuildTriggerAction instances) to get the downstream builds, but they are not available.
run.getActions(BuildTriggerAction.class)
returns an empty list.
I've seen indeed that action is removed every time the triggered build is completed, as described in this ticket https://issues.jenkins-ci.org/browse/JENKINS-28673
My questions are:
do you know how to retrieve the handle to the triggered builds in another way? Not at runtime (I don't have the RunWrapper object, but the WorkflowRun instead). Maybe using the flow objects?
is there another way to fix the issues seen in the ticket, instead of removing the BuildTriggerAction actions?
Thanks in advance!

Related

Can there be a few build causes in Jenkins?

The currentBuild global variable in Jenkins has a method of getBuildCauses(). The Reference says this:
getBuildCauses
Returns a JSON array of build causes for the current build
I was wondering, why does this method returns an array? Is there any possibility that a build was caused by several causes?
There are cases where a job was triggered by another job that was e.g. started manually by a user. So this information about a user who triggered the parent job is made available in the array. In another case, this job may be rebuilt manually by a user from a previous run that was triggered by a webhook. Sometimes, people want to know the whole history of the job instance, and so it's made available in this array.

Jenkins replay feature

I would like to use Replay feature. The documentation said:
1) Can be called multiple times on the same run
2) Can also be called on Pipeline runs that are still in-progress
What is the difference with these two points? Could you explain me better?
1) Each 'Build' (or 'Run') has some configuration (like parameters of the build for 'Build with parameters') that sometime you want to reuse in Replay. You can launch multiple Replay on the same 'Build'. Each of the Replayed Build will get the same parameters as the original one.
2) You are able to launch Replay also on the 'Build' that is still in-progress. It is irrelevant for Replayed 'Build' because once launched, the original 'Build' already updated its object in Jenkins master with all that will be of use for Replay.

Jenkins: How can I know if an automatic process or a user has triggered a build?

Is there an environment variable in Jenkins which tells me if the build has been ran manually or automatically triggered by polling?
My pipeline works like a charm if automatically triggered, but if manually ran... it always fails, so I think I'm going to edit the pipeline to check how the build has been triggered.
Unfortunately variable env.BUILD_CAUSE is not set in Pipeline builds.
For pipeline jobs see following example
if ( currentBuild.rawBuild.getCauses()[0].toString().contains('UserIdCause') ){
// do steps for manual trigger here
}
Other possible causes to compare can be found here.
The ability to get causes for a workflow run was released in version 2.22 (2018 Nov 02) to the Pipeline Supporting APIs Plugin. The feature was requested in JENKINS-41272.
A couple methods were added to the currentBuild global variable with that release:
getBuildCauses
Returns a JSON array of build causes for the current build
EXPERIMENTAL - MAY CHANGE getBuildCauses(String causeClass)
Takes a string representing the fully qualified Cause class and returns a JSON array of build causes filtered by that type for the current build, or an empty JSON array if no causes of the specified type apply to the current build
See answer https://stackoverflow.com/a/53342374/5955565.
I have copy-pasted it here because this question is shown first in search results (unlike How to differentiate build triggers in Jenkins Pipeline).
See also ${YOUR_JENKINS_URL}/pipeline-syntax/globals for a complete, and up to date, list of properties available on currentBuild.

Jenkins plugin code that should excute before any kind of job is run in Jenkins

I am new to Jenkins plugin development. M trying to write a plugin that should be executed before any Multi configuration type job runs in Jenkins.
In this plugin I want to write rules that will check what configuration parameters user has selected while submitting the job, based on selected parameters, I want to decide whether to allow the job to run or to restrict it.
User should be shown reason as to why that job cannot be run in the Console Output.
Does anyone have any ideas which class I need to extend or which interface I need to implement in order to get a hook into Jenkins job run?
You could look at the Matrix Execution Strategy which allows for a groovy script to select which matrix combinations to run. I would think if your script threw an exception it would stop the build.
For background, the multi configuration projects run a control job (or flyweight) which runs the SCM phase then starts all the actual combinations. This plugin runs after the flyweight SCM checkout.
If nothing else, this will give you a working plugin to start from
Disclaimer: I wrote this plugin
Blocked queue job plugin was what I needed
Out of the box that plugin supports two ways to block the jobs -
Based on the result of last run of another project.
Based on result of last run of the current project
In that plugin the BlockQueueItemTaskDispatcher.java extends Jenkin's QueueTaskDispatcher providing us a hook into Jenkins logic to allow or block the jobs present in the queue from running.
I used this plugin as a starting point for developing a new plugin that allows us to restrict project based on parameters selected and the current time. Ultimate goal is to restrict production migrations from running during the day.
Overriding the isBlocked() method of QueueTaskDispatcher gave access to hudson.model.Queue.Item instance as an argument to me. Then I used the Item instance's getParams method to get access to build parameters selected by the user at runtime. Parsed the lifecyle value from it. Checked the current time. If lifecycle was Production and current time was day time then restricted the job by returning non null CauseOfBlockage from isBlocked() method. If that condition was false, then returnedCauseOfBlockage as null allowing the queued job to run.

How to Remotely start jenkins build and get back result transactionally?

I had a request a to create a java client and start jenkins build for a specific job; and get back the result of that build.
The problem is, the system is used by multiple users and their build might messed up altogether. Also the get latest build my retrieve me the previous finished build instead of current one. Is there anyway to do build/get result transactionally?
I don't think there's a way to get true transactional functionality (in the way that, say, Postgres is transactional), however, I think you can prevent collisions amongst multiple users by doing the following:
Have your build wrapped around a script (bash, Python, or similar) which takes out an exclusive lock on a semfile before the build and releases it after its done. That is, a file which serves as a semaphore that the build process must be able to exclusively lock in order to be able to proceed.
That way, if you have a build in progress, and another user triggers one, the in-progress build will have the semfile locked, and the 2nd one will block waiting for the exclusive lock on that file, getting the lock only once the 1st build is complete and has released the lock on the file.
Also, to be able to refer to each remote build after the fact, I would recommend you refer to my previous post Retrieve id of remotely triggered jenkins job.

Resources