3 Jenkins構建Maven項目


3 Jenkins構建Maven項目

3.1 Jenkins項目構建類型(1)-Jenkins構建的項目類型介紹

Jenkins中自動構建項目的類型有很多,常用的有以下三種:

  • 自由風格軟件項目(FreeStyle Project)

  • Maven項目(Maven Project)

  • 流水線項目(Pipeline Project)

每種類型的構建其實都可以完成一樣的構建過程與結果,只是在操作方式、靈活度等方面有所區別,在實際開發中可以根據自己的需求和習慣來選擇。(PS:個人推薦使用流水線類型,因為靈活度非常高)

3.2 Jenkins項目構建類型(2)-自由風格項目構建

演示創建一個自由風格項目來完成項目的集成過程:

拉取代碼->編譯->打包->部署

3.2.1 拉取代碼

1)創建項目

image-20210520093850397

 

2)配置源碼管理,從gitlab拉取代碼

image-20210520094102826

3.2.2 編譯打包

構建->添加構建步驟->Executor Shell

echo "開始編譯和打包"
mvn clean package
echo "編譯和打包結束"

image-20210520094209521

3.2.3 部署

把項目部署到遠程的Tomcat里面

1)安裝 Deploy to container插件

Jenkins本身無法實現遠程部署到Tomcat的功能,需要安裝Deploy to container插件實現

2)添加Tomcat用戶憑證

image-20210520093733705

3)添加構建后操作

image-20210520093740313

image-20210520093747433

image-20210520094754408

image-20210520094712158

點擊"Build Now",開始構建過程

image-20210521093819881

4)部署成功后,訪問項目

http://192.168.5.5:8080/web_demo-1.0-SNAPSHOT/

image-20210521093849756

3.2.4 演示改動代碼后的持續集成

1)IDEA中源碼修改並提交到gitlab

image-20210522143602240

image-20210522143618678

image-20210522143656006

2)在Jenkins中項目重新構建

image-20210521094637157

3)訪問Tomcat

http://192.168.5.5:8080/web_demo-1.0-SNAPSHOT/

image-20210521094759411

3.3 Jenkins項目構建類型(3)-Maven項目構建

1)安裝Maven Integration插件

Maven Integration

image-20210521094906025

2)創建Maven項目

image-20210521094902810

3)配置項目

拉取代碼和遠程部署的過程和自由風格項目一樣,只是"構建"部分不同

image-20210521094859305

image-20210521111100231

3.4 Jenkins項目構建類型(4)-Pipeline流水線項目構建

3.4.1 Pipeline簡介

1)概念 Pipeline,簡單來說,就是一套運行在 Jenkins 上的工作流框架,將原來獨立運行於單個或者多個節點的任務連接起來,實現單個任務難以完成的復雜流程編排和可視化的工作。

2)使用Pipeline有以下好處(來自翻譯自官方文檔):

代碼:Pipeline以代碼的形式實現,通常被檢入源代碼控制,使團隊能夠編輯,審查和迭代其傳送流程。 持久:無論是計划內的還是計划外的服務器重啟,Pipeline都是可恢復的。 可停止:Pipeline可接收交互式輸入,以確定是否繼續執行Pipeline。 多功能:Pipeline支持現實世界中復雜的持續交付要求。它支持fork/join、循環執行,並行執行任務的功能。 可擴展:Pipeline插件支持其DSL的自定義擴展 ,以及與其他插件集成的多個選項。

3)如何創建 Jenkins Pipeline

  • Pipeline 腳本是由 Groovy 語言實現的,但是我們沒必要單獨去學習 Groovy

  • Pipeline 支持兩種語法:Declarative(聲明式)和 Scripted Pipeline(腳本式)語法

  • Pipeline 也有兩種創建方法:可以直接在 Jenkins 的 Web UI 界面中輸入腳本;也可以通過創建一個 Jenkinsfile 腳本文件放入項目源碼庫中(一般我們都推薦在 Jenkins 中直接從源代碼控制(SCM)中直接載入 Jenkinsfile Pipeline 這種方法)。

