Jenkins execute action after delete build - jenkins

I need to execute some action after build has been deleted (by user or automatically) on Jenkins.
Actually, I need the following:
Send http-request with info about deleted build.
Delete build artifacts on remote location.
About #2: I use Artifact Deployer plugin to deploy build, but because of issue
https://issues.jenkins-ci.org/browse/JENKINS-26109 build is not deleting on remote location after build has been deleted.
Any way, how I can do something on deleting build? Maybe I have to write script or create plugin?

There is a class RunListener which has method onDeleted.
Do something like this:
import hudson.model.Run;
import hudson.model.listeners.RunListener;
import hudson.Extension;
#Extension
public class DeleteListener extends RunListener<Run> {
#Override
public void onDeleted(Run r) {
// your code here
}
}
Moreover, remember that if you delete job - event onDeleted will not be fired.

I don't think Plugin is required for this.
You can write a cron job for this which checks the build directory continuously for any changes in the contents.
$JENKINS_HOME/jobs/your_job_here/builds/
If any of the folder is deleted that means a build is deleted manually/automatically. Then you can trigger a mail or perform whatever task you want to do as now you know a build has been deleted.

Related

How to access trigger event properties in a Jenkins pipeline script

I have a Jenkins job config that uses the "Build whenever the specified event is seen" trigger (supported by the Cloudbee's Notification API plugin) and specifies a Jmespath Query (e.g. ref=='refs/heads/master') and runs a pipeline script. I want to access other properties in the trigger event (e.g. repository.full_name) from within the pipeline script. How can I do this?
Found the answer. The data I was looking for is in the com.cloudbees.jenkins.plugins.pipeline.events.EventTriggerCause instance of the build causes. For example, the following code finds all the commits:
def newCommits = currentBuild.rawBuild.getCauses().findAll {
it instanceof com.cloudbees.jenkins.plugins.pipeline.events.EventTriggerCause
}.collect{
it.getEvent().commits
}

How to run groovy script to read build cause?

I am writing a first groovy script in the Jenkins, have an upstream job A which calls job B.
Being in job B I need to read GERRIT_CHANGE_NUMBER which triggered the job A.
In below e.g, how to get 28331 in the downstream job B?, its printed in the job B's console as below:
Started by upstream project some_up_project build number 100
originally caused by:
Triggered by Gerrit: https://gerrit-server.com/28331
I looked at this SO answer, but not sure how to do this in jenkins.
In job B, I did Add build step to add Execute system Groovy script section, then chose Groovy command in its dropdown, and in the Groovy Script area, added below for testing purpose, it gives error as unable to resolve class Run.cause ..., tried many other ways too and nothing worked.
import hudson.model.Run
for (cause in Run.getCauses()) {
if (cause instanceof Run.Cause.UserIdCause) {
println cause.getUserName()
}
}
there is no such class Run.Cause
start from something that works: hudson.model.Run
search for the documentation: hudson.model.Run.getCauses()
the method returns: List<Cause>
so, import this class into your code and use it:
import hudson.model.Cause
import hudson.model.Run
for (cause in Run.getCauses()) {
if (cause instanceof Cause.UserIdCause) {
println cause.getUserName()
}
}
Note: I have not tested the code. I just gave you an idea how to resolve an error.

Select a different runner for cucumber.api.cli.Main?

Is it possible to define/specify a runner when starting tests from cucumber's command line(cucumber.api.cli.Main)?
My reason for this is so i can generate xml reports in Jenkins and push the results to ALM Octane.
I kind of inherited this project and its using gradle to do a javaexect and call cucumber.api.cli.Main
I know its possible to do this with #RunWith(OctaneCucumber.class) when using JUnit runner + maven (or only JUnit runner), otherwise that tag is ignored. I have the custom runner with that tag but when i run from cucumber.api.cli.Main i can't find a way to run with it and my tag just gets ignored.
What #Grasshopper suggested didn't exactly work but it made me look in the right direction.
Instead of adding the code as a plugin, i managed to "hack/load" the octane reporter by creating a copy of the cucumber.api.cli.Main, using it as a base to run the cli commands and change a bit the run method and add the plugin at runtime. Needed to do this because the plugin required quite a few parameters in its constructor. Might not be the perfect solution, but it allowed me to keep the gradle build process i initially had.
public static byte run(String[] argv, ClassLoader classLoader) throws IOException {
RuntimeOptions runtimeOptions = new RuntimeOptions(new ArrayList<String>(asList(argv)));
ResourceLoader resourceLoader = new MultiLoader(classLoader);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
Runtime runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
//====================Added the following lines ================
//Hardcoded runner(?) class. If its changed, it will need to be changed here also
OutputFile outputFile = new OutputFile(Main.class);
runtimeOptions.addPlugin(new HPEAlmOctaneGherkinFormatter(resourceLoader, runtimeOptions.getFeaturePaths(), outputFile));
//==============================================================
runtime.run();
return runtime.exitStatus();
}

Triggering build information available in child job

I have a job in Jenkins called notification_job which uses the "Build after other projects are built" trigger. The list of jobs will be around 25 and continue to grow. The notification_job needs to know the triggering build's name and build number.
I would like all of the configuration to be done through the notification_job, not through the triggering jobs as that list will grow and become a pain to manage. So how can I retrieve the build name and number in the child job?
Jenkins version is 2.19.3
Thank you,
Duke
I was able to pull the data with a groovy script
import hudson.model.Cause
for (cause in build.getCauses()) {
if (cause instanceof Cause.UpstreamCause) {
println cause.getUpstreamProject()
println cause.getUpstreamBuild()
}
}

Using the ez-template plugin for Jenkins through the Jenkins Job DSL doesn't apply the template after creation

I am working on automating the creation of Jenkins jobs by using the Jenkins Job DSL (Groovy). Right now, I am trying to automate the creation of a job that uses the ez-template plugin to use an already existing template and apply that to my newly created job. However, after I am done writing the necessary configuration:
job('foo') {
properties {
templateImplementationProperty {
exclusions(['ez-templates', 'job-params', 'disabled', 'description'])
syncAssignedLabel(true)
syncBuildTriggers(true)
syncDescription(false)
syncDisabled(false)
syncMatrixAxis(true)
syncOwnership(true)
syncScm(true)
syncSecurity(true)
templateJobName('template')
}
}
}
the job gets created alright... except the template is never applied until AFTER I manually hit the save button on the UI in the newly created job. Checking the config.xml of the created job I can see that the xml contains the configuration I specified, but it was never applied.
Looking at the ez-template code, I can see that this is due to the silentSave feature that was implemented in that plugin - it writes configuration to disk without triggering any save events.
I've tried methods available to the Jenkins API but I've had no success there. Any ideas on how I can apply my configuration?
Full disclosure: I'm a co-worker, and was able to help shredmasteryjm solve this. I figured it'd be best to put this out on the net for others.
The Groovy code needed to trigger template implementation contents to be updated is:
import hudson.model.*;
import jenkins.model.*;
import com.joelj.jenkins.eztemplates.utils.TemplateUtils;
import com.joelj.jenkins.eztemplates.TemplateImplementationProperty;
Jenkins j = Jenkins.getInstance()
Item job = j.getItemByFullName('foo')
TemplateImplementationProperty template = TemplateUtils.getTemplateImplementationProperty(job)
TemplateUtils.handleTemplateImplementationSaved(job, template)
This utilizes the EZ-Templates TemplateUtils class to trigger the actual save event, using the template that the job uses. Of note, if job 'foo' doesn't implement a template, then the 'template' variable will be null, causing this code to error. YMMV
In our case, we needed to also add in some useful information from another question: Access to build environment variables from a groovy script in a Jenkins build step ( Windows)
in order to utilize a parameterized job name. As such our completed script looks like this:
import hudson.model.*;
import jenkins.model.*;
import com.joelj.jenkins.eztemplates.utils.TemplateUtils;
import com.joelj.jenkins.eztemplates.TemplateImplementationProperty;
// get current thread / Executor
def thr = Thread.currentThread()
// get current build
def build = thr?.executable
def hardcoded_param = "parameter_job_name"
def resolver = build.buildVariableResolver
def hardcoded_param_value = resolver.resolve(hardcoded_param)
Jenkins j = Jenkins.getInstance()
Item job = j.getItemByFullName(hardcoded_param_value)
TemplateImplementationProperty template = TemplateUtils.getTemplateImplementationProperty(job)
TemplateUtils.handleTemplateImplementationSaved(job, template)
FYI ez-templates 1.3.0 now triggers off additional save events such that you do not need the above trick.

Resources