jenkins配置邮件及增强版邮件通知(转)


 

原文地址:https://blog.csdn.net/u013066244/article/details/78665075

安装插件

Email Extension Plugin

(安装插件,我喜欢先去下载hpi文件,然后再去手动安装)

jenkins默认的邮件通知

我先讲解下,默认的。 
jenkins默认就有一个邮件通知,只是太简单的,不能个性化或者说定制化。

设置系统管理员邮件地址

这里写图片描述

邮件通知

这里写图片描述

SMTP服务器:如果你使用的是公司邮箱,那么就询问你自己公司里的运维人员吧;他们一般都知道,至少我就是问公司里的运维人员;要是你打算使用QQ邮箱,那么你需要设置下,网上有教程;网易邮箱默认开启。 
说明:SMTP是一种协议 
②用户默认邮件后缀:根据自己情况去设置 
③勾选使用SMTP认证,用户名:根据自己情况设置,密码也是。 
SMTP端口:默认25

配置好了后,可以勾选 测试,在Test e-mail recipient输入自己的邮箱,看下能否成功。

成功后,我们可以到job中进行配置: 
这里写图片描述

这里写图片描述

配置好了后,接下来测试,我下面是故意写错echo,使其构建失败,验证邮件。

这里写图片描述

发送邮件的结果: 
这里写图片描述


可以看出这个邮件内容纯文本,连个超链接都没有,内容也不够丰富!

接下来我们使用增强版的邮件通知

系统配置

在安装好插件后,你的系统设置里面会有这么一个设置:

图片1


接上面图片: 
图片2

上面点击高级按钮后: 
这里写图片描述

SMTP server:和之前同理 
Default user E-mail suffix:根据自己情况填写 
③勾选Use SMTP Authentication,用户名和密码填写自己的 
SMTP port:默认25 
Default Content Type:邮件文档类型 
Default Recipients:默认接收人列表,已逗号进行分割

其他我都使用默认或者说没有填写,点击保存。

注意: 
上面配置中,凡是以Default开头的名称,都可以在job的配置中当做变量使用。比如:默认的收件人地址:在单独的job中可以这样使用$DEFAULT_RECIPIENTS

单个job的单独配置

增加构建后操作步骤,添加增强版邮件通知(看红色圈住的部分): 
这里写图片描述

之后你会得到:

这里写图片描述
这里写图片描述

稍微讲解下: 
Disable Extended Email Publisher:勾选后,邮件就不发送,看自己的情况喽,如果你想调试某些东西,又不想发邮件出去就可以勾选这个。 
Project Recipient List:收件人地址;多个收件人邮件地址用逗号进行分割;想使用全局默认配置的话,可以使用$DEFAULT_RECIPIENTS。 
Project Reply-To List:允许回复人的地址;想使用系统设置中的默认值的话,可以使用$DEFAULT_REPLYTO; 
Content Type:邮件文档的类型,可以设置HTML等格式; 
Default Subject:默认主题,也就是邮件标题;同理可以使用$DEFAULT_SUBJECT 
Default Content:默认邮件内容;这里是关键;我这里使用的是模板${SCRIPT, template="groovy-html.template"};后面会讲;当然不想使用模板的话,可以通过使用jenkins自身提供的变量来自己定义; 
Attach Build Log:发送的邮件是否包含日志; 
下面几个默认就好,最后一个Triggers非常关键; 
假设最后一个不改的话,邮件是接收不到的,这个是官方留下的一个大坑,一定要自己再添加一个Recipient List

点击保存,点击构建后,收到的邮件格式如下: 
这里写图片描述

遇到的问题

问题一

An attempt to send an e-mail to empty list of recipients, ignored.
  • 1

这个问题,我一直卡着很久,差不多1天吧!始终不知道为什么收不到邮件

直到Google到这个地方: 
https://stackoverflow.com/a/37167955/6952713

https://issues.jenkins-ci.org/browse/JENKINS-34731?focusedCommentId=257221&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-257221 
才知道,官方给了一个大坑。

问题二