3.4.2 安裝Pipeline插件

Manage Jenkins->Manage Plugins->可選插件

pipeline

image-20210521095141759

安裝插件后,創建項目的時候多了“流水線”類型

image-20210521095204419

3.4.3 Pipeline語法快速入門

1)Declarative聲明式-Pipeline

創建項目

image-20210521095243833

流水線->選擇HelloWorld模板

image-20210521095258158

image-20210521095939930

生成內容如下:

pipeline {
  agent any

  stages {
      stage('Hello') {
          steps {
               echo 'Hello World'
          }
      }
  }
}

stages:代表整個流水線的所有執行階段。通常stages只有1個,里面包含多個stage

stage:代表流水線中的某個階段,可能出現n個。一般分為拉取代碼,編譯構建,部署等階段。

steps:代表一個階段內需要執行的邏輯。steps里面是shell腳本,git拉取代碼,ssh遠程發布等任意內容。

編寫一個簡單聲明式Pipeline:

pipeline {
agent any

stages {
stage('拉取代碼') {
steps {
echo '拉取代碼'
}
}
stage('編譯構建') {
steps {
echo '編譯構建'
}
}
stage('項目部署') {
steps {
echo '項目部署'
}
}
}
}

點擊構建,可以看到整個構建過程

image-20210521100215009

2)Scripted Pipeline腳本式-Pipeline

創建項目

image-20210521100236205

本次選擇"Scripted Pipeline"

image-20210521100251940

node {
def mvnHome
stage('Preparation') { // for display purposes

}
stage('Build') {

}
stage('Results') {
}
}
  • Node:節點,一個 Node 就是一個 Jenkins 節點,Master 或者 Agent,是執行 Step 的具體運行環境,后續講到Jenkins的Master-Slave架構的時候用到。

  • Stage:階段,一個 Pipeline 可以划分為若干個 Stage,每個 Stage 代表一組操作,比如:Build、Test、Deploy,Stage 是一個邏輯分組的概念。

  • Step:步驟,Step 是最基本的操作單元,可以是打印一句話,也可以是構建一個 Docker 鏡像,由各類 Jenkins 插件提供,比如命令:sh ‘make’,就相當於我們平時 shell 終端中執行 make 命令一樣。

編寫一個簡單的腳本式Pipeline

node {
def mvnHome
stage('拉取代碼') { // for display purposes
echo '拉取代碼'
}
stage('編譯構建') {
echo '編譯構建'
}
stage('項目部署') {
echo '項目部署'
}
}

構建結果和聲明式一樣!

3.4.4 拉取代碼

image-20210521131921959

image-20210521132041016

pipeline {
agent any

stages {
stage('拉取代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '290fa226-a185-4097-aff6-77d2aab6dcf4', url: 'git@192.168.5.4:root/web_demo.git']]])
}
}
}
}

image-20210521132244568

image-20210521132223391

3.4.5 編譯打包

image-20210521132434955

pipeline {
agent any

stages {
stage('拉取代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '290fa226-a185-4097-aff6-77d2aab6dcf4', url: 'git@192.168.5.4:root/web_demo.git']]])
}
}
stage('編譯構建') {
steps {
sh 'mvn clean package'
}
}
}
}

image-20210521132526753

image-20210521133504378

3.4.6 部署

image-20210521133732206

pipeline {
agent any

stages {
stage('拉取代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '290fa226-a185-4097-aff6-77d2aab6dcf4', url: 'git@192.168.5.4:root/web_demo.git']]])
}
}
stage('編譯構建') {
steps {
sh label: '', script: 'mvn clean package'
}
}
stage('項目部署') {
steps {
deploy adapters: [tomcat8(credentialsId: '87f9d1b2-7b05-4a7f-8647-ffb54c042645', path: '', url: 'http://192.168.5.5:8080/')], contextPath: null, war: 'target/*.war'
}
}
}
}

image-20210521133843624

image-20210521133829164

3.4.7 Pipeline Script from SCM

之前都是直接在Jenkins的UI界面編寫Pipeline代碼,這樣不方便腳本維護,建議把Pipeline腳本放在項目中(一起進行版本控制)

1)在項目根目錄建立Jenkinsfile文件,把內容復制到該文件中

image-20210521140011645

把Jenkinsfile上傳到Gitlab

2)在項目中引用該文件

image-20210521140143821

image-20210521140229448

3.5 Jenkins項目構建細節(1)-常用的構建觸發器

Jenkins內置4種構建觸發器:

  • 觸發遠程構建

  • 其他工程構建后觸發(Build after other projects are build)

  • 定時構建(Build periodically)

  • 輪詢SCM(Poll SCM)

3.5.1 觸發遠程構建

image-20210521140942636

觸發構建url:http://192.168.5.3:808/job/test03_pipeline01/build?token=1118

image-20210521141214904

3.5.2 其他工程構建后觸發

1)創建pre_job流水線工程

image-20210521141547969

2)配置需要觸發的工程

image-20210521141619954

3.5.3 定時構建

image-20210521142113665

定時字符串從左往右分別為: 分 時 日 月 周

一些定時表達式的例子:

每30分鍾構建一次:H代表形參 H/30 * * * * 10:02 10:32
每2個小時構建一次: H H/2 * * *
每天的8點,12點,22點,一天構建3次: (多個時間點中間用逗號隔開) 0 8,12,22 * * *
每天中午12點定時構建一次 H 12 * * *
每天下午18點定時構建一次 H 18 * * *
在每個小時的前半個小時內的每10分鍾 H(0-29)/10 * * * *
每兩小時一次,每個工作日上午9點到下午5點(也許是上午10:38,下午12:38,下午2:38,下午
4:38) H H(9-16)/2 * * 1-5

3.5.4 輪詢SCM

輪詢SCM,是指定時掃描本地代碼倉庫的代碼是否有變更,如果代碼有變更就觸發項目構建。

image-20210521142151036

注意:這次構建觸發器,Jenkins會定時掃描本地整個項目的代碼,增大系統的開銷,不建議使用。

3.6 Jenkins項目構建細節(2)-Git hook自動觸發構建

剛才演示到在Jenkins的內置構建觸發器中,輪詢SCM可以實現Gitlab代碼更新,項目自動構建,但是該方案的性能不佳。那有沒有更好的方案呢? 有的。就是利用Gitlab的webhook實現代碼push到倉庫,立即觸發項目自動構建。

image-20210521142241715

3.6.1 安裝Gitlab Hook插件

需要安裝兩個插件:

Gitlab Hook

GitLab

 

image-20210521142308707

image-20210521142312723

3.6.2 Jenkins設置自動構建

image-20210521143322371

等會需要把生成的webhook URL配置到Gitlab中。

3.6.3 Gitlab配置webhook

1)開啟webhook功能

使用root賬戶登錄到后台,點擊Admin Area -> Settings -> Network

勾選"Allow requests to the local network from web hooks and services"

image-20210521142422907

2)在項目添加webhook

點擊項目->Settings->Integrations

image-20210521143638464

注意:在Jenkins控制台完成以下設置,否則會報錯

Manage Jenkins->Configure System

image-20210521142452160

3.7 Jenkins項目構建細節(3)-Jenkins的參數化構建

有時在項目構建的過程中,我們需要根據用戶的輸入動態傳入一些參數,從而影響整個構建結果,這時可以使用參數化構建。

Jenkins支持非常豐富的參數類型

image-20210521144115652

接下來演示通過輸入gitlab項目的分支名稱來部署不同分支項目。

3.7.1 項目創建分支,並推送到Gitlab上

image-20210521150932493

image-20210521151022211

image-20210521151044576

新建分支:v1,代碼稍微改動下,然后提交到gitlab上。 這時看到gitlab上有一個兩個分支:master和v1

image-20210521151157612

3.7.2 在Jenkins添加字符串類型參數

image-20210521151231650

image-20210521151239502

3.7.3 改動pipeline流水線代碼

