jenkins pipline中使用Email-ext插件

首先安装 Email-ext plugin插件
在jenkins中配置Jenkins->Manage Jenkins->Configure System
jenkins pipline中使用Email-ext插件_第1张图片
由于测试脚本基于java语言,所以需要Junit插件来发布测试结果,生成数据。在Jenkins->Manage Jenkins->Manage Plugins中安装junit插件
Email-ext插件可以用groovy脚本来自定义邮件。功能很强大,并且作者已经提供了一些模板Templates,然后就可以开始你的构建了。
Jenkins file:

pipeline{
	agent any
	tools {
        maven 'M 3'
    }
	stages{
		stage("checkout code"){
			steps {	
			    script{
					//pull your code
			}}
		}
		stage("run test case"){
			steps {	
			    script{
					//withMaven(maven: 'M 3') {
					//			bat 'mvn test'
					//		}
					//bat "cd C:\\Users\\liul5\\Desktop\\test\\project"
					bat "mvn test"
			}}
		}

	}
	post('Generate report') { 
		always {
			script{
                cucumber fileIncludePattern: '**/cucumber-default-reports/*.json', sortingMethod: 'ALPHABETICAL'
                
                junit '**/cucumber-default-reports/*.xml' //必须有这一步,否则没有数据                  
                emailext subject: "Automation Result5: Job '${env.JOB_NAME} - ${env.BUILD_NUMBER}'",
                   body:'''${SCRIPT,template="groovy-html-larry-refactor.template"}''',
                    to:'$DEFAULT_RECIPIENTS'
                
				emailext subject: "Automation Result6: Job '${env.JOB_NAME} - ${env.BUILD_NUMBER}'",
                   body:''' ${SCRIPT,template="groovy-html-refactor.template"}''',
                    to:'$DEFAULT_RECIPIENTS'

                emailext subject: "Automation Result: Job '${env.JOB_NAME} - ${env.BUILD_NUMBER}'", 
                body:'''  
                      total:${TEST_COUNTS,var="total"},
                      pass:${TEST_COUNTS,var="pass"},
                      fail:${TEST_COUNTS,var="fail"}
                   ''',
                to:'$DEFAULT_RECIPIENTS'
                      
	}}}
}

引用邮件模板在body中使用${SCRIPT,template="groovy-html-refactor.template"},必须用三引号括起来,可以直接使用作者提供的模板,${SCRIPT,template="模板名"}
如果想要自定义模板的话,需要在jenkins的根目录下创建一个email-templates文件夹,将模板放到该目录中(jenkins非msi的安装方式下的Windows的路径:C:\Users\用户名\.jenkins\email-templates,msi安装方式:C:\Program Files (x86)\Jenkins\email-templates)。自定义邮件的语法请查看插件文档document,或者作者的模板Templates。
最终结果图:
jenkins pipline中使用Email-ext插件_第2张图片
jenkins pipline中使用Email-ext插件_第3张图片
模板一:

<STYLE>
  BODY, TABLE, TD, TH, P {
    font-family: Calibri, Verdana, Helvetica, sans serif;
    font-size: 12px;
    color: black;
  }
  .console {
    font-family: Courier New;
  }
  .filesChanged {
    width: 10%;
    padding-left: 10px;
  }
  .section {
    width: 100%;
    border: thin black dotted;
  }
  .td-title-main {
    color: white;
    font-size: 200%;
    padding-left: 5px;
    font-weight: bold;
  }
  .td-title {
    color: white;
    font-size: 120%;
    font-weight: bold;
    padding-left: 5px;
    text-transform: uppercase;
  }
  .td-title-tests {
    font-weight: bold;
    font-size: 120%;
  }
  .td-header-maven-module {
    font-weight: bold;
    font-size: 120%;    
  }
  .td-maven-artifact {
    padding-left: 5px;
  }
  .tr-title {
    background-color: <%= (build.result == null || build.result.toString() == 'SUCCESS') ? '#27AE60' : build.result.toString() == 'FAILURE' ? '#E74C3C' : '#f4e242' %>;
  }
  .test {
    padding-left: 20px;
  }
  .test-fixed {
    color: #27AE60;
  }
  .test-failed {
    color: #E74C3C;
  }