Exception raised during template rendering: No signature of method: hudson.model.FreeStyleBuild.getExactRuns() is applicable for argument types: () values: [] Possible solutions: getActions(), getActions(java.lang.Class) groovy.lang.MissingMethodException: No signature of method: hudson.model.FreeStyleBuild.getExactRuns() is applicable for argument types: () values: [] Possible solutions: getActions(), getActions(java.lang.Class) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58) at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117) at SimpleTemplateScript3.run(SimpleTemplateScript3.groovy:106) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.writeTo(SimpleTemplateEngine.java:168) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.toString(SimpleTemplateEngine.java:180) at hudson.plugins.emailext.plugins.content.ScriptContent.renderTemplate(ScriptContent.java:127) at hudson.plugins.emailext.plugins.content.ScriptContent.evaluate(ScriptContent.java:68) at hudson.plugins.emailext.plugins.content.AbstractEvalContent.evaluate(AbstractEvalContent.java:64) at org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro.evaluate(DataBoundTokenMacro.java:199) at 
  • 1

这个错误是我在使用邮件模板时,报的错! 
我的步骤如下: 
我在参考官方 :https://wiki.jenkins.io/display/JENKINS/Email-ext+plugin 
中的Script content这一章节内容时,下载了两个Template Examples 
jenkins-matrix-email-html.template 
jenkins-generic-matrix-email-html.template

按照官方教程在jenkins home/home/jenkins/dataspace)目录中创建了email-templates文件夹,并把那两个模板上传上去了,之后在job配置中的Default Content中写入:

${SCRIPT, template="jenkins-matrix-email-html.template"}
  • 1

然后构建时,就报错! 
这一块也困扰我很久!直到Google到了这么一段话(网上资料真心少);

http://jenkins-ci.361315.n4.nabble.com/Email-Template-Testing-Exception-td4807117.html

内容如下:

Looks like you are trying to test a matrix template with a non matrix job.

意思是说:

看起来像你在一个非matrix job中测试一个matrix模板

之后又去查询什么是matrix job; 
这是一篇关于matrix的官方教程 
Building a matrix project

看到里面内容却是构建一个Multi-Configuration Projects;这时就有点迷糊了!接着查看Matrix Project Plugin这个插件;里面的讲解有这么一句话:

Multi-configuration (matrix) project type.

基本可以肯定matrix job就是Multi-configuration project(构建一个多配置项目)。也就是说我要使用jenkins-matrix-email-html.template这个模板就必须创建与之对应的job

经过测试后,果然可以,配置都是类似的:邮件结果如下: 
这里写图片描述

那么matrix job这个用的场景多吗? 
这是官方给出的经验:

Experience with Hudson - Building matrix project

其讲解到:

比如 你的项目想在jdk 1.4 、1.5、1.6中进行测试,你就可以通过创建这种类型的job


使用自定义模板

通过上面遇到的问题,我们有时会想自己来定义模板! 
使用自己的模板有两种方法:

方法一 不使用模板

Default Content这一栏中,自己通过Token来写: 
(这里的token不要翻译成令牌,因为不知道翻译成啥,就保留原文token吧)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>

<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
    <table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
        <tr>
            <td>
                <h2>
                    <font>来自Mr.Jenkins的邮件通知</font>
                </h2>
            </td>
        </tr>
        <tr>
            <td>
                <br />
                <b><font color="#0B610B">构建信息</font></b>
               <hr size="2" width="100%" align="center" />
             </td>
        </tr>
        <tr>
            <td>
                <ul>
                    <li>项目名称&nbsp;:&nbsp;${PROJECT_NAME}</li>
                    <li>触发原因&nbsp;:${CAUSE}</li>
                    <li>构建日志&nbsp;:&nbsp;<a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
                    <li>单元测试报告&nbsp;:<a href="${BUILD_URL}testReport/">${BUILD_URL}testReport/</a></li>
                    <li>工作目录&nbsp;:&nbsp;<a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>

                </ul>
            </td>
        </tr>
                <tr>
            <td><b><font color="#0B610B">构建日志:</font></b>
            <hr size="2" width="100%" align="center" /></td>
        </tr>
        <tr>
            <td><textarea cols="80" rows="30" readonly="readonly" style="font-family: Courier New">${BUILD_LOG}</textarea>
            </td>
        </tr>
    </table>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

这段代码是从网上找来的,我好奇的是这个写法:

${ENV, var="JOB_NAME"}
# 这个写法其实和${JOB_NAME}、$JOB_NAME是等价的
  • 1
  • 2

可以理解成:

${ENV(var:JOB_NAME)}
因为参数就一个所以可以简写为:
${JOB_NAME}或者$JOB_NAME
  • 1
  • 2
  • 3

方法二 使用模板

之前使用模板出错是因为使用了matrix项目的模板。 
如果使用groovy模板也是可以的

