7
votes

this question is about how to send emails to git committers who broke integration tests in a downstream job, in jenkins, and see the list of changes in the downstream job.

i haven't tried everything i wrote here, so i could be wrong, these are impressions from the code i encountered.

there are apparently many attempts to answer this question, but none appear satisfactory, so i will elaborate. details follow:

we used to work with svn. our job hierarchy was one job checks out and compiles, and triggers other jobs that take the compilation artifacts and execute misc integration tests on them.

emails need to be sent to the upstream svn committers who broke the build.

we like to send emails via email-ext plugin (https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin) because it is very customizable, and we use this functionality heavily.

email ext plugin uses the changelog.xml of the current job to discover who broke the build. since the changelog.xml is created by the checkout operation, it exists in the upstream job. therefore, email-ext doesn't seem to know whom it should email.

IF you decide to include culprits, you can start your jenkins with -Dhudson.upstreamCulprits=true, which changes the behavior of email-ext, but that will not help you if you don't want to include culprits. additionally, the changeset doesn't seem to be available in the downstream job.

there is also a blame-upstream committers plugin, but it doesn't seem to play well with email-ext.

upstreamCulprits and blame-upstream both seem to need fingerprinting, and we'd rather not because we have a LOT of files and a LOT of jobs... this had serious performance issues.

we solved our problem with the BlameSubversion plugin (https://wiki.jenkins-ci.org/display/JENKINS/BlameSubversion). it apparently copies the changelog.xml from the upstream project that triggered this job, and so when this job fails and looks for users who broke the build in the changelog, it can find them, and they also appear in the changelog.

so we were very happy, about svn. now, we migrated to git. there is no Blame Git plugin. we don't mind writing one. we just need to understand if we should. people have been using git and jenkins together for quite some time. we can't be the first to run into this difficulty...

thanks, Nathan.

1
Please explain: "there is also a blame-upstream committers plugin, but it doesn't seem to play well with email-ext."Gonen
from what i saw in the code and the plugin description, it appears that the mailing functionality is probably the general jenkins mailing feature, or something unique to the plugin. it is not the mailing functionality of email-ext. we really need specific emailing functionality of email-ext, so this plugin won't help us.nathan g

1 Answers

7
votes

This is the way I do it with Clearcase, it should be pretty similar on svn. In the area where you enter the list of addresses to receive the email add the following:

, ${SCRIPT, script="committers.groovy"}

Create a new script, committers.groovy in $JENKINS_HOME/email-templates with something like the following:

// the goal is to find the top level job which should contain the changelist
def upstreamBuild = null
def cause = build.causes.find {
    if(it instanceof hudson.model.Cause.UpstreamCause) {
        return true 
    }
    return false
}

try {
    while(cause != null) {
        upstreamBuild = hudson.model.Hudson.instance.getItem(cause.upstreamProject).getBuildByNumber(cause.upstreamBuild)
        if(upstreamBuild == null) {
            break;
        }
        cause = upstreamBuild.causes.find {
            if(it instanceof hudson.model.Cause.UpstreamCause) {
                return true 
            }
            return false
        }
    }   
} catch(e) {
    // do nothing
}

// now we loop through the changeset and add all the users to a list
committers = []

if(upstreamBuild != null && upstreamBuild.changeSet != null) {
    upstreamBuild.changeSet.each() { cs ->
        if(cs.user != null) {
            committers.add(cs.user)
        }
    }
}

committers.unique().join(',')

This will generate a string which will replace the ${SCRIPT} content token with the list of committers from the upstream job.