I'm trying to run a few suits with tests in parallel as a part of workflow. So I create a map, put there a couple of closures and pass it to parallel step. The issue that I'm facing related to name of the HTML report. After execution, I see a few identical "HTML Report" links, so I can't open specific report - all of them have the same name. I had tried to make this name unique, but these attempts were not successful. Does anyone faced similar thing?
def testExecutions = [:]
def testExecution = {
node {
//code to run tests
publishHTML(target: [allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: true, reportDir: 'target/reports',
reportFiles: 'index.html',
reportName: "HTML Report " + it)
}
}
for (int i = 0; i < 2; i++) {
final k = i
testExecutions.put("tests $k", {testExecution(k)})
}
parallel(testExecutions)
Maybe the testExecution() function lacks the it parameter?
def testExecution(it) = {
node {
....
}
}
It seems that your node is on the wrong level. Now this rises a really interesting question.
My guess would be that when your workers would actually get the node to execute k or it would have be already evaluated by the master, meaning that from the point of view of parallel call the closure implicit argument would always be equal to 1. (although I consider myself not educated enough with Jenkins workflow and groovy to say for sure)
This version should work for you
def testExecutions = [:]
def testExecution = {
println "HTML Report " + it
}
for (int i = 0; i < 2; i++) {
final k = i
testExecutions.put("tests $k", {node{testExecution(k)}})
}
parallel(testExecutions)
Related
In my one jenkins pipeline job, I use createSummary of post build plugin to add some log url on the jenkins job UI. For the files moved to somewhere else, so I want to change the url. Is there a way to reset the information for this build?
manager.createSummary("red/yellow/green.gif")
.appendText("""log""", false, false, false, "black")
Any tips/advice are appriciated, thanks a lot!
I finally solved it using BadgeSummaryAction.
Jenkins.instance.getItemByFullName(jobName).builds.findAll { it.number > startnumber &&
it.number < endnumber}.each {
List<Action> actions = it.getActions();
List<BadgeSummaryAction> summaryActions = it.getActions(BadgeSummaryAction.class);
String iconText = "green.gif"
for(int i =0; i<summaryActions.size();i++) {
BadgeSummaryAction currentAction = summaryActions.get(i);
String sActionText = currentAction.getText()
if(sActionText.contains("FAILED")){
iconText = "red.gif"
}else if(sActionText.contains("UNSTABLE")){
iconText = "yellow.gif"
}
actions.remove(currentAction);
BadgeSummaryAction summary = new BadgeSummaryAction(iconText)
summary.appendText(replaceText, false);
it.addAction(summary);
}//end of for
}
I have the Build Failure Analyzer plugin installed in my Jenkins instance, and I have a number of different failures entered into the plugin. Does anyone know if it is possible to get the total number of failures across all jobs that have the same cause?
For example, I occasionally get "ChannelClosedException" failures if the build node goes offline during a build or test unexpectedly and I would like to determine how often this is happening across all my jobs. Is there some way to aggregate this value? I imagine it could be done through groovy if you can iterate over each build for each job and collect the Build Failure cause if one is detected.
Has anyone else done something like this before?
Not the exact answer... but should be able to modify to get what you are looking for:
Jenkins.instance.getAllItems(Job).each{
def jobBuilds=it.getBuilds()
//for each job get the things (you can limit at your convenience)
jobBuilds.each { build ->
def runningSince = groovy.time.TimeCategory.minus( new Date(), build.getTime() )
def currentStatus = build.buildStatusSummary.message
def cause = build.getCauses()[0] //we keep the first cause
def user = cause instanceof Cause.UserIdCause? cause.getUserId():""
println "Build: ${build} | Since: ${runningSince} | Status: ${currentStatus} | Cause: ${cause} | User: ${user}"
def parameters = build.getAction(ParametersAction)?.parameters
parameters.each {
println "Type: ${it.class} Name: ${it.name}, Value: ${it.dump()}"
}
}
}
Using some google-fu and some of the info from VinDev, I came up with this solution:
// get all jobs in Jenkins
Jenkins.instance.getAllItems(Job).each {
// get all builds for each job
def jobBuilds=it.getBuilds()
//for each build, get the name and status + and failure messages
jobBuilds.each { build ->
// get the build status
def currentStatus = build.buildStatusSummary.message
// we only care about the broken builds because we want failure messages
if (currentStatus.contains("broken")) {
println "Build: ${build} | Status: ${currentStatus}"
def BFA = build.actions.find{ it instanceof com.sonyericsson.jenkins.plugins.bfa.model.FailureCauseBuildAction };
if (BFA != null) {
for (failureCause in BFA.getFoundFailureCauses()) {
println("name: " + failureCause.getName() + ", description: " + failureCause.getDescription())
}
}
}
}
}
I need to grab the "Build Triggers -> Build Periodically" values using a groovy script. I need to check if it is enabled and what the Schedule values are but I have no luck while searching through Jenkins' github and the javadoc.jenkins api documentation.
List keys = new ArrayList(job.getTriggers().keySet());
for (int i = 0; i < keys.size(); i++) {
Object obj = keys.get(i);
if(obj.getDisplayName().contains("Build periodically")) {
println job.fullName + "," + job.getTriggers().get(keys.get(i)).spec
}
}
Is there a way to retrieve a list of individuals who broke the build in Jenkins Pipeline, just like the mailer plugin apparently does to send out a mail to those involved?
I've found one possible way, though it is somewhat limited to the amount of builds that are being kept. By iterating over the previousBuild hierarchy and their change logs, this may be a solution:
def getAuthors(def build) {
def userIds = []
build.changeSets.each { hudson.scm.SubversionChangeLogSet changeLogSet ->
userIds += changeLogSet.collect { it.author.id }
}
userIds.unique()
}
def getIndividualsWhoBrokeTheBuild() {
def userIds = []
for(def build = currentBuild; build.result != 'SUCCESS'; build = build.previousBuild) {
userIds += getAuthors(build)
}
userIds.unique()
}
Suppose a job keeps only five builds, this won't return the original felon, if it was broken more than five builds before.
I am working on Jenkins version 2.32.1 pipeline. I want to extract the parameters that were chosen in the previous build of my job.
In our previous Jenkins instance ( 1.627 ) we were using jenkins.model.Jenkins.instance.getItem(job).lastBuild.getBuildVariables().get(param);
For some reason this is not working in this version (I also tried disabling the sandbox).
Any pointers on how to accomplish it?
Simplified version of the previous script:
def build = Jenkins.get().getItems(org.jenkinsci.plugins.workflow.job.WorkflowJob).find {it.displayName == 'YOUR_JOB_NAME_HERE'}?.getLastBuild()
build.actions.find{ it instanceof ParametersAction }?.parameters.each {echo "${it.name}=${it.value}"}
Actually a little bit shorter version for those who want to get the params for the current build from the previous run and is working on new 2+ Jenkins versions.
To get 1 particular parameter:
def cls = currentBuild.getPreviousBuild().getRawBuild().actions.find{ it instanceof ParametersAction }?.parameters.find{it.name == 'cls'}?.value
Get all params respectfully:
def cls = currentBuild.getPreviousBuild().getRawBuild().actions.find{ it instanceof ParametersAction }?.parameters
Something like this might work, based on https://stackoverflow.com/a/19564602/3920342:
def h = hudson.model.Hudson.instance
def r = null
h.getItems(org.jenkinsci.plugins.workflow.job.WorkflowJob).each {project ->
if (project.displayName.equals('YOUR_JOB_NAME')) {
r = project
}
}
r.getBuilds().findAll { b -> // here we loop over all past builds, apply some filter if necessary
def p = b?.actions.find{ it instanceof ParametersAction }?.parameters
p.each {
echo "parameter ${it.name}: ${it.value}"
}
}
For those who are not able to access getActions() due to admin permissions i.e. facing the following error:
Scripts not permitted to use method hudson.model.Actionable getActions
They can copy the parameter variables to the env and get them using build.previousBuild.buildVariables
stage('Prepare environment') {
steps {
script {
env.MY_PARAM_COPY = "${MY_PARAM}"
}
}
}
println("MY_PARAM in previous build: ${currentBuild.previousBuild.buildVariables["MY_PARAM_COPY"]}")
That's how I made it works, answer from #dan.goriaynov and #jherb caused some CPS closure issues for me.
(the gist of the code is to allow only greater TAG number than the previous one to be deployed)
stage('Validate build number') {
def previous_build = currentBuild.getPreviousBuild().getRawBuild();
def PREVIOUS_TAG = '';
for (int i = 0; i < previous_build.allActions.size(); i++) {
if (previous_build.allActions[i] in hudson.model.ParametersAction) {
PREVIOUS_TAG = previous_build.allActions[i].getParameter("TAG").value
}
}
if (PREVIOUS_TAG.toInteger() > TAG.toInteger()) {
echo PREVIOUS_TAG
error('TAG number needs to be greater than the previous one')
}
}