STYLE>
<BODY>
  
  <table class="section">
    <tr class="tr-title">
      <td class="td-title-main" colspan=2>
        BUILD ${build.result ?: 'COMPLETED'}
      td>
    tr>
	<tr>
      <td>Project:td>
      <td>${project.name}td>
    tr>
    <tr>
      <td>Build #${build.number}:td>
      <td><A href="${rooturl}${build.url}">${rooturl}${build.url}A>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>
	<tr>
		<td>Report:td>
		<td><A href="${rooturl}${build.url}cucumber-html-reports/overview-features.html">${rooturl}${build.url}cucumber-html-reports/overview-features.htmlA>td>
	tr>
  table>
  <br/>

  

  <%
  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 class="section">
    <tr class="tr-title">
      <td class="td-title" colspan="5">${junitResultList.first().displayName}td>
    tr>
    <tr>
	    
	    <td class="td-title-tests">Totaltd>
		<td class="td-title-tests">Passedtd>
        <td class="td-title-tests">Failedtd>
        <td class="td-title-tests">Skippedtd>
        <td class="td-title-tests">Success Ratetd>

      tr>
    <% junitResultList.each {
      junitResult -> junitResult.getChildren().each {
        packageResult -> %>
	<%
		def passed = packageResult.getPassCount()
		def failed = packageResult.getFailCount()
		def skipped = packageResult.getSkipCount()
		def total = passed + failed + skipped
		def rate = 0
		if(total != 0){
			def temp = passed / total
			rate = Math.round(temp*10000)/100
			}
		%>
    <tr>
      
	  <td>${total}td>
	  <td>${passed}td>
      <td>${failed}td>
      <td>${skipped}td>
	  <td>${rate}%td>

    tr>
    <% packageResult.getPassedTests().findAll({it.getStatus().toString() == "FIXED";}).each{
        test -> %>
            <tr>
              <td class="test test-fixed" colspan="5">
                ${test.getFullName()} ${test.getStatus()}
              td>
            tr>
        <% } %>
        <% packageResult.getFailedTests().sort({a,b -> a.getAge() <=> b.getAge()}).each{
          failed_test -> %>
    <tr>
      <td class="test test-failed" colspan="5">
        ${failed_test.getFullName()} (Age: ${failed_test.getAge()})
      td>
    tr>
        <% }
      }
    } %>
  table>
  <br/>
  <% } %>
  
  
  
  <%
  def changeSets = build.changeSets
  if(changeSets != null) {
    def hadChanges = false %>
  <table class="section">
    <tr class="tr-title">
      <td class="td-title" colspan="2">CHANGEStd>
    tr>
    <% changeSets.each() { 
      cs_list -> cs_list.each() { 
        cs -> hadChanges = true %>
    <tr>
      <td>
        Revision
        <%= cs.metaClass.hasProperty('commitId') ? cs.commitId : cs.metaClass.hasProperty('revision') ? cs.revision : cs.metaClass.hasProperty('changeNumber') ? cs.changeNumber : "" %>
        by <B><%= cs.author %>B>
      td>
      <td>${cs.msgAnnotated}td>
    tr>
        <% cs.affectedFiles.each() {
          p -> %>
    <tr>
      <td class="filesChanged">${p.editType.name}td>
      <td>${p.path}td>
    tr>
        <% }
      }
    }
    if ( !hadChanges ) { %>
    <tr>
      <td colspan="2">No Changestd>
    tr>
    <% } %>
  table>
  <br/>
  <% } %>


  <% 
  def artifacts = build.artifacts
  if ( artifacts != null && artifacts.size() > 0 ) { %>
  <table class="section">
    <tr class="tr-title">
      <td class="td-title">BUILD ARTIFACTStd>
    tr>
    <% artifacts.each() {
      f -> %>
      <tr>
        <td>
          <a href="${rooturl}${build.url}artifact/${f}">${f}a>
      td>
    tr>
    <% } %>
  table>
  <br/>
  <% } %>


  <%
  try {
    def mbuilds = build.moduleBuilds
    if ( mbuilds != null ) { %>
  <table class="section">
    <tr class="tr-title">
      <td class="td-title">BUILD ARTIFACTStd>
    tr>
      <%
      try {
        mbuilds.each() {
          m -> %>
    <tr>
      <td class="td-header-maven-module">${m.key.displayName}td>
    tr>
          <%
          m.value.each() { 
            mvnbld -> def artifactz = mvnbld.artifacts
            if ( artifactz != null && artifactz.size() > 0) { %>
    <tr>
      <td class="td-maven-artifact">
              <% artifactz.each() {
                f -> %>
        <a href="${rooturl}${mvnbld.url}artifact/${f}">${f}a><br/>
              <% } %>
      td>
    tr>
            <% }
          }
        }
      } catch(e) {
        // we don't do anything
      } %>
  table>
  <br/>
    <% }
  } catch(e) {
    // we don't do anything
  } %>



  <%
  if ( build.result == hudson.model.Result.FAILURE ) { %>
  <table class="section" cellpadding="0" cellspacing="0">
    <tr class="tr-title">
      <td class="td-title">CONSOLE OUTPUTtd>
    tr>
    <% 	build.getLog(100).each() {
      line -> %>
	  <tr>
      <td class="console">${org.apache.commons.lang.StringEscapeUtils.escapeHtml(line)}td>
    tr>
    <% } %>
  table>
  <br/>
  <% } %>
