1

我有一个 Jenkins CI 设置,我们使用 Perforce 作为我们的 SCM。

我已经配置了 Email-ext 插件,以在构建中断以及修复时通知开发人员。

目前,通知电子邮件正文仅使用$DEFAULT_CONTENT,但我真的很想在电子邮件内容中指出最新的 Perforce 更改列表,因为这对开发人员更有帮助。

我在想Changelist numberChangelist titleCommitter

关于如何做到这一点的任何想法?

4

1 回答 1

2

在 jenkins 邮件列表的某个地方,我找到了这个模板,我认为它可以满足您的需求。在您的 jenkins 根目录中创建一个文件夹“email-templates”,将文件放在那里并将其命名为“p4htmlmail.jelly”。然后在您的 jenkins 配置中放入${JELLY_SCRIPT,template="p4htmlmail"}email-ext 插件配置的 DEFAULT_CONTENT 字段。

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define">

<link type="text/css" rel="stylesheet" href="${rooturl}static/e59dfe28/css/style.css"/>
<link type="text/css" rel="stylesheet" href="${rooturl}static/e59dfe28/css/color.css"/>

<STYLE>
a:link,a:visited {
  text-decoration: underline;
  <!--color: #3B5998;-->
  color: #8B9DC3
}

a.success:link,a.success:visited {
  text-decoration: underline;
  color: #338033;
}

a.failure:link,a.failure:visited {
  text-decoration: underline;
  color: #900;
}

a.unstable:link,a.unstable:visited {
  text-decoration: underline;
  color: #F0C000;
}

<!--
body {
  background-color: #DFE3EE;
}-->

.pane {
  margin-top: 4px;
  white-space: nowrap;
}

.pane TD {
  padding: 4px 4px 3px 4px;
}

TABLE.pane {
  width: 100%;
  border: none;
}

TD.style1 {
  color: #3B5998;
  width: 10%;
}

TD.pane {
  padding: 3px 4px 3px 4px;
  vertical-align: middle;
}

TD.pane-header {
  border-top: 1px #8B9DC3 solid;
  border-bottom: 1px #8B9DC3 solid;
  background-color: #DFE3EE;
  font-weight: bold;
  font-family: Verdana, Helvetica, sans serif;
  font-size: 11px;
  color: #8B9DC3;
  padding-top: 10px;
  padding-bottom: 10px;
}

TD.pane-header-success {
  border-top: 1px #338033 solid;
  border-bottom: 1px #338033 solid;
  background-color: #E0FFE0;
  font-weight: bold;
  font-family: Verdana, Helvetica, sans serif;
  font-size: 11px;
  color: #338033;
  padding-top: 10px;
  padding-bottom: 10px;
}

TD.pane-header-failure {
  border-top: 1px #900 solid;
  border-bottom: 1px #900 solid;
  background-color: #FCC;
  font-weight: bold;
  font-family: Verdana, Helvetica, sans serif;
  font-size: 11px;
  color: #900;
  padding-top: 10px;
  padding-bottom: 10px;
}

TD.pane-header-unstable {
  border-top: 1px #F0C000 solid;
  border-bottom: 1px #F0C000 solid;
  background-color: #FFFFCE;
  font-weight: bold;
  font-family: Verdana, Helvetica, sans serif;
  font-size: 11px;
  color: #F0C000;
  padding-top: 10px;
  padding-bottom: 10px;
}

TH.pane {
  font-weight: bold;
}

SPAN.style1 {
  font-weight: bold;
  color: #8B9DC3;
}

SPAN.success {
  color: #338033;
}

SPAN.failure {
  color: #900;
}

LI.style1 {
  list-style: cirle outside;
}

LI.failure {
  list-style: cirle outside;
  color: #900;
}


</STYLE>



<BODY>
<j:set var="spc" value="&amp;nbsp;&amp;nbsp;" />


<!-- GENERAL INFO -->

<TABLE class="pane">
 <TBODY>
  <TR>
    <j:choose>
      <j:when test="${build.result=='SUCCESS'}">
    <TD colspan="2" class="pane-header-success">
    <SPAN>Build Result Summary - <A class="success" href="${rooturl}${build.url}">See full build details</A></SPAN>
     </TD>
      </j:when>
      <j:when test="${build.result=='FAILURE'}">
    <TD colspan="2" class="pane-header-failure">
    <SPAN>Build Result Summary - <A class="failure" href="${rooturl}${build.url}">See full build details</A></SPAN>
     </TD>
      </j:when>
      <j:otherwise>
    <TD colspan="2" class="pane-header-unstable">
    <SPAN>Build Result Summary - <A class="unstable" href="${rooturl}${build.url}">See full build details</A></SPAN>
     </TD>
      </j:otherwise>
    </j:choose>
  </TR>

  <TR>
    <TD class="style1">Project:</TD>
    <TD><A href="${rooturl}${project.url}">${project.name}</A></TD>
  </TR>

  <TR>
    <TD class="style1">Completion:</TD>
    <TD>${it.timestampString}</TD>
  </TR>

  <TR>
    <TD class="style1">Duration:</TD>
    <TD>${build.durationString}</TD>
  </TR>

  <TR>
    <TD class="style1">Status:</TD>
    <TD>
    <j:choose>
      <j:when test="${build.result=='SUCCESS'}">
    <IMG SRC="${rooturl}static/e59dfe28/images/16x16/blue.png"/>
      </j:when>
      <j:when test="${build.result=='FAILURE'}">
    <IMG SRC="${rooturl}static/e59dfe28/images/16x16/red.png"/>
      </j:when>
      <j:otherwise>
    <IMG SRC="${rooturl}static/e59dfe28/images/16x16/yellow.png"/>
      </j:otherwise>
    </j:choose>
    ${build.result}
    </TD>
  </TR>
  <TR>
    <TD class="style1">Help:</TD>
    <TD>
    Help text goes here.
    </TD>
  </TR>
 </TBODY>