这是官方给的groovy的模板:

https://github.com/jenkinsci/email-ext-plugin/blob/master/src/main/resources/hudson/plugins/emailext/templates/groovy-html.template

在文件夹email-templates,创建一个文件,比如我:

//我的路径: /home/jenkins/dataspace/email-templates
[root@master01 email-templates] vim testy.template
// 再把官方给的模板复制粘贴进去,代码如下:
  • 1
  • 2
  • 3
<STYLE> BODY, TABLE, TD, TH, P { font-family:Verdana,Helvetica,sans serif; font-size:11px; color:black; } h1 { color:black; } h2 { color:black; } h3 { color:black; } TD.bg1 { color:white; background-color:#0000C0; font-size:120% } TD.bg2 { color:white; background-color:#4040FF; font-size:110% } TD.bg3 { color:white; background-color:#8080FF; } TD.test_passed { color:blue; } TD.test_failed { color:red; } TD.console { font-family:Courier New; } </STYLE>
<BODY>

<TABLE>
  <TR><TD align="right"><IMG SRC="${rooturl}static/e59dfe28/images/32x32/<%= (build.result == null || build.result.toString() == 'SUCCESS') ? "blue.gif" : build.result.toString() == 'FAILURE' ? 'red.gif' : 'yellow.gif' %>" />
  </TD><TD valign="center"><B style="font-size: 200%;">BUILD ${build.result ?: 'SUCCESSFUL'}</B></TD></TR>
  <TR><TD>URL</TD><TD><A href="${rooturl}${build.url}">${rooturl}${build.url}</A></TD></TR>
  <TR><TD>Project:</TD><TD>${project.name}</TD></TR>
  <TR><TD>Date:</TD><TD>${it.timestampString}</TD></TR>
  <TR><TD>Duration:</TD><TD>${build.durationString}</TD></TR>
  <TR><TD>Cause:</TD><TD><% build.causes.each() { cause -> %> ${cause.shortDescription} <% } %></TD></TR>
</TABLE>
<BR/>

<!-- CHANGE SET -->
<% def changeSets = build.changeSets if(changeSets != null) { def hadChanges = false %>
    <TABLE width="100%">
    <TR><TD class="bg1" colspan="2"><B>CHANGES</B></TD></TR>

<% changeSets.each() { cs_list -> cs_list.each() { cs -> hadChanges = true %>
        <TR>
          <TD colspan="2" class="bg2">&nbsp;&nbsp;Revision <B><%= cs.metaClass.hasProperty('commitId') ? cs.commitId : cs.metaClass.hasProperty('revision') ? cs.revision : cs.metaClass.hasProperty('changeNumber') ? cs.changeNumber : "" %></B> by
            <B><%= cs.author %>: </B>
            <B>(${cs.msgAnnotated})</B>
           </TD>
        </TR>
<% cs.affectedFiles.each() { p -> %>
        <TR>
          <TD width="10%">&nbsp;&nbsp;${p.editType.name}</TD>
          <TD>${p.path}</TD>
        </TR>
<% } } } if(!hadChanges) { %>
        <TR><TD colspan="2">No Changes</TD></TR>
<% } %>
  </TABLE>
<BR/>
<% } %>

<!-- ARTIFACTS -->
<% def artifacts = build.artifacts if(artifacts != null && artifacts.size() > 0) { %>
  <TABLE width="100%">
    <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
    <TR>
      <TD>
<% artifacts.each() { f -> %>
          <li>
            <a href="${rooturl}${build.url}artifact/${f}">${f}</a>
          </li>
<% } %>
      </TD>
    </TR>
  </TABLE>
<BR/>
<% } %>

<!-- MAVEN ARTIFACTS -->
<% try { def mbuilds = build.moduleBuilds if(mbuilds != null) { %>
  <TABLE width="100%">
      <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
<% try { mbuilds.each() { m -> %>
        <TR><TD class="bg2"><B>${m.key.displayName}</B></TD></TR>
<% m.value.each() { mvnbld -> def artifactz = mvnbld.artifacts if(artifactz != null && artifactz.size() > 0) { %>
      <TR>
        <TD>
<% artifactz.each() { f -> %>
            <li>
              <a href="${rooturl}${mvnbld.url}artifact/${f}">${f}</a>
            </li>
<% } %>
        </TD>
      </TR>
<% } } } } catch(e) { // we don't do anything } %>
  </TABLE>
<BR/>
<% } }catch(e) { // we don't do anything } %>

<!-- JUnit TEMPLATE -->

<% def junitResultList = it.JUnitTestResult try { def cucumberTestResultAction = it.getAction("org.jenkinsci.plugins.cucumber.jsontestsupport.CucumberTestResultAction") junitResultList.add(cucumberTestResultAction.getResult()) } catch(e) { //cucumberTestResultAction not exist in this build } if (junitResultList.size() > 0) { %>
 <TABLE width="100%">
 <TR><TD class="bg1" colspan="2"><B>${junitResultList.first().displayName}</B></TD></TR>
 <% junitResultList.each{ junitResult -> %>
     <% junitResult.getChildren().each { packageResult -> %>
        <TR><TD class="bg2" colspan="2"> Name: ${packageResult.getName()} Failed: ${packageResult.getFailCount()} test(s), Passed: ${packageResult.getPassCount()} test(s), Skipped: ${packageResult.getSkipCount()} test(s), Total: ${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()} test(s)</TD></TR>
        <% packageResult.getFailedTests().each{ failed_test -> %>
          <TR bgcolor="white"><TD class="test_failed" colspan="2"><B><li>Failed: ${failed_test.getFullName()} </li></B></TD></TR>
        <% } } } %>
 </TABLE>
 <BR/>
<% } %>

<!-- CONSOLE OUTPUT -->
<% if(build.result==hudson.model.Result.FAILURE) { %>
<TABLE width="100%" cellpadding="0" cellspacing="0">
<TR><TD class="bg1"><B>CONSOLE OUTPUT</B></TD></TR>
<% build.getLog(100).each() { line -> %>
    <TR><TD class="console">${org.apache.commons.lang.StringEscapeUtils.escapeHtml(line)}</TD></TR>
<% } %>
</TABLE>
<BR/>
<% } %>

</BODY>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156

之后把Default Content这一栏改为:

${SCRIPT, template="testy.template"}
  • 1

就可以了!

可以使用Email Template Testing 这个功能进行测试,把模板名称输入进去就可以啦!

这里写图片描述

假设你输入groovy-html.template,即使你的email-templates文件夹里压根没有这个文件,也是能成功的,这是因为该插件默认内置的就是这个模板!

安装插件

Email Extension Plugin

(安装插件,我喜欢先去下载hpi文件,然后再去手动安装)

jenkins默认的邮件通知

我先讲解下,默认的。 
jenkins默认就有一个邮件通知,只是太简单的,不能个性化或者说定制化。

设置系统管理员邮件地址

这里写图片描述

邮件通知

这里写图片描述

SMTP服务器:如果你使用的是公司邮箱,那么就询问你自己公司里的运维人员吧;他们一般都知道,至少我就是问公司里的运维人员;要是你打算使用QQ邮箱,那么你需要设置下,网上有教程;网易邮箱默认开启。 
说明:SMTP是一种协议 
②用户默认邮件后缀:根据自己情况去设置 
③勾选使用SMTP认证,用户名:根据自己情况设置,密码也是。 
SMTP端口:默认25

配置好了后,可以勾选 测试,在Test e-mail recipient输入自己的邮箱,看下能否成功。

成功后,我们可以到job中进行配置: 
这里写图片描述

这里写图片描述

配置好了后,接下来测试,我下面是故意写错echo,使其构建失败,验证邮件。

这里写图片描述

发送邮件的结果: 
这里写图片描述


可以看出这个邮件内容纯文本,连个超链接都没有,内容也不够丰富!

接下来我们使用增强版的邮件通知

系统配置

在安装好插件后,你的系统设置里面会有这么一个设置:

图片1


接上面图片: 
图片2

上面点击高级按钮后: 
这里写图片描述

SMTP server:和之前同理 
Default user E-mail suffix:根据自己情况填写 
③勾选Use SMTP Authentication,用户名和密码填写自己的 
SMTP port:默认25 
Default Content Type:邮件文档类型 
Default Recipients:默认接收人列表,已逗号进行分割

其他我都使用默认或者说没有填写,点击保存。

注意: 
上面配置中,凡是以Default开头的名称,都可以在job的配置中当做变量使用。比如:默认的收件人地址:在单独的job中可以这样使用$DEFAULT_RECIPIENTS

单个job的单独配置

增加构建后操作步骤,添加增强版邮件通知(看红色圈住的部分): 
这里写图片描述

之后你会得到:

这里写图片描述
这里写图片描述

稍微讲解下: 
Disable Extended Email Publisher:勾选后,邮件就不发送,看自己的情况喽,如果你想调试某些东西,又不想发邮件出去就可以勾选这个。 
Project Recipient List:收件人地址;多个收件人邮件地址用逗号进行分割;想使用全局默认配置的话,可以使用$DEFAULT_RECIPIENTS。 
Project Reply-To List:允许回复人的地址;想使用系统设置中的默认值的话,可以使用$DEFAULT_REPLYTO; 
Content Type:邮件文档的类型,可以设置HTML等格式; 
Default Subject:默认主题,也就是邮件标题;同理可以使用$DEFAULT_SUBJECT 
Default Content:默认邮件内容;这里是关键;我这里使用的是模板${SCRIPT, template="groovy-html.template"};后面会讲;当然不想使用模板的话,可以通过使用jenkins自身提供的变量来自己定义; 
Attach Build Log:发送的邮件是否包含日志; 
下面几个默认就好,最后一个Triggers非常关键; 
假设最后一个不改的话,邮件是接收不到的,这个是官方留下的一个大坑,一定要自己再添加一个Recipient List

点击保存,点击构建后,收到的邮件格式如下: 
这里写图片描述

遇到的问题

问题一

An attempt to send an e-mail to empty list of recipients, ignored.
  • 1

这个问题,我一直卡着很久,差不多1天吧!始终不知道为什么收不到邮件

直到Google到这个地方: 
https://stackoverflow.com/a/37167955/6952713

https://issues.jenkins-ci.org/browse/JENKINS-34731?focusedCommentId=257221&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-257221 
才知道,官方给了一个大坑。

问题二

Exception raised during template rendering: No signature of method: hudson.model.FreeStyleBuild.getExactRuns() is applicable for argument types: () values: [] Possible solutions: getActions(), getActions(java.lang.Class) groovy.lang.MissingMethodException: No signature of method: hudson.model.FreeStyleBuild.getExactRuns() is applicable for argument types: () values: [] Possible solutions: getActions(), getActions(java.lang.Class) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58) at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117) at SimpleTemplateScript3.run(SimpleTemplateScript3.groovy:106) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.writeTo(SimpleTemplateEngine.java:168) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.toString(SimpleTemplateEngine.java:180) at hudson.plugins.emailext.plugins.content.ScriptContent.renderTemplate(ScriptContent.java:127) at hudson.plugins.emailext.plugins.content.ScriptContent.evaluate(ScriptContent.java:68) at hudson.plugins.emailext.plugins.content.AbstractEvalContent.evaluate(AbstractEvalContent.java:64) at org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro.evaluate(DataBoundTokenMacro.java:199) at 
  • 1

这个错误是我在使用邮件模板时,报的错! 
我的步骤如下: 
我在参考官方 :https://wiki.jenkins.io/display/JENKINS/Email-ext+plugin 
中的Script content这一章节内容时,下载了两个Template Examples 
jenkins-matrix-email-html.template 
jenkins-generic-matrix-email-html.template

按照官方教程在jenkins home/home/jenkins/dataspace)目录中创建了email-templates文件夹,并把那两个模板上传上去了,之后在job配置中的Default Content中写入:

