zoukankan      html  css  js  c++  java
  • jenkins 邮件配置一

    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 

    这个错误是我在使用邮件模板时,报的错! 
    我的步骤如下: 
    我在参考官方 :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"}

    然后构建时,就报错! 
    这一块也困扰我很久!直到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吧)

    1.  
      <!DOCTYPE html>
    2.  
      <html>
    3.  
      <head>
    4.  
      <meta charset="UTF-8">
    5.  
      <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
    6.  
      </head>
    7.  
       
    8.  
      <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
    9.  
      offset="0">
    10.  
      <table width="95%" cellpadding="0" cellspacing="0"
    11.  
      style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
    12.  
      <tr>
    13.  
      <td>
    14.  
      <h2>
    15.  
      <font>来自Mr.Jenkins的邮件通知</font>
    16.  
      </h2>
    17.  
      </td>
    18.  
      </tr>
    19.  
      <tr>
    20.  
      <td>
    21.  
      <br />
    22.  
      <b><font color="#0B610B">构建信息</font></b>
    23.  
      <hr size="2" width="100%" align="center" />
    24.  
      </td>
    25.  
      </tr>
    26.  
      <tr>
    27.  
      <td>
    28.  
      <ul>
    29.  
      <li>项目名称 : ${PROJECT_NAME}</li>
    30.  
      <li>触发原因 :${CAUSE}</li>
    31.  
      <li>构建日志 : <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
    32.  
      <li>单元测试报告 :<a href="${BUILD_URL}testReport/">${BUILD_URL}testReport/</a></li>
    33.  
      <li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
    34.  
       
    35.  
      </ul>
    36.  
      </td>
    37.  
      </tr>
    38.  
      <tr>
    39.  
      <td><b><font color="#0B610B">构建日志:</font></b>
    40.  
      <hr size="2" width="100%" align="center" /></td>
    41.  
      </tr>
    42.  
      <tr>
    43.  
      <td><textarea cols="80" rows="30" readonly="readonly"
    44.  
      style="font-family: Courier New">${BUILD_LOG}</textarea>
    45.  
      </td>
    46.  
      </tr>
    47.  
      </table>
    48.  
      </body>
    49.  
      </html>

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

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

    可以理解成:

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

    方法二 使用模板

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

    这是官方给的groovy的模板:

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

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

    1.  
      //我的路径: /home/jenkins/dataspace/email-templates
    2.  
      [root@master01 email-templates] vim testy.template
    3.  
      // 再把官方给的模板复制粘贴进去,代码如下:
    1.  
      <STYLE>
    2.  
      BODY, TABLE, TD, TH, P {
    3.  
      font-family:Verdana,Helvetica,sans serif;
    4.  
      font-size:11px;
    5.  
      color:black;
    6.  
      }
    7.  
      h1 { color:black; }
    8.  
      h2 { color:black; }
    9.  
      h3 { color:black; }
    10.  
      TD.bg1 { color:white; background-color:#0000C0; font-size:120% }
    11.  
      TD.bg2 { color:white; background-color:#4040FF; font-size:110% }
    12.  
      TD.bg3 { color:white; background-color:#8080FF; }
    13.  
      TD.test_passed { color:blue; }
    14.  
      TD.test_failed { color:red; }
    15.  
      TD.console { font-family:Courier New; }
    16.  
      </STYLE>
    17.  
      <BODY>
    18.  
       
    19.  
      <TABLE>
    20.  
      <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' %>" />
    21.  
      </TD><TD valign="center"><B style="font-size: 200%;">BUILD ${build.result ?: 'SUCCESSFUL'}</B></TD></TR>
    22.  
      <TR><TD>URL</TD><TD><A href="${rooturl}${build.url}">${rooturl}${build.url}</A></TD></TR>
    23.  
      <TR><TD>Project:</TD><TD>${project.name}</TD></TR>
    24.  
      <TR><TD>Date:</TD><TD>${it.timestampString}</TD></TR>
    25.  
      <TR><TD>Duration:</TD><TD>${build.durationString}</TD></TR>
    26.  
      <TR><TD>Cause:</TD><TD><% build.causes.each() { cause -> %> ${cause.shortDescription} <% } %></TD></TR>
    27.  
      </TABLE>
    28.  
      <BR/>
    29.  
       
    30.  
      <!-- CHANGE SET -->
    31.  
      <% def changeSets = build.changeSets
    32.  
      if(changeSets != null) {
    33.  
      def hadChanges = false %>
    34.  
      <TABLE width="100%">
    35.  
      <TR><TD class="bg1" colspan="2"><B>CHANGES</B></TD></TR>
    36.  
       
    37.  
      <% changeSets.each() { cs_list ->
    38.  
      cs_list.each() { cs ->
    39.  
      hadChanges = true %>
    40.  
      <TR>
    41.  
      <TD colspan="2" class="bg2">  Revision <B><%= cs.metaClass.hasProperty('commitId') ? cs.commitId : cs.metaClass.hasProperty('revision') ? cs.revision :
    42.  
      cs.metaClass.hasProperty('changeNumber') ? cs.changeNumber : "" %></B> by
    43.  
      <B><%= cs.author %>: </B>
    44.  
      <B>(${cs.msgAnnotated})</B>
    45.  
      </TD>
    46.  
      </TR>
    47.  
      <% cs.affectedFiles.each() { p -> %>
    48.  
      <TR>
    49.  
      <TD width="10%">  ${p.editType.name}</TD>
    50.  
      <TD>${p.path}</TD>
    51.  
      </TR>
    52.  
      <% }
    53.  
      }
    54.  
      }
    55.  
       
    56.  
      if(!hadChanges) { %>
    57.  
      <TR><TD colspan="2">No Changes</TD></TR>
    58.  
      <% } %>
    59.  
      </TABLE>
    60.  
      <BR/>
    61.  
      <% } %>
    62.  
       
    63.  
      <!-- ARTIFACTS -->
    64.  
      <% def artifacts = build.artifacts
    65.  
      if(artifacts != null && artifacts.size() > 0) { %>
    66.  
      <TABLE width="100%">
    67.  
      <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
    68.  
      <TR>
    69.  
      <TD>
    70.  
      <% artifacts.each() { f -> %>
    71.  
      <li>
    72.  
      <a href="${rooturl}${build.url}artifact/${f}">${f}</a>
    73.  
      </li>
    74.  
      <% } %>
    75.  
      </TD>
    76.  
      </TR>
    77.  
      </TABLE>
    78.  
      <BR/>
    79.  
      <% } %>
    80.  
       
    81.  
      <!-- MAVEN ARTIFACTS -->
    82.  
      <%
    83.  
      try {
    84.  
      def mbuilds = build.moduleBuilds
    85.  
      if(mbuilds != null) { %>
    86.  
      <TABLE width="100%">
    87.  
      <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
    88.  
      <%
    89.  
      try {
    90.  
      mbuilds.each() { m -> %>
    91.  
      <TR><TD class="bg2"><B>${m.key.displayName}</B></TD></TR>
    92.  
      <% m.value.each() { mvnbld ->
    93.  
      def artifactz = mvnbld.artifacts
    94.  
      if(artifactz != null && artifactz.size() > 0) { %>
    95.  
      <TR>
    96.  
      <TD>
    97.  
      <% artifactz.each() { f -> %>
    98.  
      <li>
    99.  
      <a href="${rooturl}${mvnbld.url}artifact/${f}">${f}</a>
    100.  
      </li>
    101.  
      <% } %>
    102.  
      </TD>
    103.  
      </TR>
    104.  
      <% }
    105.  
      }
    106.  
      }
    107.  
      } catch(e) {
    108.  
      // we don't do anything
    109.  
      } %>
    110.  
      </TABLE>
    111.  
      <BR/>
    112.  
      <% }
    113.  
       
    114.  
      }catch(e) {
    115.  
      // we don't do anything
    116.  
      }
    117.  
      %>
    118.  
       
    119.  
      <!-- JUnit TEMPLATE -->
    120.  
       
    121.  
      <% def junitResultList = it.JUnitTestResult
    122.  
      try {
    123.  
      def cucumberTestResultAction = it.getAction("org.jenkinsci.plugins.cucumber.jsontestsupport.CucumberTestResultAction")
    124.  
      junitResultList.add(cucumberTestResultAction.getResult())
    125.  
      } catch(e) {
    126.  
      //cucumberTestResultAction not exist in this build
    127.  
      }
    128.  
      if (junitResultList.size() > 0) { %>
    129.  
      <TABLE width="100%">
    130.  
      <TR><TD class="bg1" colspan="2"><B>${junitResultList.first().displayName}</B></TD></TR>
    131.  
      <% junitResultList.each{
    132.  
      junitResult -> %>
    133.  
      <% junitResult.getChildren().each { packageResult -> %>
    134.  
      <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>
    135.  
      <% packageResult.getFailedTests().each{ failed_test -> %>
    136.  
      <TR bgcolor="white"><TD class="test_failed" colspan="2"><B><li>Failed: ${failed_test.getFullName()} </li></B></TD></TR>
    137.  
      <% }
    138.  
      }
    139.  
      } %>
    140.  
      </TABLE>
    141.  
      <BR/>
    142.  
      <%
    143.  
      } %>
    144.  
       
    145.  
      <!-- CONSOLE OUTPUT -->
    146.  
      <% if(build.result==hudson.model.Result.FAILURE) { %>
    147.  
      <TABLE width="100%" cellpadding="0" cellspacing="0">
    148.  
      <TR><TD class="bg1"><B>CONSOLE OUTPUT</B></TD></TR>
    149.  
      <% build.getLog(100).each() { line -> %>
    150.  
      <TR><TD class="console">${org.apache.commons.lang.StringEscapeUtils.escapeHtml(line)}</TD></TR>
    151.  
      <% } %>
    152.  
      </TABLE>
    153.  
      <BR/>
    154.  
      <% } %>
    155.  
       
    156.  
      </BODY>

    之后把Default Content这一栏改为:

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

    就可以了!

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

    这里写图片描述

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

    参考地址:

    Email-ext plugin

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

    https://stackoverflow.com/questions/424295/experience-with-hudson-building-matrix-project

    https://stackoverflow.com/questions/37144078/jenkins-email-ext-plugin-thinks-i-have-no-recipients-configured

  • 相关阅读:
    数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号
    基于深度学习方法的dota2游戏数据分析与胜率预测(python3.6+keras框架实现)
    基于CBOW网络手动实现面向中文语料的word2vec
    《Machine Learning Yearing》读书笔记
    使用神经网络预测航班起飞准点率
    使用LSTM-RNN建立股票预测模型
    基于selenium+phantomJS的动态网站全站爬取
    TensorFlow保存、加载模型参数 | 原理描述及踩坑经验总结
    学习笔记--python中使用多进程、多线程加速文本预处理
    通过外汇对冲手段稳定获利的可行性验证
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/10037819.html
Copyright © 2011-2022 走看看