在Jenkins里build now构建任务成功使用groovy模板发邮件没有问题,但是使用定时器构建任务后使用groovy模板发送邮件报错:
Exception raised during template rendering: Cannot invoke method getUserName() on null object java.lang.NullPointerException: Cannot invoke method getUserName() on null object at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:47) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:34) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:56) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120) at SimpleTemplateScript1.run(SimpleTemplateScript1.groovy:50) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.writeTo(SimpleTemplateEngine.java:181) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.toString(SimpleTemplateEngine.java:193) at hudson.plugins.emailext.plugins.content.ScriptContent.renderTemplate(ScriptContent.java:155) at hudson.plugins.emailext.plugins.content.ScriptContent.evaluate(ScriptContent.java:81) at hudson.plugins.emailext.plugins.content.AbstractEvalContent.evaluate(AbstractEvalContent.java:76) at org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro.evaluate(DataBoundTokenMacro.java:205) at org.jenkinsci.plugins.tokenmacro.Parser.processToken(Parser.java:472) at org.jenkinsci.plugins.tokenmacro.Parser.parseDelimitedToken(Parser.java:178) at org.jenkinsci.plugins.tokenmacro.Parser.parseToken(Parser.java:111) at org.jenkinsci.plugins.tokenmacro.Parser.parse(Parser.java:87) at org.jenkinsci.plugins.tokenmacro.Parser.process(Parser.java:75) at org.jenkinsci.plugins.tokenmacro.Parser.process(Parser.java:68) at org.jenkinsci.plugins.tokenmacro.TokenMacro.expand(TokenMacro.java:196) at org.jenkinsci.plugins.tokenmacro.TokenMacro.expandAll(TokenMacro.java:234) at hudson.plugins.emailext.plugins.ContentBuilder.transformText(ContentBuilder.java:79) at hudson.plugins.emailext.ExtendedEmailPublisher.addContent(ExtendedEmailPublisher.java:1013) at hudson.plugins.emailext.ExtendedEmailPublisher.createMail(ExtendedEmailPublisher.java:886) at hudson.plugins.emailext.ExtendedEmailPublisher.sendMail(ExtendedEmailPublisher.java:494) at hudson.plugins.emailext.ExtendedEmailPublisher._perform(ExtendedEmailPublisher.java:444) at hudson.plugins.emailext.ExtendedEmailPublisher.perform(ExtendedEmailPublisher.java:354) at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20) at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:814) at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:763) at hudson.model.Build$BuildExecution.cleanUp(Build.java:189) at hudson.model.Run.execute(Run.java:1943) at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44) at hudson.model.ResourceController.execute(ResourceController.java:101) at hudson.model.Executor.run(Executor.java:442)
使用的groovy邮件模板:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<style type="text/css">
/*base css*/
body
{
margin: 0px;
padding: 15px;
}
body, td, th
{
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Tahoma, sans-serif;
font-size: 10pt;
}
th
{
text-align: left;
}
h1
{
margin-top: 0px;
}
a
{
color:#4a72af
}
/*div styles*/
.status{background-color:<%=
build.result.toString() == "SUCCESS" ? 'green' : 'red' %>;font-size:28px;font-weight:bold;color:white;width:720px;height:52px;margin-bottom:18px;text-align:center;vertical-align:middle;border-collapse:collapse;background-repeat:no-repeat}
.status .info{color:white!important;text-shadow:0 -1px 0 rgba(0,0,0,0.3);font-size:32px;line-height:36px;padding:8px 0}
</style>
<body>
<div class="content round_border">
<div class="status">
<p class="info">The build <%= build.result.toString().toLowerCase() %></p>
</div>
<!-- status -->
<table>
<tbody>
<tr>
<th>项目名称:</th>
<td>${project.name}</td>
</tr>
<tr>
<th>触发原因:</th>
<%
cause = build.getCause(hudson.model.Cause.UserIdCause.class)
user_name = cause.getUserName()
%>
<td>Started by ${user_name} </td>
</tr>
<tr>
<th>构建编号 ${build.displayName}:</th>
<td><a
href="${rooturl}${build.url}">${rooturl}${build.url}</a></td>
</tr>
<tr>
<th>构建时间:</th>
<td>${it.timestampString}</td>
</tr>
<tr>
<th>构建耗时:</th>
<td>${build.durationString}</td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
</tbody>
</table>
<!-- main -->
<% def artifacts = build.artifacts
if(artifacts != null && artifacts.size() > 0) { %>
<b>离线报告:</b>
<ul>
<% artifacts.each() { f -> %>
<li><a href="${rooturl}${build.url}artifact/${f}">${f}</a></li>
<% } %>
</ul>
<% } %>
<!-- artifacts -->
<%
lastAllureReportBuildAction = build.getAction(ru.yandex.qatools.allure.jenkins.AllureReportBuildAction.class)
lastAllureBuildAction = build.getAction(ru.yandex.qatools.allure.jenkins.AllureBuildAction.class)
if (lastAllureReportBuildAction) {
allureResultsUrl = "${rooturl}${build.url}allure"
allureLastBuildSuccessRate = String.format("%.2f", lastAllureReportBuildAction.getPassedCount() * 100f / lastAllureReportBuildAction.getTotalCount())
}
%>
<% if (lastAllureReportBuildAction) { %>
<h2>测试结果</h2>
<table>
<tbody>
<tr>
<th>执行用例数:</th>
<td><a href="${allureResultsUrl}">${lastAllureReportBuildAction.getTotalCount()}</a></td>
</tr>
<tr>
<th>失败:</th>
<td>${lastAllureReportBuildAction.getFailedCount()} </td>
</tr>
<tr>
<th>成功:</th>
<td>${lastAllureReportBuildAction.getPassedCount()} </td>
</tr>
<tr>
<th>跳过:</th>
<td>${lastAllureReportBuildAction.getSkipCount()} </td>
</tr>
<tr>
<th>故障:</th>
<td>${lastAllureReportBuildAction.getBrokenCount()} </td>
</tr>
<tr>
<th>通过率: </th>
<td>${allureLastBuildSuccessRate}% </td>
</tr>
</tbody>
</table>
<%
String auth = "user" + ":" + "password"; byte[] encodedAuth = auth.bytes.encodeBase64().toString(); String authHeaderValue = "Basic " + new String(encodedAuth);
content=new URL("${allureResultsUrl}/graph").getBytes( useCaches: true, allowUserInteraction: false, requestProperties: ["User-Agent": "Groovy Sample Script","Authorization": authHeaderValue])
%>
<img src="data:image/png;base64, ${content.encodeBase64().toString()}"/>
<!-- <img lazymap="${allureResultsUrl}/graphMap" src="${allureResultsUrl}/graph" alt="Allure results trend"/> -->
<% } %>
<!-- content -->
<!-- bottom message -->
</body>