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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM