1. 程式人生 > >物聯網架構成長之路(29)-Jenkins環境搭建

物聯網架構成長之路(29)-Jenkins環境搭建

0. 說明

  哈哈,前面中間插入了一篇Eclipse增加Git外掛,在此之前真的沒有用過GIT。

 

1. 執行Jenkins

  這裡為了方便,還是用Docker方式安裝,由於這個是標準的war報,不對Docker Image進行過多的干預,直接使用官方的Jenkins即可

docker pull jenkins/jenkins:lts

  寫一份docker-compose.yml

1 version: '3'
2 services:
3     jenkins:
4         image: registry.cn-shenzhen.aliyuncs.com/wunaozai/jenkins
5 ports: 6 - 8080:8080 7 - 50000:50000 8 volumes: 9 - /root/workspace/docker/jenkins/data:/var/jenkins_home

 

2. 執行jenkins

  docker-compose啟動容器

  然後訪問宿主機,開始Jenkins安裝和配置,安裝就不多說了,就是下一步下一步。還有之前的部落格也簡單的講解的Jenkins的搭建及使用。安裝外掛就使用官方預設的就可以了,以後有需要還可以在管理介面上增加。 遇到網速不好的,等一下重試一下就可以了。

  Ps: 安裝後,如果重新整理頁面,沒有出現登入介面的,重啟一下jenkins
  進入歡迎介面

 

3. 本地eclipse關聯GitLab倉庫、利用Spring Cloud的Eureka測試自動構建

  物聯網服務註冊中心 global-service-eureka

  GlobalServiceEurekaApplication.java

1 @EnableEurekaServer
2 @SpringBootApplication
3 public class GlobalServiceEurekaApplication {
4     public
static void main(String[] args) { 5 SpringApplication.run(GlobalServiceEurekaApplication.class, args); 6 } 7 }

  application.yml

1 server:
2   port: 8761
3 eureka:
4   client:
5     register-with-eureka: false
6     fetch-registry: false
7     service-url:
8       defaultZone: http://localhost:8761/eureka/

  在GitLab上建立專案

  Eclipse關聯專案到GitLab這一步就不做過多說明

 

4. Jenkins 系統配置

  建立前,先標準外掛安裝,然後我們還需要安裝幾個外掛,在系統管理-外掛管理

  由於我們使用Maven構建Spring Cloud專案,所以需要增加對應的Maven Plugin。我們還使用了GitLab作為程式碼版本管理,因此需要安裝Gitlab Hook Plugin用來使用提交程式碼,觸發自動構建行為。最後還需要把自動構建的結果通過郵件返回給相關人員,這裡又需要Email Extension Plugin。

  這一步需要配置Maven,預設的Jenkins Docker Image是有包含了JDK和GIT,所以我們只需要配置Maven。在系統管理-全域性工具配置 這個介面,只需要配置Maven工具,使用自動安裝。

  配置一下GIT帳號密碼,在Jenkins-憑證-系統-全域性憑證-新增


  配置郵件 在Jenkins-系統管理-系統設定
  配置Jenkins Locaion

  配置E-mail Notification,填入SMTP伺服器、郵件字尾,使用者名稱、密碼。有些伺服器要求SSL、SSL埠有587、465兩種,好像可以不填,JavaMail包會自動選擇。然後就可以測試傳送了。

  由於預設的E-mail Notificaion功能比較弱,因此,需要Email Extension Plugin,對應的配置如下

 

5. Jenkins 任務

  建立一個任務、構建一個Maven專案

  配置原始碼管理Git方式,輸入對應Repo URL、選擇對應的認證憑證,這個在簽名一步已經配置了,這裡選擇就可以。分支就選預設主分支的。

  構建觸發器,採用Git上有人提交時觸發構建

  這裡將 GitLab Webhook URL,複製到GitLab對應的專案上。注意這裡的URL,必須GitLab所在的伺服器要能訪問到。

  下面這個,根據實際構建Goals及Options進行配置,以後可能會通過Maven 直接構建成 Docker Image

  下面這個是配置構建成功後,對應執行的操作,以後可能會通過這個指令碼,構建成docker Image然後上傳到Aliyun Repo

  下面這個是配置自定義構建後,把結果發郵件到指定人,最前面的 Project From 要填前面配置的管理,下面的Recipient List可以寫郵件接收人

  下面的高階,注意下面這個配置才是實際要傳送的郵件內容。我們先預設的傳送一份郵件測試一下。

  一切完成後,點選儲存

 

6. 觸發構建

  可以在GitLab的Web Hooks 點選 Test Hook 按鈕,測試一下是否觸發自動構建。

  看這裡,自動觸發構建、等構建完成,對應的郵箱就會收到構建結果。

 

  可以看到這個郵件已經收到了。結果也是顯示在郵件裡面

 

7. 自定義郵件格式

  初看郵件內容,感覺有點Low,通過下面方式實現自定義郵件內容。在 $JENKINS_HOME 目錄下建立 email-templates 檔案,建立 wunaozai.html 檔案,並寫上以下內容,可以通過以下方式預覽效果。

  wunaozai.html 內容

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

    <TABLE>
    <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' %>" />
    </TD><TD valign="center"><B style="font-size: 200%;">BUILD ${build.result ?: 'SUCCESSFUL'}</B></TD></TR>
    <TR><TD>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:</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>
    </TABLE>
    <BR/>

    <!-- CHANGE SET -->
    <% def changeSets = build.changeSets
            if(changeSets != null) {
            def hadChanges = false %>
            <TABLE width="100%">
                <TR><TD class="bg1" colspan="2"><B>CHANGES</B></TD></TR>
                <%  changeSets.each() { cs_list ->
                cs_list.each() { cs ->
                hadChanges = true %>
                <TR>
                <TD colspan="2" class="bg2">&nbsp;&nbsp;Revision <B><%= cs.metaClass.hasProperty('commitId') ? cs.commitId : cs.metaClass.hasProperty('revision') ? cs.revision :
            cs.metaClass.hasProperty('changeNumber') ? cs.changeNumber : "" %></B> by
        <B><%= cs.author %>: </B>
        <B>(${cs.msgAnnotated})</B>
                </TD>
                </TR>
                <%      cs.affectedFiles.each() { p -> %>
                <TR>
                <TD width="10%">&nbsp;&nbsp;${p.editType.name}</TD>
                <TD>${p.path}</TD>
                </TR>
                <%      }
    }
    }

    if(!hadChanges) { %>
    <TR><TD colspan="2">No Changes</TD></TR>
    <%  } %>
            </TABLE>
            <BR/>
            <% } %>

            <!-- ARTIFACTS -->
            <% def artifacts = build.artifacts
     if(artifacts != null && artifacts.size() > 0) { %>
     <TABLE width="100%">
         <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
         <TR>
         <TD>
             <%      artifacts.each() { f -> %>
             <li>
             <a href="${rooturl}${build.url}artifact/${f}">${f}</a>
             </li>
             <%      } %>
         </TD>
         </TR>
     </TABLE>
     <BR/>
     <% } %>

     <!-- MAVEN ARTIFACTS -->
     <%
       try {
       def mbuilds = build.moduleBuilds
       if(mbuilds != null) { %>
       <TABLE width="100%">
       <TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
       <%
        try {
        mbuilds.each() { m -> %>
        <TR><TD class="bg2"><B>${m.key.displayName}</B></TD></TR>
        <%      m.value.each() { mvnbld ->
        def artifactz = mvnbld.artifacts
        if(artifactz != null && artifactz.size() > 0) { %>
        <TR>
        <TD>
            <%              artifactz.each() { f -> %>
            <li>
            <a href="${rooturl}${mvnbld.url}artifact/${f}">${f}</a>
            </li>
            <%              } %>
        </TD>
        </TR>
        <%          }
      }
      }
      } catch(e) {
      // we don't do anything
      }  %>
       </TABLE>
       <BR/>
       <% }

}catch(e) {
// we don't do anything
      }
      %>

      <!-- JUnit TEMPLATE -->

      <% 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 width="100%">
      <TR><TD class="bg1" colspan="2"><B>${junitResultList.first().displayName}</B></TD></TR>
      <% junitResultList.each{
               junitResult -> %>
               <% junitResult.getChildren().each { packageResult -> %>
               <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>
               <% packageResult.getFailedTests().each{ failed_test -> %>
               <TR bgcolor="white"><TD class="test_failed" colspan="2"><B><li>Failed: ${failed_test.getFullName()} </li></B></TD></TR>
               <% }
                             }
                             } %>
      </TABLE>
      <BR/>
      <%
                             } %>

                             <!-- CONSOLE OUTPUT -->
                             <% if(build.result==hudson.model.Result.FAILURE) { %>
                             <TABLE width="100%" cellpadding="0" cellspacing="0">
                             <TR><TD class="bg1"><B>CONSOLE OUTPUT</B></TD></TR>
                             <%  build.getLog(100).each() { line -> %>
                             <TR><TD class="console">${org.apache.commons.lang.StringEscapeUtils.escapeHtml(line)}</TD></TR>
                             <%  } %>
                             </TABLE>
                             <BR/>
                             <% } %>

</BODY>

  進入到專案任務的配置介面,配置一下自定義郵件格式,如下圖所屬,配置Content部分,最後的Attach build log 也加上

  下圖就是經過自定義後的郵件格式

  哈哈,收到郵件,格式還行,還帶構建日誌。就這樣吧。

 

8. 小結

  終於完了,發現這種截圖式部落格真的特別麻煩,應該是錄視訊好些。哈哈!!這一篇部落格就講到這裡的。還有更多的功能,暫時沒有講到。Jenkins可以做的事情還是很多的。通過寫指令碼,做任意想要做的事情。不過這個就是根據實際專案來實現了。以後有機會用到我再講。

 

參考資料:

  https://blog.csdn.net/u013066244/article/details/78665075
  https://blog.csdn.net/galen2016/article/details/77975965
  https://www.cnblogs.com/gcgc/p/5631385.html
  https://www.cnblogs.com/bigben0123/p/7886092.html
  https://www.cnblogs.com/xiewenming/p/7490828.html

本文地址: https://www.cnblogs.com/wunaozai/p/9997566.html