創建一個基於Maven的Java應用
目錄
本教程將向您展示如何使用Jenkins構建基於Maven的簡單Java應用。
如果您是一名使用Maven的Java開發人員,並且之前並沒有接觸過持續集成/持續部署的概念,或者您可能熟悉這些概念但並不清楚如何使用Jenkins實現這樣的構建,那麼本教程適合您。
這個簡單Java程序(您將從一個GitHub倉庫上獲取它)會輸出字符串“Hello world!”,幷包含一系列單元測試來保證主程序的運行符合預期。測試結果將會被保存爲JUnit
XML報告。
用時: 完成本教程需要20-40分鐘的時間(假如您已經符合下文的先決條件)。確切的用時將取決於您的機器速度,以及您是否已經完成了另一教程中的在Docker中運行Jenkins。
您可以在任何時刻停止本教程並在隨後繼續。
如果您已經做過另一篇教程了,您可以跳過下面的《先決條件》和《在Docker中運行Jenkins》兩節,直接從《派生示例倉庫》開始。(要確保您已經在本地安裝了Git。)如果您需要重啓Jenkins,只需要跟着《Jenkins的重啓和停止》做就可以了,並且之後您還可以從停止的地方繼續。
先決條件
對本教程來說,您需要:
- 一臺macOS、Linux或Windows機器(譯註:Windows家庭版無法運行Docker),它有
- 至少256MB內存,儘管推薦512MB或更高。
- 10GB存儲空間,用於Jenkins和Docker容器及鏡像。
- 需要安裝如下軟件:
- Docker - 關於安裝Docker的信息在安裝Jenkins教程頁的安裝Docker小節。注意: 如果您使用的是Linux,本教程假定您不會使用root用戶執行Docker命令,而是使用一個同樣可以訪問其他本教程涉及的工具的獨立用戶賬戶。
- Git和可選的GitHub Desktop。
在Docker中運行Jenkins
在本教程中,您將使用來自“jenkinsci/blueocean”Docker鏡像的Docker容器來運行Jenkins。
要在Docker中運行Jenkins,請遵循下文對應的對macOS和Linux或Windows系統的講解。
您可以在安裝Jenkins上的Docekr和在Docker中下載及運行Jenkins小節獲取更多信息。
macOS和Linux
- 打開一個終端窗口。
- 使用docker run命令在Docker中以容器的方式運行
jenkinsci/blueocean
鏡像(該命令會在您本機沒有下載該鏡像時自動下載鏡像):
docker run \
--rm \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \ <1>
-v "$HOME":/home \ <2>
jenkinsci/blueocean
<1> 映射容器中的/var/jenkins_home
目錄到名爲jenkins-data
的Docker數據卷。如果該數據卷不存在,docker run
命令會自動幫您創建。
<2> 映射宿主(例如您的本地)機器的$HOME
目錄(通常爲/Users/<用戶名>
目錄)至容器的/home
目錄。
注意: 如果上述命令片段複製粘貼過去無法工作,嘗試複製粘貼下文不包含標註的版本:
docker run \
--rm \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME":/home \
jenkinsci/blueocean
- 根據《安裝嚮導》繼續操作。
Windows
- 打開一個命令提示符窗口。
- 使用docker run命令在Docker中以容器的方式運行
jenkinsci/blueocean
鏡像(該命令會在您本機沒有下載該鏡像時自動下載鏡像):
docker run ^
--rm ^
-u root ^
-p 8080:8080 ^
-v jenkins-data:/var/jenkins_home ^
-v /var/run/docker.sock:/var/run/docker.sock ^
-v "%HOMEPATH%":/home ^
jenkinsci/blueocean
有關這些參數的解釋,請參照上文《macOS和Linux》的內容。
- 根據《安裝嚮導》繼續操作。
訪問Jenkins/Blue Ocean Docker容器
如果您有Docker的使用經驗,並且想要通過終端/命令提示符使用docker exec命令訪問Jenkins/Blue Ocean容器,那麼您可以添加--name jenkins-tutorials
(在上文docker run命令那裏)選項,它會將您的容器命名爲“jenkins-tutorials”。
這意味着您可以通過docker exec
命令(通過另一個終端/命令提示符窗口)訪問Jenkins/Blue Ocean容器,就像這樣:
docker exec -it jenkins-tutorials bash
安裝嚮導
在訪問Jenkins之前,您需要做一些很快的“一次性”步驟。
解鎖Jenkins
當您首次訪問一個新的Jenkins實例時,您需要使用一段自動生成的密碼來將其解鎖。
- 在終端/命令提示符窗口裏出現數行星號後,訪問
http://localhost:8080
並等待解鎖Jenkins頁面出現。
- 回到您的終端/命令提示符窗口,拷貝自動生成的密碼(在數行星號之間)。
- 在解鎖Jenkins頁面粘貼密碼至管理員密碼輸入框並點擊繼續。
自定義Jenkins插件
在解鎖了Jenkins之後,就會出現自定義Jenkins頁面。
在該頁面,點擊安裝推薦的插件。
安裝嚮導會顯示Jenkins的配置進度,以及正在安裝的插件。該環節將持續數分鐘。
創建首個管理員用戶
最後,Jenkins會讓您創建您的首個管理員用戶。
- 當創建第一個管理員用戶頁面出現時,在對應輸入框指定您的詳細信息並點擊保存並完成。
- 當Jenkins已就緒頁面出現時,點擊開始使用Jenkins。
注意:
- 該頁面可能會提示Jenkins幾乎就緒了!,這時點擊重啓。
- 如果頁面在一分鐘後還沒有自動刷新,手動點擊web瀏覽器的刷新按鈕。
- 如果需要的話,使用剛創建的賬戶登錄Jenkins,您已經做好了開始使用Jenkins的所有準備工作~
Jenkins的重啓和停止
在本教程的剩餘部分,您可以通過在之前執行docker run …
命令的終端或命令提示符窗口鍵入Ctrl-C
來停止Jenkins/Blue Ocean Docker容器。
要重啓Jenkins/Blue Ocean Docker容器:
- 根據上文執行同樣的
docker run …
命令。
**注意:**該處理會在鏡像發佈更新時,同時更新jenkinsci/blueocean
Docker鏡像。 - 瀏覽器訪問
http://localhost:8080
。 - 等待登錄界面出現並登錄。
在GitHub上派生並克隆示例倉庫
從GitHub上獲取示例“Hello World!”Java應用,將源碼派生至您個人的GitHub賬戶並在本地克隆該派生。
- 確保您已經註冊了GitHub賬戶。如果沒有的話,就先去GitHub網站註冊一個。
- 將GitHub上的
simple-java-maven-app
派生至您個人GitHub賬戶。如果這一步您需要幫助,請參考GitHub網站上的派生一個倉庫來獲取更多信息。 - 將派生的倉庫克隆到您的本地機器上。要執行這一步,下文給出兩種解決方案(
<your-username>
代表您在操作系統中的用戶名):
- 如果您在機器上安裝了GitHub Desktop應用程序:
- 在GitHub您的派生倉庫,點擊綠色的Clone or Download按鈕,之後點擊Open in Desktop。
- 在GitHub Desktop中,在點擊Clone a Repository對話框的Clone按鈕之前,確保Local Path爲:
- macOS爲
/Users/<your-username>/Documents/GitHub/simple-java-maven-app
- Linux爲
/home/<your-username>/GitHub/simple-java-maven-app
- Windows爲
C:\Users\<your-username>\Documents\GitHub\simple-java-maven-app
- macOS爲
- 否則:
- 打開一個終端/命令提示符並
cd
至如下目錄:- macOS -
/Users/<your-username>/Documents/GitHub/
- Linux -
home/<your-username>/GitHub/
- Windows -
C:\Users\<your-username>\Documents\GitHub\
(不過使用Git bash命令行窗口時是強力反對使用傳統微軟命令提示符的)
- macOS -
- 執行如下命令以繼續/完成您的派生倉庫的克隆:
git clone https://github.com/YOUR-GITHUB-ACCOUNT-NAME/simple-java-maven-app
YOUR-GITHUB-ACCOUNT-NAME
即您在GitHub上的賬戶名。
- 打開一個終端/命令提示符並
在Jenkins中創建管線工程
- 回到Jenkins,可能需要重新登錄,點擊歡迎頁上的create new jobs(新建任務)。
提示:如果看不到該項,點擊左上側New Item。 - 在**Enter an item name(輸入任務名)**輸入框,指定管線項目的名稱(例如
simple-java-maven-app
)。 - 滾動頁面並點擊Pipeline(管線),之後點擊頁面底部的OK按鈕。
- (可選)在新的頁面裏,在**Description(描述)**輸入框裏指定管線的簡單描述(例如“一個入門級管線,用於演示如何使用Jenkins構建基於Maven的簡單Java應用”)。
- 點擊頁面頂部的**Pipeline(管線)標籤頁,滑動頁面至Pipeline(管線)**部分。
- 在**Definition(定義)輸入框,選擇Pipeline script from SCM(來自源碼控制系統的管線腳本)**選項。該選項會引導Jenkins從源碼控制管理系統(SCM),也就是您本地克隆的Git倉庫處獲取管線。
- 在SCM字段項,選擇Git。
- 在**Repository URL(倉庫URL)**字段項,指定上文克隆到本地的倉庫的路徑。
- 點擊**Save(保存)**保存該管線項目。現在您就可以創建
Jenkinsfile
,並簽入本地克隆的Git倉庫內。
使用Jenkinsfile創建初始化管線
現在您就可以創建管線以在Jenkins裏基於Maven自動化構建Java應用了。 管線應該以Jenkinsfile
文件的形式創建,它可以被提交到您本地克隆的Git倉庫(simple-java-maven-app
)裏。
將持續交付管線代碼和視爲應用其他受版控和複查的代碼一樣的一部分是“代碼式管線”的基礎。更多關於管線和Jenkinsfile是什麼的內容位於用戶手冊的管線和使用Jenkinsfile小節。
首先,創建一個初始化管線下載Maven Docker鏡像並將其以容器的形式運行(將會在裏邊構建您的Java應用)。同時給添加一個“Build(構建)”階段以啓動整個流程的編排。
- 使用您擅長的文本編輯器或IDE,在您本地的
simple-java-maven-app
Git倉庫根目錄新建一個名爲Jenkinsfile
的文件。 - 複製如下聲明式管線代碼並貼入
Jenkinsfile
文件(注意刪除尖括號數字標記):
pipeline {
agent {
docker {
image 'maven:3-alpine' <1>
args '-v /root/.m2:/root/.m2' <2>
}
}
stages {
stage('Build') { <3>
steps {
sh 'mvn -B -DskipTests clean package' <4>
}
}
}
}
<1> image
參數(在agent部分的docker
參數裏)會下載maven:3-apline Docker鏡像(如果您本地沒有下載過)並將該鏡像作爲獨立容器。這意味着:
· 您的Jenkins和Maven容器會分別運行在本地Docker裏。
· Jenkins會使用Maven容器作爲agent執行管線項目。然而,該容器是短存活的,它的生命週期僅限您的管線的執行期間。
<2> args
參數在段村擴Maven Docker容器和Docker宿主機文件系統的/root/.m2
(Maven倉庫)文件夾間建立了對等映射。解釋該作用域的細節超出了本教程的範圍。不過,這樣做的主要原因是確保編譯您的Java應用所需要的包依賴(Maven會在管線執行時下載)在Maven容器的生命週期結束後仍然存留。在反覆執行Jenkins管線時,Maven就不需要衝虛下載相同的包了。注意和上文創建的jenkins-data
Docker數據卷不同,Docker宿主機文件系統會在Docker每次重啓時清空。這意味着您將會在Docker每次重啓時丟失已下載的Maven倉庫包。
<3> 定義一個名爲Build
的stage(階段)(指令),會顯示在Jenkins UI上。
<4> 該sh
步驟(位於steps作用域)先清理後構建您的Java應用(不執行測試)。
- 保存
Jenkinsfile
並將其提交到本地Git倉庫。例如,在simple-java-maven-app
目錄下,執行如下命令:
git add .
之後
git commit -m "Add initial Jenkinsfile"
- 返回Jenkins,也許需要再次登錄。點擊左側的**Open Blue Ocean(打開Blue Ocean)**進入Jenkins Blue Ocean界面。
- 在This job has not been run(該任務沒被運行過)消息框處,點擊Run(運行),快速點擊短暫出現在右下方的OPEN(打開)鏈接查看Jenkins對管線的執行。如果您無法點擊OPEN鏈接,點擊主Blue Ocean界面行來訪問本功能。
**注意:**可能需要您等待數分鐘第一次執行才能完畢。在Jenkins對您本地的simple-java-maven-app
進行拷貝後:
· Jenkins在內部對要在agent上運行的項目進行隊列
· 下載Maven Docker鏡像並在Docker裏運行它。
· 在Maven容器裏運行Build
階段(定義在Jenkinsfile
裏)。此時,Maven會下載構建所需依賴包,並最終存放於Jenkins的本地Maven倉庫裏(在Docker宿主機文件系統中)。
Blue Ocean在Jenkins構建成功後變爲綠色。
- 點擊右上角的×返回到Blue Ocean主界面。
給管線添加測試階段
- 返回文本編輯器/IDE並打開
Jenkinsfile
。 - 複製粘貼下文聲明式管線語法代碼至您的
Jenkinsfile
的Build
階段下:
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
故現在文件結果應是:
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v /root/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
stage('Test') { <1>
steps {
sh 'mvn test' <2>
}
post {
always {
junit 'target/surefire-reports/*.xml' <3>
}
}
}
}
}
<1> 定義一個名爲Test
的階段(指令)。
<2> sh
步驟通過執行Maven命令運行單元測試。該命令同時會生成JUnit XML報告,保存於target/surefire-reports
目錄(在Jenkins容器的/var/jenkins_home/workspace/simple-java-maven-app
目錄下)。
<3> junit步驟(由JUnit插件提供)保存JUnit XML報告(由mvn test
命令產生)並將結果暴露給Jenkins接口。在Blue Ocean裏,該結果可以通過管線運行的**Tests(測試)**頁訪問到。post作用域的always
會確保Test
階段執行完畢後不理會階段的結果,總是執行其包含的junit
步驟。
- 保存
Jenkinsfile
並將其提交到本地倉庫。
git stage.
git commit -m "添加 'Test' 步驟"
- 返回Jenkins,訪問Blue Ocean界面。
- 點擊Run,快速點擊OPEN鏈接。
**注意:**您可能發現這次運行Jenkins不在需要下載Maven Docker鏡像了。Jenkins會使用之前下載過的鏡像。同時因爲Docker從上次執行管線以來沒有重啓過,所以在“Build”階段Maven也不需要下載依賴包。也就是說,本次管線的運行應該會快很多。
如果改進版的管線執行成功,Blue Ocean的界面應如下圖所示。注意新增加的“Test”階段。您可以點擊“Build”階段的原型標記訪問在該階段的輸出。
- 點擊×返回Blue Ocean主界面。
給管線添加最終分發階段
- 返回文本編輯器/IDE並確保打開了
Jenkinsfile
。 - 複製粘貼如下聲明式管線語法代碼到
Jenkinsfile
的Test
步驟下:
stage('Deliver') {
steps {
sh './jenkins/scripts/deliver.sh'
}
}
此時文件最終結果應是:
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v /root/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('Deliver') { <1>
steps {
sh './jenkins/scripts/deliver.sh' <2>
}
}
}
}
<1> 定義一個名爲Delivar
的新階段。
<2> sh
步驟執行位於倉庫根目錄下,jenkins/scripts
目錄下的deliver.sh
shell腳本。該腳本的行爲說明請參考腳本內容自身。通常原則上,保持管線代碼(如Jenkinsfile
)儘可能地簡單並將複雜的構建步驟(特別是包含兩步或更多步驟的)放入獨立的shell腳本文件如deliver.sh
文件裏是一個好主意。最終這會使您的管線代碼易於維護,特別是在管線變得越來越複雜的時候。
- 保存
Jenkinsfile
並提交至本地Git倉庫。
git stage .
git commit -m "添加 Deliver' 階段"
- 返回Jenkins,訪問Blue Ocean界面。
- 點擊Run,快速點擊OPEN鏈接。如果修改後的 管線執行成功,其界面應如下:
此處是“Deliver”步驟輸出的樣子,在結尾向您展示了Java應用的執行結果。
- 點擊×返回Blue Ocean主界面,上面以時序倒序展示了您之前的管線執行。
封裝
很好!您剛剛已經使用Jenkins基於Maven構建了一個簡單的Java應用!
您在上面創建的“Build”、“Test”和“Deliver”步驟都是在Jenkins中基於Maven構建使用了更多技術棧的更加複雜的Java應用的基礎。
由於Jenkins是極度可擴展的,它可以通過修改和配置以支持幾乎任意的自動化相關部分。
要了解更多關於Jenkins可以做什麼,參考: