Jenkins下游任务如何通过email-ext向上游Git提交者发送电子邮件通知?

7
这个问题是关于如何向在Jenkins中的下游任务中破坏集成测试的git committers发送电子邮件,并查看下游任务的更改列表。
我没有尝试过这里写的所有内容,所以可能会有错误,这些都是我遇到的代码的印象。
显然有很多尝试回答这个问题,但似乎没有一个令人满意的答案,因此我将详细说明。具体细节如下:
我们以前使用svn工作。我们的工作层次结构为一个任务检出并编译,触发其他任务获取编译产物并对其执行各种集成测试。
需要向破坏构建的上游svn committers发送电子邮件。
我们喜欢通过email-ext插件(https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin)发送电子邮件,因为它非常可定制,我们经常使用此功能。
Email ext插件使用当前任务的changelog.xml来查找谁破坏了构建。由于changelog.xml是通过checkout操作创建的,因此它存在于上游任务中。因此,email-ext似乎不知道应该向谁发送电子邮件。
如果您决定包括culprits,则可以使用-Dhudson.upstreamCulprits=true启动jenkins,这会更改email-ext的行为,但如果您不想包括culprits,则这并不会帮助您。此外,在下游任务中似乎无法使用changeset。
还有一个blame-upstream committers插件,但它似乎与email-ext不兼容。 upstreamCulprits和blame-upstream似乎都需要指纹识别,而我们宁愿不使用这种方式,因为我们有很多文件和很多任务...这会带来严重的性能问题。
我们使用BlameSubversion插件(https://wiki.jenkins-ci.org/display/JENKINS/BlameSubversion)解决了我们的问题。它显然是从触发此任务的上游项目复制changelog.xml,因此当此任务失败并查找在changelog中破坏构建的用户时,它可以找到他们,并且他们也出现在changelog中。
所以我们对svn非常满意。现在,我们迁移到git。没有Blame Git插件。我们不介意编写一个。我们只需要了解是否应该。人们已经将git和jenkins一起使用了一段时间。我们不能是第一个遇到这个困难的人...谢谢,Nathan.

请解释:“还有一个责备上游提交者插件,但似乎与email-ext不兼容。” - Gonen
从我在代码和插件描述中看到的,邮件功能似乎是通用的Jenkins邮件功能或者是插件独有的功能。但这不是email-ext的邮件功能。我们真正需要的是email-ext的特定邮件功能,所以这个插件对我们没有帮助。 - nathan g
1个回答

7
这是我使用Clearcase的方法,对于svn应该很相似。在输入电子邮件地址列表的区域中添加以下内容:

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

在$JENKINS_HOME/email-templates中创建一个名为committers.groovy的新脚本,并编写类似以下内容的代码:
// 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(',')

这将生成一个字符串,该字符串将用上游作业的提交者列表替换${SCRIPT}内容令牌。

非常好的想法和(我希望)实现。 我将适应Git并将其集成到我们的流程中。 非常感谢! - nathan g
谢谢,这很有帮助!我必须进行微调,因为它试图发送完整名称“Joe Smith@company.com”,而不是用户ID“jsmith@company.com”。user = hudson.model.Hudson.instance.getUser(cs.user) if(user != null) { committers.add(user.id) } - Kevin Brotcke
另外,我找到了一种获取电子邮件的方法,而不是用户ID。 email = new URL("http://jenkins-server/user/" + user.id + "/api/xml?xpath=/user/property/address").getText()[9..-11] - Kevin Brotcke
嗯...亲爱的@nathang - 需要进行任何适应吗? - orshachar
@Or Shachar,它已经因为我们开发的一种方法而变得无关紧要了,在这种方法中,执行SCM检索操作(git克隆/拉取)的工作同时也负责所有的电子邮件发送,因此它在本地拥有提交者列表。 - nathan g

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接