${SCRIPT, template="jenkins-matrix-email-html.template"}
  • 1

然后构建时,就报错! 
这一块也困扰我很久!直到Google到了这么一段话(网上资料真心少);

http://jenkins-ci.361315.n4.nabble.com/Email-Template-Testing-Exception-td4807117.html

内容如下:

Looks like you are trying to test a matrix template with a non matrix job.

意思是说:

看起来像你在一个非matrix job中测试一个matrix模板

之后又去查询什么是matrix job; 
这是一篇关于matrix的官方教程 
Building a matrix project

看到里面内容却是构建一个Multi-Configuration Projects;这时就有点迷糊了!接着查看Matrix Project Plugin这个插件;里面的讲解有这么一句话:

Multi-configuration (matrix) project type.

基本可以肯定matrix job就是Multi-configuration project(构建一个多配置项目)。也就是说我要使用jenkins-matrix-email-html.template这个模板就必须创建与之对应的job

经过测试后,果然可以,配置都是类似的:邮件结果如下: 
这里写图片描述

那么matrix job这个用的场景多吗? 
这是官方给出的经验:

Experience with Hudson - Building matrix project

其讲解到:

比如 你的项目想在jdk 1.4 、1.5、1.6中进行测试,你就可以通过创建这种类型的job


使用自定义模板

