Instantly share code, notes, and snippets.

Embed
What would you like to do?
A trigger script for the jenkins (hudson) email_ext plugin which informs users in case their commits introduce new violations or warnings. In contrast to the limit options of various other plugins for code analysis reporting this does not fail the build.A simple but insecure way to share this script between different jobs is to execute the follo…
import jenkins.model.Jenkins
build = Jenkins.instance.items[0].builds[0]
println build
println("Available actions on the build: " + build.actions)
def analysisCoreActions = []
// All static analysis actions based on static analysis core can be handled uniformly
analysisCoreActions.addAll(build.actions.findAll{it.class.name =~ "hudson.plugins.checkstyle.CheckStyle.*ResultAction"})
analysisCoreActions.addAll(build.actions.findAll{it.class.name =~ "hudson.plugins.findbugs.FindBugs.*ResultAction"})
analysisCoreActions.addAll(build.actions.findAll{it.class.name =~ "hudson.plugins.pmd.Pmd.*ResultAction"})
analysisCoreActions.addAll(build.actions.findAll{it.class.name =~ "hudson.plugins.dry.Dry.*ResultAction"})
analysisCoreActions.addAll(build.actions.findAll{it.class.name =~ "hudson.plugins.warnings.*ResultAction"})
analysisCoreActions.removeAll([null])
println "Found analysis core actions: " + analysisCoreActions
def newViolations = analysisCoreActions.sum{it.result.numberOfNewWarnings}
println "Found " + newViolations + " new violations in analysis core plugins"
// Specifically handle new tasks as we probably want to send something different in this case
def tasksAction = build.actions.find{it.class.name =~ "hudson.plugins.tasks.*ResultAction"}
def newTasks = 0
if (tasksAction != null) {
newTasks = tasksAction.result.numberOfNewWarnings
println "Found " + newTasks + " new tasks"
}
// now there are some special rules for plugins that do not use analysis core
// violations plugin
def violationsStatus(build) {
def violationsAction = build.actions.find{it.class.name =~ "hudson.plugins.violations.ViolationsBuildAction"}
if (violationsAction == null) {
return false
}
def previousBuild = build.previousBuild
if (previousBuild == null) {
return false
}
def previousViolationsAction = previousBuild.actions.find{it.class.name =~ "hudson.plugins.violations.ViolationsBuildAction"}
if (previousViolationsAction == null) {
return false
}
for (currentViolationState in violationsAction.report.violations) {
println currentViolationState.key + ": " + currentViolationState.value
def previousState = previousViolationsAction.report.violations[currentViolationState.key]
if (previousState == null) {
continue
}
println "Previous: " + previousState
if (currentViolationState.value > previousState && previousState >= 0) {
return true
}
}
return false
}
def violationsAdded = violationsStatus(build)
println "Added violations: " + violationsAdded
// cppcheck
def cppcheckStatus(build) {
def cppcheckAction = build.actions.find{it.class.name =~ "org.jenkinsci.plugins.cppcheck.CppcheckBuildAction"}
if (cppcheckAction == null) {
return false
}
def previousBuild = build.previousBuild
println "Previous cppcheck build: " + previousBuild
if (previousBuild == null) {
return false
}
def previousCppcheckAction = previousBuild.actions.find{it.class.name =~ "org.jenkinsci.plugins.cppcheck.CppcheckBuildAction"}
println "Previous cppcheck action: " + previousCppcheckAction
if (previousCppcheckAction == null) {
return false
}
return cppcheckAction.result.report.allErrors.size() > previousCppcheckAction.result.report.allErrors.size()
}
def cppcheckAdded = cppcheckStatus(build)
println "Added cppcheck errors: " + cppcheckAdded
// send email if we have new warnings
newViolations > 0 || newTasks > 0 || violationsAdded || cppcheckAdded
@slide

This comment has been minimized.

Copy link

slide commented Sep 26, 2013

FYI, I'm working on a way to use managed groovy scripts for templates and trigger scripts. So, you won't need the insecure way in the future.

@languitar

This comment has been minimized.

Copy link
Owner

languitar commented Sep 26, 2013

That's a really good idea!

@rshoemaker

This comment has been minimized.

Copy link

rshoemaker commented May 19, 2014

I'd really like to figure out how to setup this script to generate an e-mail whenever a new issue is introduced to the build, but I'm having trouble. Can you provide some instructions on how to configure jenkins to use this script? Thanks!

@res1st

This comment has been minimized.

Copy link

res1st commented Aug 1, 2014

Thank you for you code, but the documentation could be improved.
I copied your script to the "Pre-send Script" element of the Email-ext plugin, but no e-mail is send if a new findbugs warning is added.
Any idea what I'm doing wrong?
I also don't find your script output (println) in the build log.

@languitar

This comment has been minimized.

Copy link
Owner

languitar commented Nov 19, 2014

@res1st, sorry, never saw your post. I have updated the description accordingly. There is a dedicated trigger to add under the advanced section. You need to use that.

@annaannaanna

This comment has been minimized.

Copy link

annaannaanna commented Nov 26, 2014

Do you know if there is any way to source a groovy script in that section of Jenkins (by giving it the file path) instead of copy and pasting the script in there?

@gerardflynn

This comment has been minimized.

Copy link

gerardflynn commented Jan 14, 2015

Hi, I cant get the script to run in Jenkins correctly.
created the Editable Email Notification --> Advance Setting paste the above code into Pre-Send Script and save. ran Jenkins with warning and not calling the script is there something i doing wrong

@telmopmota

This comment has been minimized.

Copy link

telmopmota commented Jul 28, 2015

Helpful code!
Using it in Post-build actions .. Editable Email Notification .. Advanced Settings .. Add Trigger .. Script .. Advanced .. Trigger Script.

One minor improvement to it is use

build = this.binding.build

instead of

build = Jenkins.instance.items[0].builds[0]

Works even if we create new jobs copying current settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment