这里的可编辑邮件通知指的是email-ext这个插件。使用之前需要在jenkins的全局设置里找到Extended E-mail Notification,然后配置你的邮件服务器地址等信息,这里不再贴图了,也不会详细介绍,大家都说的很清楚了。

    email-ext如果没有的话自己搜索安装一下,好像目前最新的jenkins版本都是自带的,有一点要注意的是还需要安装Email Extension Template Plugin插件

    我们的重心全放在如何做到发出一封包含我们想要的信息的邮件。这里我们来认识Jelly脚本。

    2.9版本新增了使用Jelly脚本的功能。Jelly脚本功能强大,可以将它入Jenkins API以获取想要或需要的任何信息。有两个现成的Jelly脚本与插件打包在一起,当然你也可以编写自己的脚本。

    有两种可用的默认Jelly脚本; 一个是为HTML电子邮件设计的,另一个是为文本电子邮件设计的。查看这些模板的外观截图。可以使用模板参数指定您想要的脚本。每个脚本的用法如下:
        1. 仅文本Jelly脚本:$ {JELLY_SCRIPT,template =“text”}
        2. HTMLJelly脚本:$ {JELLY_SCRIPT,template =“html”}

  Jelly脚本特别强大,因为它们为Jenkins API提供了一个pull,包括hudson.model.AbstractBuild和hudson.model.AbstractProject。例如,如何做到这一点,看看现有的HTML和文本脚本。

    使用定制的Jelly脚本(那些不包含在email-ext中的脚本)需要Hudson管理员的配合。步骤相对简单:
        1. 创建Jelly脚本。脚本的名称应该是<name> .jelly。名字以.jelly结尾非常重要。

        2.让您的Jenkins管理员将脚本放置在$ JENKINS_HOM\Eemail-templates这个路径中。


        3.使用模板参数等于您的脚本文件名而不带.jelly扩展名的Jelly标记。例如,如果脚本文件名是foobar.jelly,则电子邮件内容将如下所示:$ {JELLY_SCRIPT,template =“foobar”}。

    Jelly脚本提示:

        可以通过查询构建操作来获取其他插件操作的对象,例如:$ {it.getAction('hudson.plugins.fitnesse.FitnesseResultsAction')}但是需要提前知道此操作对象允许的所有功能,并遍历结果。

    我给出一个示例,我使用的是用自己编写的模板与jelly脚本混合,实际配置如下(触发原因,这里我使用的jelly脚本)

<!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: 15pt; font-family: Tahoma, Arial, Helvetica, sans-serif">  
        <tr>  
            <td><br />  
            <b><font color="#0B610B">自动部署信息</font></b>  
            <hr size="2" width="100%" align="center" /></td>
        </tr>  
        <tr>  
            <td>  
                <ul>  
                    <li>项目名称 : ${PROJECT_NAME}</li>  
                    <li>构建编号 : 第${BUILD_NUMBER}次构建</li>
                    <li>构建详情查看 : <a href="http://%E4%B8%9C%E8%88%AA%E6%9C%8D%E5%8A%A1/">点击查看</a></li>  
                    <li>触发原因 : ${JELLY_SCRIPT,template="template_for_123"}</li>  
                </ul>  
            </td>  
        </tr>  
    </table>  
</body>  
</html>  

    这里我给出与插件一起下载下来的模板HTML-Jelly脚本以及它的效果图。

Skip to content
Features
Business
Explore
Marketplace
Pricing
This repository
Search
Sign in or Sign up
 Watch 160  Star 197  Fork 440 jenkinsci/email-ext-plugin
 Code  Pull requests 0  Projects 0  Insights
Branch: master Find file Copy path email-ext-plugin/src/main/resources/hudson/plugins/emailext/templates/html.jelly
8016062  on 28 Nov 2017
@davidvanlaatum davidvanlaatum improvements to template
4 contributors @kohsuke @davidvanlaatum @slide @mfriedenhagen
RawBlameHistory     
254 lines (226 sloc)  9.25 KB
<?jelly escape-by-default='true'?>
<!DOCTYPE html [
    <!ENTITY nbsp "&#38;nbsp;">
]>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define">

<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>


<!-- GENERAL INFO -->