</TABLE>
<BR/>


<!-- CHANGE SET -->

<j:set var="changeSet" value="${build.changeSet}" />
<j:if test="${changeSet!=null}">
  <j:set var="hadChanges" value="false" />
  <TABLE class="pane">
    <TBODY>
      <TR>
        <TD colspan="2" class="pane-header">
      <SPAN>Code Changes - <A href="${rooturl}${build.url}/changes">See full change details</A></SPAN>
        </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">
        <SPAN class="style1">
          Change <B>${cs.changeNumber}</B> by
          <B>${aUser!=null?aUser.displayName:cs.author.displayName}: </B>
          '${cs.msgAnnotated}'
        </SPAN>
      </TD>
        </TR>
        <j:forEach var="p" items="${cs.affectedFiles}">
      <TR>
        <TD width="2%">
          <j:switch on="${p.editType.name}">
        <j:case value="add">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-ADD.gif"/>
        </j:case>
        <j:case value="branch">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-BRANCH.gif"/>
        </j:case>
        <j:case value="delete">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-DELETE.gif"/>
        </j:case>
        <j:case value="edit">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-EDIT.gif"/>
        </j:case>
        <j:case value="import">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-IMPORT.gif"/>
        </j:case>
        <j:case value="integrate">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-INTEGRATE.gif"/>
        </j:case>
        <j:case value="move_add">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-MOVE_ADD.gif"/>
        </j:case>
        <j:case value="move_delete">
          <IMG SRC="${rooturl}plugin/perforce/icons/action-MOVE_DELETE.gif"/>
        </j:case>
        <j:default>
           ${p.editType.name} 
        </j:default>
          </j:switch>
        </TD>
        <TD><SPAN>${p.path}</SPAN></TD>
      </TR>
        </j:forEach>
      </j:forEach>
      <j:if test="${!hadChanges}">
        <TR><TD colspan="2">No Changes</TD></TR>
      </j:if>
    </TBODY>
  </TABLE>
<BR/>
</j:if>

<!-- JUNIT TEST OUTPUT -->

<j:set var="junitResultList" value="${it.JUnitTestResult}" />
<j:if test="${junitResultList.isEmpty()!=true}">
<TABLE class="pane">
 <TBODY>
    <TR>
       <TD colspan="2" class="pane-header">
      <SPAN>Unit Tests - <A href="${rooturl}${build.url}/testReport">See full test details</A></SPAN>
       </TD>
    </TR>

    <j:forEach var="junitResult" items="${it.JUnitTestResult}">
      <j:forEach var="packageResult" items="${junitResult.getChildren()}">
    <TR>
       <TD>
    Name: ${packageResult.getName()}, Failed: <SPAN class="failure">${packageResult.getFailCount()}</SPAN> test(s), Passed: <SPAN class="success">${packageResult.getPassCount()}</SPAN> test(s), Skipped: ${packageResult.getSkipCount()} test(s), Total: ${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()} test(s)
       </TD>
    </TR>
        <j:forEach var="failed_test" items="${packageResult.getFailedTests()}">
    <TR>
       <TD>
        <UL>
          <B>
        <LI class="failure">Failed: ${failed_test.getFullName()}</LI>
      </B>
    </UL>
       </TD>
    </TR>
        </j:forEach>
      </j:forEach>
    </j:forEach>
 </TBODY>
</TABLE>
<BR/>
</j:if>

<!-- CONSOLE OUTPUT -->

<j:getStatic var="resultFailure" field="FAILURE" className="hudson.model.Result"/>
<j:if test="${build.result==resultFailure}">
<TABLE class="pane">
 <TBODY>
  <TR>
     <TD colspan="2" class="pane-header">
    <SPAN>Console Output - <A href="${rooturl}${build.url}/console">See full console details</A></SPAN>
     </TD>
  </TR>

  <j:forEach var="line" items="${build.getLog(100)}">
  <TR>
     <TD>${line}</TD>
  </TR>
  </j:forEach>
 </TBODY>
</TABLE>
<BR/>
</j:if>


</BODY>
</j:jelly>
于 2013-07-23T06:33:16.757 回答