通过上面遇到的问题,我们有时会想自己来定义模板! 
使用自己的模板有两种方法:

方法一 不使用模板

Default Content这一栏中,自己通过Token来写: 
(这里的token不要翻译成令牌,因为不知道翻译成啥,就保留原文token吧)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>

<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
    <table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
        <tr>
            <td>
                <h2>
                    <font>来自Mr.Jenkins的邮件通知</font>
                </h2>
            </td>
        </tr>
        <tr>
            <td>
                <br />
                <b><font color="#0B610B">构建信息</font></b>
               <hr size="2" width="100%" align="center" />
             </td>
        </tr>
        <tr>
            <td>
                <ul>
                    <li>项目名称&nbsp;:&nbsp;${PROJECT_NAME}</li>
                    <li>触发原因&nbsp;:${CAUSE}</li>
                    <li>构建日志&nbsp;:&nbsp;<a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
                    <li>单元测试报告&nbsp;:<a href="${BUILD_URL}testReport/">${BUILD_URL}testReport/</a></li>
                    <li>工作目录&nbsp;:&nbsp;<a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>

                </ul>
            </td>
        </tr>
                <tr>
            <td><b><font color="#0B610B">构建日志:</font></b>
            <hr size="2" width="100%" align="center" /></td>
        </tr>
        <tr>
            <td><textarea cols="80" rows="30" readonly="readonly" style="font-family: Courier New">${BUILD_LOG}</textarea>
            </td>
        </tr>
    </table>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