<TABLE>
  <TR><TD align="right">
    <j:choose>
      <j:when test="${build.result=='SUCCESS'}">
        <IMG SRC="${rooturl}static/e59dfe28/images/32x32/blue.gif" />
      </j:when>
	  <j:when test="${build.result=='FAILURE'}">
        <IMG SRC="${rooturl}static/e59dfe28/images/32x32/red.gif" />
      </j:when>
      <j:otherwise>
        <IMG SRC="${rooturl}static/e59dfe28/images/32x32/yellow.gif" />
      </j:otherwise>
    </j:choose>
  </TD><TD valign="center"><B style="font-size: 200%;">BUILD ${build.result}</B></TD></TR>
  <TR><TD>Build 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 of build:</TD><TD>${it.timestampString}</TD></TR>
  <TR><TD>Build duration:</TD><TD>${build.durationString}</TD></TR>
</TABLE>
<BR/>


<!-- CHANGE SET -->

<j:set var="changeSet" value="${build.changeSet}" />
<j:if test="${changeSet!=null}">
  <j:set var="hadChanges" value="false" />
  <TABLE width="100%">
    <TR><TD class="bg1" colspan="2"><B>CHANGES</B></TD></TR>
    <j:forEach var="cs" items="${changeSet}" varStatus="loop">
      <j:set var="hadChanges" value="true" />
      <j:set var="aUser" value="${cs.hudsonUser}"/>
      <TR>
        <TD colspan="2" class="bg2">  Revision <B>${cs.commitId?:cs.revision?:cs.changeNumber}</B> by
          <B>${aUser!=null?aUser.displayName:cs.author.displayName}: </B>
          <B>(${cs.msgAnnotated})</B>
         </TD>
      </TR>
      <j:forEach var="p" items="${cs.affectedFiles}">
        <TR>
          <TD width="10%">  ${p.editType.name}</TD>
          <TD>${p.path}</TD>
        </TR>
      </j:forEach>
    </j:forEach>
    <j:if test="${!hadChanges}">
      <TR><TD colspan="2">No Changes</TD></TR>
    </j:if>
  </TABLE>
<BR/>
</j:if>


<!-- ARTIFACTS -->

<j:set var="artifacts" value="${build.artifacts}" />
<j:if test="${artifacts!=null and artifacts.size()>0}">
  <TABLE width="100%">
    <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
    <TR>
      <TD>
        <j:forEach var="f" items="${artifacts}">
      	  <li>
      	    <a href="${rooturl}${build.url}artifact/${f}">${f}</a>
      	  </li>
      	</j:forEach>
      </TD>
    </TR>
  </TABLE>
<BR/>  
</j:if>


<!-- MAVEN ARTIFACTS -->

<j:set var="mbuilds" value="${build.moduleBuilds}" />
<j:if test="${mbuilds!=null}">
  <TABLE width="100%">
      <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
      <j:forEach var="m" items="${mbuilds}">
        <TR><TD class="bg2"><B>${m.key.displayName}</B></TD></TR>
        <j:forEach var="mvnbld" items="${m.value}">
        <j:set var="artifacts" value="${mvnbld.artifacts}" />
        <j:if test="${artifacts!=null and artifacts.size()>0}">
      <TR>
        <TD>
      	  <j:forEach var="f" items="${artifacts}">
      	    <li>
      	      <a href="${rooturl}${mvnbld.url}artifact/${f}">${f}</a>
      	    </li>
      	  </j:forEach>
      	</TD>
      </TR>
        </j:if>
        </j:forEach>
      </j:forEach>
  </TABLE>
<BR/>  
</j:if>


<!-- JUnit TEMPLATE -->

<j:set var="junitResultList" value="${it.JUnitTestResult}" />
<j:if test="${junitResultList.isEmpty()!=true}">
  <TABLE width="100%">
    <TR><TD class="bg1" colspan="2"><B>JUnit Tests</B></TD></TR>
    <j:forEach var="junitResult" items="${it.JUnitTestResult}">
      <j:forEach var="packageResult" items="${junitResult.getChildren()}">
        <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>
        <j:forEach var="test" items="${packageResult.getPassedTests()}">
          <j:if test="${test.status == 'FIXED'}">
            <TR bgcolor="white"><TD class="test_passed" colspan="2"><B><li>Fixed: ${test.getFullName()} (${test.getAge()})</li></B></TD></TR>
          </j:if>
        </j:forEach>
        <j:forEach var="failed_test" items="${packageResult.getFailedTests()}">
          <TR bgcolor="white"><TD class="test_failed" colspan="2"><B><li>Failed: ${failed_test.getFullName()} (${failed_test.getAge()})</li></B></TD></TR>
        </j:forEach>
      </j:forEach> 
    </j:forEach>  
  </TABLE>	
<BR/>
</j:if>


<!-- COBERTURA TEMPLATE -->

<j:set var="coberturaAction" value="${it.coberturaAction}" />
<j:if test="${coberturaAction!=null}">
  <j:set var="coberturaResult" value="${coberturaAction.result}" />
  <j:if test="${coberturaResult!=null}">
  	<table width="100%"><TD class="bg1" colspan="2"><B>Cobertura Report</B></TD></table>
	<table width="100%"><TD class="bg2" colspan="2"><B>Project Coverage Summary</B></TD></table>
            <table border="1px" class="pane">
                <tr>
                    <td>Name</td>
                    <j:forEach var="metric" items="${coberturaResult.metrics}">
                        <td>${metric.name}</td>
                    </j:forEach>
                </tr>
                <tr>
                    <td>${coberturaResult.name}</td>
                    <j:forEach var="metric" items="${coberturaResult.metrics}">
                        <td data="${coberturaResult.getCoverage(metric).percentageFloat}">${coberturaResult.getCoverage(metric).percentage}%
                            (${coberturaResult.getCoverage(metric)})
                        </td>
                    </j:forEach>
                </tr>
            </table>

            <j:if test="${coberturaResult.sourceCodeLevel}">
                <h2>Source</h2>
                <j:choose>
                    <j:when test="${coberturaResult.sourceFileAvailable}">
                        <div style="overflow-x:scroll;">
                            <table class="source">
                                <thead>
                                    <tr>
                                        <th colspan="3">${coberturaResult.relativeSourcePath}</th>
                                    </tr>
                                </thead>
                                ${coberturaResult.sourceFileContent}

                            </table>
                        </div>
                    </j:when>
                    <j:otherwise>
                        <p>
                            <i>Source code is unavailable</i>
                        </p>
                    </j:otherwise>
                </j:choose>
            </j:if>

            <j:forEach var="element" items="${coberturaResult.childElements}">
                <j:set var="childMetrics" value="${coberturaResult.getChildMetrics(element)}"/>
               <table width="100%"><TD class="bg2" colspan="2">Coverage Breakdown by ${element.displayName}</TD></table>
                <table border="1px" class="pane sortable">
                    <tr>
                        <td>Name</td>
                        <j:forEach var="metric" items="${childMetrics}">
                            <td>${metric.name}</td>
                        </j:forEach>
                    </tr>
                    <j:forEach var="c" items="${coberturaResult.children}">
                        <j:set var="child" value="${coberturaResult.getChild(c)}"/>
                        <tr>

                            <td>
                                ${child.xmlTransform(child.name)}
                            </td>
                            <j:forEach var="metric" items="${childMetrics}">
                                <j:set var="childResult" value="${child.getCoverage(metric)}"/>
                                <j:choose>
                                    <j:when test="${childResult!=null}">
                                        <td data="${childResult.percentageFloat}">${childResult.percentage}%
                                            (${childResult})
                                        </td>
                                    </j:when>
                                    <j:otherwise>
                                        <td data="101">N/A</td>
                                    </j:otherwise>
                                </j:choose>
                            </j:forEach>
                        </tr>
                    </j:forEach>
                </table>
            </j:forEach>
  </j:if>
<BR/>
</j:if>


<!-- CONSOLE OUTPUT -->

<j:getStatic var="resultFailure" field="FAILURE" className="hudson.model.Result"/>
<j:if test="${build.result==resultFailure}">
<TABLE width="100%" cellpadding="0" cellspacing="0">
<TR><TD class="bg1"><B>CONSOLE OUTPUT</B></TD></TR>
<j:forEach var="line" items="${build.getLog(100)}"><TR><TD class="console">${line}</TD></TR></j:forEach>
</TABLE>
<BR/>
</j:if>

</BODY>
</j:jelly>
? 2018 GitHub, Inc.
Terms
Privacy
Security
Status
Help
Contact GitHub
API
Training
Shop
Blog
About
Press h to open a hovercard with more details.


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