BODY>

模板二:


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Build from Jenkisntitle>
<style type="text/css">
/*base css*/
a{color:#4a72af}
body{background-color:#e4e4e4}
body,p{margin:0;padding:0}
img{display:block}
h1,h2,h3,h4,h5,h6{margin:0 0 .8em 0}
h3{font-size:28px;color:#444!important;font-family:Arial,Helvetica,sans-serif}
h4{font-size:22px;color:#4a72af!important;font-family:Arial,Helvetica,sans-serif}
h5{font-size:18px;color:#444!important;font-family:Arial,Helvetica,sans-serif}
p{font-size:12px;color:#444!important;font-family:"Lucida Grande","Lucida Sans","Lucida Sans Unicode",sans-serif;line-height:1.5}
ol li img{display:inline;height:20px}
/*div styles*/
/*.news{text-align:center;padding-top:15px;}*/
.content{width:720px;background-color:white;margin-left: auto; margin-right: auto ;}
.round_border{margin-bottom:5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;margin-top:0;font-size:14px;padding:6px;border:1px solid #ccc}
.status{background-color:green;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}
.main img{width:38px;margin-right:16px;height:38px}
.main table{font-size:14px;}
.main table th{text-align:left;}
.bottom-message{width:720px;cellpadding:5px;cellspacing:0px}
.bottom-message .message{font-size:13px;color:#aaa;line-height:18px;text-align:center}
.bottom-message .designed{font-size:13px;color:#aaa;line-height:18px;font-style: italic;text-align:right}
img.cartoon {width: 36px; display:inline}
style>
head>
<body>
	
	<div class="content round_border">
		<div class="status">
			<p class="info">The build ${build.result ?: 'completed'}p>
		div>
<%
	import hudson.tasks.junit.TestResultAction
	//import hudson.tasks.test.AbstractTestResultAction
    //AbstractTestResultAction result = build.getAction(AbstractTestResultAction.class)
	TestResultAction testResultAction = build.getAction(TestResultAction.class)  
	def total = " "
	def passed = " "
	def failed = " "
	def skipped = " "
	//if(result != null){
	//	passed = testResultAction.totalCount
	//}
	if(testResultAction){
		total = testResultAction.totalCount
		failed = testResultAction.failCount
		skipped = testResultAction.skipCount
		passed = total - failed - skipped  }
%>
		
		<div class="main round_border">
			<table>
				<tbody>
					<tr>
						<th>Project:th>
						<td>${project.name}td>
					tr>
					<tr>
						<th>Build #${build.number}:th>
						<td><A href="${rooturl}${build.url}">${rooturl}${build.url}A>td>
					tr>
					<tr>
						<th>Date of build:th>
						<td>${it.timestampString}td>
					tr>
					<tr>
						<th>Build duration:th>
						<td>${build.durationString}td>
					tr>
					<tr>
						<th>Build cause:th>
						<td><% build.causes.each() { cause -> %> ${cause.shortDescription} <%  } %>td>						
					tr>
					<tr>
						<th>Test results:th>
						<td>Total: ${total}; Passed:${passed}; Failed:${failed}; Skipped:${skipped}td>
					tr>
					
				tbody>

			table>
			
		div>
		
		<div class="artifacts round_border">
			<b>Report Artifacts:b>
			<ul>
				<li><A href="${rooturl}${build.url}cucumber-html-reports/overview-features.html">${rooturl}${build.url}cucumber-html-reports/overview-features.htmlA>li>
				<li><a href="#">display in new pagea>li>
			ul>
		div>
	div>
	

    <table class="bottom-message" align="center">
		<tr>     
        	<td class="message">You are receiving this email because you
				are relavent with this build<br>
				<p>
					<a href="#">support teama> | <a href="#">QAa>
				p>
			td>
		tr>
	table>
	
body>
html>

参考:
https://wiki.jenkins.io/display/JENKINS/Email-ext+plugin#Email-extplugin-TemplateExamples
http://ikeptwalking.com/using-email-ext-plugin-in-jenkins-pipeline/
https://github.com/jenkinsci/email-ext-plugin/tree/master/src/main/resources/hudson/plugins/emailext/templates
https://gist.github.com/arjabbar/c6f27c64fd18153680f3b52102688c13

你可能感兴趣的:(CI,自动化测试,Jenkins,jenkins,pipline,Email-ext,持续集成,邮件模板)