image-20210521151335535

3.7.4 點擊Build with Parameters

image-20210521151508455

image-20210521151732631

輸入分支名稱,構建即可!構建完成后訪問Tomcat查看結果

image-20210521151800253

image-20210521151713193

3.8 Jenkins項目構建細節(4)-配置郵箱服務器發送構建結果

3.8.1 安裝Email Extension插件

Email Extension Template

image-20210521151936616

 

3.8.2 Jenkins設置郵箱相關參數

Manage Jenkins->Configure System

image-20210521152434150

設置郵件參數

image-20210521165656186

設置Jenkins默認郵箱信息

image-20210521165619568

測試郵箱是否可以發送成功

image-20210521165747164

image-20210521165841109

3.8.3 准備郵件內容

在項目根目錄編寫email.html,並把文件推送到Gitlab,內容如下:

image-20210521171348299

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次構建日志</title>
</head>

<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
offset="0">
<table width="95%" cellpadding="0" cellspacing="0"
style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
<tr>
<td>(本郵件是程序自動下發的,請勿回復!)</td>
</tr>
<tr>
<td><h2>
<font color="#0000FF">構建結果 - ${BUILD_STATUS}</font>
</h2></td>
</tr>
<tr>
<td><br />
<b><font color="#0B610B">構建信息</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>項目名稱&nbsp;:&nbsp;${PROJECT_NAME}</li>
<li>構建編號&nbsp;:&nbsp;第${BUILD_NUMBER}次構建</li>
<li>觸發原因:&nbsp;${CAUSE}</li>
<li>構建日志:&nbsp;<a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>構建&nbsp;&nbsp;Url&nbsp;:&nbsp;<a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目錄&nbsp;:&nbsp;<a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
<li>項目&nbsp;&nbsp;Url&nbsp;:&nbsp;<a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>
</td>
</tr>
<tr>
<td><b><font color="#0B610B">Changes Since Last
Successful Build:</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>歷史變更記錄 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
</ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat="&nbsp;&nbsp;&nbsp;&nbsp;%p"}
</td>
</tr>
<tr>
<td><b>Failed Test Results</b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td><pre
style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre>
<br /></td>
</tr>
<tr>
<td><b><font color="#0B610B">構建日志 (最后 100行):</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td><textarea cols="80" rows="30" readonly="readonly"
style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea>
</td>
</tr>
</table>
</body>
</html>

3.8.4 編寫Jenkinsfile添加構建后發送郵件

image-20210521172146111

pipeline {
agent any

stages {
stage('拉取代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '290fa226-a185-4097-aff6-77d2aab6dcf4', url: 'git@192.168.5.4:root/web_demo.git']]])
}
}
stage('編譯構建') {
steps {
sh 'mvn clean package'
}
}
stage('項目部署') {
steps {
deploy adapters: [tomcat8(credentialsId: '87f9d1b2-7b05-4a7f-8647-ffb54c042645', path: '', url: 'http://192.168.5.5:8080/')], contextPath: null, war: 'target/*.war'
}
}
}
post {
always {
emailext(
subject: '構建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
body: '${FILE,path="email.html"}',
to: 'xxx@qq.com'
)
}
}
}

 

 

測試郵件發送情況

image-20210521173923642

郵件發送格式存在問題,可以修改以下字段

image-20210521173820480

PS:郵件相關全局參數參考列表:

image-20210521170356675

3.9 Jenkins+SonarQube代碼審查(1) - 安裝SonarQube

3.9.1 SonaQube簡介

image-20210522104519611

SonarQube是一個用於管理代碼質量的開放平台,可以快速的定位代碼中潛在的或者明顯的錯誤。目前 支持java,C#,C/C++,Python,PL/SQL,Cobol,JavaScrip,Groovy等二十幾種編程語言的代碼質量管理與檢 測。

官網:https://www.sonarqube.org/

3.9.2 環境配置說明

名稱 IP地址 安裝軟件
持續基礎服務器 192.168.5.3 ... SonarQube6.7.4,Mysql5.7
代碼托管服務器 192.168.5.4 gitlab-ce-12.4.2
應用測試服務器 192.168.5.5 JDK1.8,Tomcat8.5

3.9.3 安裝SonarQube

1)安裝MySQL

詳細請參考文檔:Linux-Mysql安裝文檔

2)安裝SonarQube 在MySQL創建sonar數據庫

create database sonar;

image-20210522105513523

下載sonar壓縮包:

由於SonarQube在7.9版本后開始就不再支持MySQL連接

個人收集:

wget https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/install-pkg/sonarqube-6.7.4.zip

解壓sonar,並設置權限

yum install unzip
# 解壓
cd /root &&unzip sonarqube-6.7.4.zip
mv sonarqube-6.7.4 /usr/local/sonar
useradd sonar && chown -R sonar. /usr/local/sonar

修改sonar配置文件

vim /usr/local/sonar/conf/sonar.properties
sonar.jdbc.username=root 
sonar.jdbc.password=Root@123

sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

image-20210522131802923

注意:sonar默認監聽9000端口,如果9000端口被占用,需要更改。

image-20210522131816807

啟動sonar

su - sonar 
su sonar ./bin/linux-x86-64/sonar.sh start 啟動
su sonar ./bin/linux-x86-64/sonar.sh status 查看狀態
su sonar ./bin/linux-x86-64/sonar.sh stop 停止
tail -f logs/sonar.logs 查看日志

訪問sonar

http://192.168.5.3:9000

image-20210522131917522

默認賬戶:admin/admin

image-20210522132102554

image-20210522132114196

6c4dd14a866779edf26f4cc741f5fe8ec1bb9379

3.10 Jenkins+SonarQube代碼審查(2) - 實現代碼審查

image-20210522132149704

3.10.1 安裝SonarQube Scanner插件

SonarQube Scanner

image-20210522132159167

3.10.2 添加SonarQube憑證

image-20210522132433101

 

3.10.3 Jenkins進行SonarQube配置

Manage Jenkins->Configure System->SonarQube servers

image-20210522133708596

image-20210522133744486

Manage Jenkins->Global Tool Configuration

image-20210522133810440

image-20210522154141510

3.10.4 SonaQube關閉審查結果上傳到SCM功能

image-20210522133901859

3.10.5 在項目添加SonaQube代碼審查(非流水線項目)

添加構建步驟:

# must be unique in a given SonarQube instance
sonar.projectKey=tset-01
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tset-01
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**

sonar.java.source=1.8
sonar.java.target=1.8

# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8

image-20210522134902346

image-20210522134752132

image-20210522134825319

3.10.6 在項目添加SonaQube代碼審查(流水線項目)

image-20210522140350019

# must be unique in a given SonarQube instance
sonar.projectKey=tset-02
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tset-02
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**

sonar.java.source=1.8
sonar.java.target=1.8

# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8

2)修改Jenkinsfile,加入SonarQube代碼審查階段

pipeline {
agent any

stages {
stage('拉取代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '290fa226-a185-4097-aff6-77d2aab6dcf4', url: 'git@192.168.5.4:root/web_demo.git']]])
}
}
stage('編譯構建') {
steps {
sh 'mvn clean package'
}
}
stage('SonarQube代碼審查') {
steps{
script {
// 引入sonarqubescanner工具
scannerHome = tool 'sonarqube-scanner'
}
//引入sonarqube的服務器環境
withSonarQubeEnv('sonarqube') {
sh "${scannerHome}/bin/sonar-scanner"
}
}
}
stage('項目部署') {
steps {
deploy adapters: [tomcat8(credentialsId: '87f9d1b2-7b05-4a7f-8647-ffb54c042645', path: '', url: 'http://192.168.5.5:8080/')], contextPath: null, war: 'target/*.war'
}
}
}
post {
always {
emailext(
subject: '構建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
body: '${FILE,path="email.html"}',
to: 'xxx@qq.com'
)
}
}
}

3)到SonarQube的UI界面查看審查結果

 


免責聲明!

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



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