这段代码是从网上找来的,我好奇的是这个写法:

${ENV, var="JOB_NAME"}
# 这个写法其实和${JOB_NAME}、$JOB_NAME是等价的
  • 1
  • 2

可以理解成:

${ENV(var:JOB_NAME)}
因为参数就一个所以可以简写为:
${JOB_NAME}或者$JOB_NAME
  • 1
  • 2
  • 3

方法二 使用模板

之前使用模板出错是因为使用了matrix项目的模板。 
如果使用groovy模板也是可以的

这是官方给的groovy的模板:

https://github.com/jenkinsci/email-ext-plugin/blob/master/src/main/resources/hudson/plugins/emailext/templates/groovy-html.template

在文件夹email-templates,创建一个文件,比如我:

//我的路径: /home/jenkins/dataspace/email-templates
[root@master01 email-templates] vim testy.template
// 再把官方给的模板复制粘贴进去,代码如下:
  • 1
  • 2
  • 3
<STYLE> BODY, TABLE, TD, TH, P { font-family:Verdana,Helvetica,sans serif; font-size:11px; color:black; } h1 { color:black; } h2 { color:black; } h3 { color:black; } TD.bg1 { color:white; background-color:#0000C0; font-size:120% } TD.bg2 { color:white; background-color:#4040FF; font-size:110% } TD.bg3 { color:white; background-color:#8080FF; } TD.test_passed { color:blue; } TD.test_failed { color:red; } TD.console { font-family:Courier New; } </STYLE>
<BODY>

<TABLE>
  <TR><TD align="right"><IMG SRC="${rooturl}static/e59dfe28/images/32x32/<%= (build.result == null || build.result.toString() == 'SUCCESS') ? "blue.gif" : build.result.toString() == 'FAILURE' ? 'red.gif' : 'yellow.gif' %>" />
  </TD><TD valign="center"><B style="font-size: 200%;">BUILD ${build.result ?: 'SUCCESSFUL'}</B></TD></TR>
  <TR><TD>URL</TD><TD><A href="${rooturl}${build.url}">${rooturl}${build.url}</A></TD></TR>
  <TR><TD>Project:</TD><TD>${project.name}</TD></TR>
  <TR><TD>Date:</TD><TD>${it.timestampString}</TD></TR>
  <TR><TD>Duration:</TD><TD>${build.durationString}</TD></TR>
  <TR><TD>Cause:</TD><TD><% build.causes.each() { cause -> %> ${cause.shortDescription} <% } %></TD></TR>
</TABLE>
<BR/>

<!-- CHANGE SET -->
<% def changeSets = build.changeSets if(changeSets != null) { def hadChanges = false %>
    <TABLE width="100%">
    <TR><TD class="bg1" colspan="2"><B>CHANGES</B></TD></TR>

<% changeSets.each() { cs_list -> cs_list.each() { cs -> hadChanges = true %>
        <TR>
          <TD colspan="2" class="bg2">&nbsp;&nbsp;Revision <B><%= cs.metaClass.hasProperty('commitId') ? cs.commitId : cs.metaClass.hasProperty('revision') ? cs.revision : cs.metaClass.hasProperty('changeNumber') ? cs.changeNumber : "" %></B> by
            <B><%= cs.author %>: </B>
            <B>(${cs.msgAnnotated})</B>
           </TD>
        </TR>
<% cs.affectedFiles.each() { p -> %>
        <TR>
          <TD width="10%">&nbsp;&nbsp;${p.editType.name}</TD>
          <TD>${p.path}</TD>
        </TR>
<% } } } if(!hadChanges) { %>
        <TR><TD colspan="2">No Changes</TD></TR>
<% } %>
  </TABLE>
<BR/>
<% } %>

<!-- ARTIFACTS -->
<% def artifacts = build.artifacts if(artifacts != null && artifacts.size() > 0) { %>
  <TABLE width="100%">
    <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
    <TR>
      <TD>
<% artifacts.each() { f -> %>
          <li>
            <a href="${rooturl}${build.url}artifact/${f}">${f}</a>
          </li>
<% } %>
      </TD>
    </TR>
  </TABLE>
<BR/>
<% } %>

<!-- MAVEN ARTIFACTS -->
<% try { def mbuilds = build.moduleBuilds if(mbuilds != null) { %>
  <TABLE width="100%">
      <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
<% try { mbuilds.each() { m -> %>
        <TR><TD class="bg2"><B>${m.key.displayName}</B></TD></TR>
<% m.value.each() { mvnbld -> def artifactz = mvnbld.artifacts if(artifactz != null && artifactz.size() > 0) { %>
      <TR>
        <TD>
<% artifactz.each() { f -> %>
            <li>
              <a href="${rooturl}${mvnbld.url}artifact/${f}">${f}</a>
            </li>
<% } %>
        </TD>
      </TR>
<% } } } } catch(e) { // we don't do anything } %>
  </TABLE>
<BR/>
<% } }catch(e) { // we don't do anything } %>

<!-- JUnit TEMPLATE -->

<% def junitResultList = it.JUnitTestResult try { def cucumberTestResultAction = it.getAction("org.jenkinsci.plugins.cucumber.jsontestsupport.CucumberTestResultAction") junitResultList.add(cucumberTestResultAction.getResult()) } catch(e) { //cucumberTestResultAction not exist in this build } if (junitResultList.size() > 0) { %>
 <TABLE width="100%">
 <TR><TD class="bg1" colspan="2"><B>${junitResultList.first().displayName}</B></TD></TR>
 <% junitResultList.each{ junitResult -> %>
     <% junitResult.getChildren().each { packageResult -> %>
        <TR><TD class="bg2" colspan="2"> Name: ${packageResult.getName()} Failed: ${packageResult.getFailCount()} test(s), Passed: ${packageResult.getPassCount()} test(s), Skipped: ${packageResult.getSkipCount()} test(s), Total: ${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()} test(s)</TD></TR>
        <% packageResult.getFailedTests().each{ failed_test -> %>
          <TR bgcolor="white"><TD class="test_failed" colspan="2"><B><li>Failed: ${failed_test.getFullName()} </li></B></TD></TR>
        <% } } } %>
 </TABLE>
 <BR/>
<% } %>

<!-- CONSOLE OUTPUT -->
<% if(build.result==hudson.model.Result.FAILURE) { %>
<TABLE width="100%" cellpadding="0" cellspacing="0">
<TR><TD class="bg1"><B>CONSOLE OUTPUT</B></TD></TR>
<% build.getLog(100).each() { line -> %>
    <TR><TD class="console">${org.apache.commons.lang.StringEscapeUtils.escapeHtml(line)}</TD></TR>
<% } %>
</TABLE>
<BR/>
<% } %>

</BODY>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156

之后把Default Content这一栏改为:

${SCRIPT, template="testy.template"}
  • 1

就可以了!

可以使用Email Template Testing 这个功能进行测试,把模板名称输入进去就可以啦!

这里写图片描述

假设你输入groovy-html.template,即使你的email-templates文件夹里压根没有这个文件,也是能成功的,这是因为该插件默认内置的就是这个模板!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM