GitBucket + Jenkins 自動化建置與 Gmail 通知設定
#
如何設定 GitBucket 程式碼推送(Push)自動觸發 Jenkins 進行 Pipeline 建置(包含程式碼檢查、安全掃描、測試與覆蓋率報告),並在建置完成後自動發送 Gmail 通知。
流程概覽圖
#
- 開發者推送(Push)程式碼至 GitBucket (
master 分支)。
- GitBucket 發送 Webhook 請求(帶有安全 Token)至 Jenkins。
- Jenkins 根據
Jenkinsfile 定義的步驟執行 CI 流程。
- 執行完畢後,Jenkins 透過 Gmail SMTP 發送通知郵件。
好的,沒問題!這裡直接用 Mermaid 語法幫你把這套自動化流程圖畫出來。你在支援 Markdown Mermaid 的編輯器或平台上就可以直接看到圖形:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
graph TD
%% 節點定義
Dev[開發者 Local Dev]
GitBucket[GitBucket 伺服器<br>port 443 / java17]
Nginx[Nginx 反向代理]
Jenkins[Jenkins 伺服器<br>/jenkins 路徑]
CI_Stages{執行 CI 階段}
Gmail[Gmail SMTP<br>smtp.gmail.com]
Inbox[開發者 Gmail 信箱]
%% 流程線
Dev -->|1. git push master| GitBucket
GitBucket -->|2. 發送 Webhook 請求<br>帶上 Access Token & 使用 IP| Nginx
Nginx -->|3. 轉發請求至後端| Jenkins
Jenkins -->|4. 比對成功,觸發 Poll SCM<br>回 GitBucket 抓取 Jenkinsfile| GitBucket
Jenkins -->|5. 依據腳本內容| CI_Stages
subgraph Pipeline 執行項目
CI_Stages -->|Stage 1| S1[./gradlew clean]
CI_Stages -->|Stage 2| S2[./gradlew checkstyleMain]
CI_Stages -->|Stage 3| S3[./gradlew dependencyCheckAnalyze]
CI_Stages -->|Stage 4| S4[./gradlew test jacocoTestReport]
end
S1 -->|不論成功或失敗<br>進入全域 post| PostAction[執行 emailext]
S2 -->|不論成功或失敗| PostAction
S3 -->|不論成功或失敗| PostAction
S4 -->|不論成功或失敗| PostAction
PostAction -->|6. 透過應用程式密碼連線| Gmail
Gmail -->|7. 發送建置報告郵件| Inbox
%% 樣式調整
style Dev fill:#f9f,stroke:#333,stroke-width:2px
style Jenkins fill:#bbf,stroke:#333,stroke-width:2px
style GitBucket fill:#bfb,stroke:#333,stroke-width:2px
style Inbox fill:#fbb,stroke:#333,stroke-width:2px
|
第一部分:專案程式碼與 Jenkins Job 設定
#
為了確保架構的穩定性,捨棄傳統將腳本貼在網頁上的作法,改用 Pipeline script from SCM(基礎設施即程式碼) 形式。
1. 專案端設定(建立 Jenkinsfile)
#
在專案根目錄(與 coins 資料夾同層)建立一個無副檔名的檔案,命名為 Jenkinsfile,並寫入 Pipeline 腳本(含全域 post 寄信邏輯):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
pipeline {
environment {
JAVA_HOME = tool 'java-21'
GRADLE_HOME = tool 'gradle'
PATH = "${env.JAVA_HOME}/bin:${env.GRADLE_HOME}/bin:${env.PATH}"
}
agent any
stages {
stage('clean') {
steps {
dir('coins') {
sh './gradlew clean'
}
}
}
stage('Code Style Check') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
dir('coins') {
sh './gradlew checkstyleMain'
}
}
}
}
stage('OWASP Security Scan') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
dir('coins') {
withCredentials([string(credentialsId: 'NVD-API-KEY', variable: 'NVD_API_KEY')]) {
sh './gradlew dependencyCheckAnalyze'
}
}
}
}
}
stage('Test & Coverage') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
dir('coins') {
sh './gradlew test jacocoTestReport'
}
}
} // 欄位修正:在這裡就先結束 steps 區塊
post { // 欄位修正:post 移到跟 steps 同層級
always {
jacoco execPattern: 'coins/**/build/jacoco/*.exec',
classPattern: 'coins/**/build/classes/java/main'
}
}
}
}
post {
always{
mail to: [EMAIL_ADDRESS]',
subject: "Jenkins 建置報告: ${env.JOB_NAME} - #${env.BUILD_NUMBER} - ${currentBuild.currentResult}",
body: """專案名稱: ${env.JOB_NAME}
建置編號: ${env.BUILD_NUMBER}
建置結果: ${currentBuild.currentResult}
詳細連結: ${env.BUILD_URL}
請點擊上方連結至 Jenkins 查看詳細報告。"""
}
}
}
|
- 動作:將此檔案
commit 並 push 至 GitBucket 的 master 分支。
2. Jenkins Job 基礎組態設定
#
- 進入 Jenkins 點選您的 Job(例如
coins-test),點擊 Configure。
- 勾選 Build Triggers 區塊中的 Poll SCM,Schedule 欄位請保持完全空白。
- 移至 Pipeline 區塊,將 Definition 切換為 Pipeline script from SCM。
- SCM 選擇 Git。
- Repository URL 輸入:
[email protected]:pollo-lab/ims.git。
- Credentials 選擇:
Jenkins-ssh-key。
- Branch Specifier 輸入:
*/master。
- 點擊 Save 儲存。
第二部分:安全憑證與 Webhook 連線設定
#
1. Jenkins 端:發行安全 Token
#
- 依序進入 管理 Jenkins -> Security(鎖頭圖示)。
- 找到 Git plugin notifyCommit access tokens(或 Access tokens 按鈕)。
- 點擊 Add new access token,輸入名稱(如
gitbucket-ims),點擊 Generate。
- 複製畫面上顯示的 Token 密碼,並點擊網頁最下方的 Save。
2. GitBucket 端:配置 Webhook
#
- 進入 GitBucket 的專案儲存庫,依序點選 Settings -> Webhooks -> Add webhook。
- 在 Payload URL 欄位填入結合了路徑與安全 Token 的完整網址:
https://127.0.0.1/jenkins/git/[email protected]:pollo-lab/ims.git&token=【您的Token】
- 觸發事件選擇 Push,完成建立。
第三部分:常見地雷與疑難排解 (Troubleshooting)
#
以下為本架構佈署過程中,於內部網路環境最常遭遇的三大錯誤與對應解法:
問題一:SSL 憑證不被 Java 環境信任
#
- 錯誤訊息:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: ... unable to find valid certification path to requested target
- 原因:GitBucket 運行的 Java 環境不信任 Jenkins 伺服器所使用的自簽憑證或內部 CA。
- 解決方法:
- 在 GitBucket 伺服器上透過 openssl 抓取 Jenkins 的憑證:
1
|
openssl s_client -connect base.home.pollochang.work:443 -showcerts </dev/null | openssl x509 -outform PEM > /root/jenkins.crt
|
- 使用
keytool 將憑證強制匯入該 Java 版本的信任庫(預設密碼為 changeit):
1
|
keytool -importcert -trustcacerts -alias jenkins-server -file /root/jenkins.crt -keystore /usr/local/lib/jvm/java17-latest/lib/security/cacerts -storepass changeit -noprompt
|
- 重新啟動 GitBucket 服務。
問題二:主機名稱與憑證安全網域不符
#
- 錯誤訊息:
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <domain> doesn't match any of the subject alternative names: [*.localhost, localhost]
- 原因:雖然 Java 信任了該憑證,但連線時發現網址(如
base.home.pollochang.work)並不在憑證所登記的允許域名(SAN)清單內。
- 解決方法:
- 方案 A (最推薦):直接將 GitBucket 的 Webhook Payload URL 中的域名替換為憑證內已被允許的 IP 位址(例如
https://127.0.0.1/...)。
- 方案 B:改用非加密的 HTTP 連線進行內部互連(如
http://base.home.pollochang.work:8080/...)。
問題三:連線遭 Jenkins 拒絕 (HTTP 401 Unauthorized)
#
- 錯誤訊息:Webhook 測試回傳狀態碼
401 Unauthorized。
- 原因:新版 Jenkins 安全機制規定,外部系統呼叫
/git/notifyCommit 端點觸發輪詢時,必須通過身分驗證。
- 解決方法:
- 按照【第二部分】的步驟,在 Jenkins 安全設定中核發 Git 外掛專用的 Access Token,並在 GitBucket 的 Webhook 網址後方加上
&token=... 參數。
第四部分:變更驗證流程
#
當上述設定皆完成後,請依循以下步驟進行端到端(End-to-End)測試:
- 首次引導:在 Jenkins 介面中手動點擊一次 Build Now(馬上建置)。這能讓 Jenkins 透過實體執行,在歷史紀錄中記住專案的 Git 網址。
- 自動化測試:在本地端修改程式碼,執行
git commit 並 git push 至 GitBucket 的 master 分支。
- 預期結果:
- GitBucket 的 Webhook 紀錄應顯示傳送成功(HTTP 200 或相關正確回應標頭)。
- Jenkins 的
coins-test 專案會在幾秒內被自動勾起並開始建置。
- 建置完成後,您的 Gmail 將會收到一封包含專案名稱、建置編號與結果的建置報告郵件。