寫在前面的話
個人認為 Pipeline 在 Jenkins 中算是一個優化性功能,它能夠將我們的構建服務的整個過程流程化,這意味着當我們在執行到某一步的時候,可以添加詢問,提示我們是否繼續運行下一步。當然,這個東西並非我們必須的,在沒有 Pipeline 的時候我們依舊能夠很好的完成大部分項目的構建。但是 Pipeline 對於傳統構建肯定是一個很好的補充,而且當你習慣以后會愛不釋手。
關於流水線(Pipline)
Jenkins 從 2.0 開始逐漸從一個 CI 工具轉變成為 CD 工具,Pipeline 在其中扮演着至關重要的角色。配置由界面選擇逐漸腳本化(采用 Groovy 腳本),我們可以將配置連同代碼一起存放在代碼倉庫,實現版本控制。一次編寫,到處運行。
在 Pipeline 中有兩個主要關鍵字需要先簡單的了解,可能有些地方還能見到 Step 關鍵字:
1. Stage:階段,這其實就是我們將任務細分為多個過程。
2. Node:節點,前面提到過,Jenkins 是可以分布式的,Node 標記着具體在 Master 還是 Slave 運行這個構建。
簡單上手
可能我們目前並不知道 Groovy 腳本的語法到底是什么樣子,但是可以結合下面的例子慢慢的進行了解。
1. 新建 Pipeline 任務:

可以發現 Pipeline 的配置非常簡單,簡單到你都找不到哪里拉取代碼,其主要的功能都集中在這個腳本框中:

2. 添加 Hello World:

可以看到,由於我們只有一步,所以在 node 關鍵字下面就只有一個 Step,執行 echo 輸出操作。
值得注意的是,這的 echo 並不是我們 Linux 中的 echo 命令,這個 echo 是 Groovy 的關鍵字,就像 Python 中的 print 一樣。
保存退出!
3. 執行構建,查看輸出:

我們發現和普通構建執行 Shell 輸出感覺差不多,那么我們可以復雜一下步驟!
4. 修改之前的流水線配置,加入步驟:

需要知道的是,這個輸入框賊難用,建議外部寫好粘貼進去:
node { stage("拉取代碼"){ echo 'STEP 1:clone code' } stage("打包代碼"){ echo 'STEP 2:code package' } stage("上線發布"){ echo 'STEP 3:deploy package' } }
保存執行構建:

我們可以看到,本次構建按照我們配置的 Stage 分成了三步,我們甚至能夠看到每一個過程耗時,做到單獨查看該過程的日志。

當然,我們依舊可以去控制台輸出里面查看整個過程的全部日志。但是細分的好處在於出問題我們更好的查找到問題所在。
5. Pipeline 語法說明:
我們知道了如何分步驟,但是卻只直到一個 echo,顯然無法滿足我們的需求。在我們填寫 Pipeline 的地方有告知語法。

在這里,我們可以通過配置,生成我們常用的語法,比如生成 git 拉代碼:

將配置放到我們流水線腳本中,然后配置打包命令:

其實運行 Linux 命令是可以簡寫的,直接:sh '命令' 這樣就行。
由於我們本次 mvn 執行構建其實際是依賴於 JDK 的,而我們本地又有多個版本 JDK,所以還需要指定環境變量:

此時我們的腳本變成:
node { stage("拉取代碼"){ echo 'STEP 1:clone code' git credentialsId: 'xxx', url: 'http://192.168.10.199:8041/xxx.git' } stage("打包代碼"){ echo 'STEP 2:code package' withEnv(['JAVA_HOME=/data/jdk7']) { sh '/data/maven/bin/mvn -e clean package -U -Dmaven.test.skip=true -Ptest' } } stage("上線發布"){ echo 'STEP 3:deploy package' } }
注意上面 git 的地址是你自己生成的地址!

因為我之前沒有配置環境變量,多以可以看到構建報錯,后面添加環境變量以后就不再出現報錯。
當然,withEnv 其實屬性是一個 list,所以我們其實是可以定義多個變量的,可以像下面一樣,並去調用它:
withEnv(['JAVA_HOME=/data/jdk7', 'NAME="hello"']) { echo "${NAME}" echo "${JAVA_HOME}" }
至於其他的一些語法,如 sleep,timeout 等我們也可找到對用的語法生成。如果你實在懶得去深究,那么 sh 已經能夠滿足你大部分需求。
同時,在 Pipline 中依然是支持參數化構建的,意味着我們也可以以變量的形式直接引用。
另外有一個特殊的可以說明一下:input

將生成的加入我們的配置中:
node { stage("拉取代碼"){ echo 'STEP 1:clone code' git credentialsId: 'xxxxx', url: 'http://192.168.10.199:8041/xxxxxx.git' } stage("打包代碼"){ echo 'STEP 2:code package' withEnv(['JAVA_HOME=/data/jdk7']) { sh '/data/maven/bin/mvn -e clean package -U -Dmaven.test.skip=true -Ptest' } input '是否確定上線' } stage("上線發布"){ echo 'STEP 3:deploy package' } }
再度構建:

發現卡在了第二步,我們點擊查看:

點擊以后步驟繼續執行:

GitLab 顯示構建狀態
這其實是一個特殊需求,我們項目在測試階段一般都存在於開發分支,當測試完成以后才會被提交合並到主干分支。這其中就會有一個問題,具有合並的人能夠看到你的代碼,但是它並不知道你的代碼是否能夠正常的構建通過,所以我們希望在 GitLab 上面顯示我們測試構建的狀態。
具體流程:開發提交代碼到 dev 分支 --> 觸發 Jenkins 自動構建 --> 構建結果顯示到 GitLab 的 Merge request 上
1. 創建 Pipline 任務:

2. 將 GitLab 上我們之前的項目創建一個 dev 分支:

3. Jenkins 配置自動觸發構建,之前有詳細講過:

4. GitLab 添加 Jenkins Token:

5. Jenkins 添加 Pipeline 操作:
生成 git 拉去配置:

配置 Pipeline 操作:
node { stage("拉取代碼"){ echo 'STEP 1:clone code' git branch: 'dev', credentialsId: 'xxx', url: 'http://192.168.10.199:8041/xxx.git' } stage("打包代碼"){ echo 'STEP 2:code package' } stage("上線發布"){ echo 'STEP 3:deploy package' } }
6. 提交分支測試:

可以看到觸發自動構建成功。
此時我們創建合並請求:

7. GitLab 創建用戶 API 授權 Token:
這里就會用到上一節我們說沒用的配置,因為上一節其實是 GitLab 觸發 Jenkins,所以 Jenkins 不需要 GitLab 的其他權限。
但是這一節不同,Jenkins 需要將構建結果返回給 GitLab,所以這時候就需要這個 Token 了。
GitLab 配置用戶授權 Token:

創建 Token,勾選 API 權限:

記住這個 Token,因為只能看到這一次,忘了只能重新創建:

8. Jenkins 配置 GitLab 授權 Token:
打開:系統管理 --> 系統設置

添加的 Token 的時候注意類型是:GitLab API token

9. 修改 Pipeline 的配置:
node { gitlabCommitStatus{ stage("拉取代碼"){ echo 'STEP 1:clone code' git branch: 'dev', credentialsId: 'xxx', url: 'http://192.168.10.199:8041/xxx.git' } stage("打包代碼"){ echo 'STEP 2:code package' } stage("上線發布"){ echo 'STEP 3:deploy package' } } }
注意:我們在外層添加了 gitlab 的配置。
10. 此時提交代碼觸發構建:

11. GitLab 提交合並請求:

此時我們可以看到在合並請求下方,多了一個 Pipelines 的欄目,里面有我們構建的結果。
這個處理的作用在於,在我們上線合並代碼之前,我們能夠知道代碼是否存在問題,保證我們上線構建。
擴展插件:Blue Ocean
什么是 Blue Ocean?這其實就是 Jenkins 的一個主題,針對 Pipeline 顯示做了優化,看起來更牛逼了。
可以去插件中心安裝:

安裝完成重啟后,會在側邊欄增加入口:

可以直接進去查看:

全新的構建過程頁面,顏值更高:

感興趣的可以自己去研究,畢竟 Jenkins 本身的界面已經很多年沒變過了,確實丑了點。
小結
Pipeline 的配置簡單的可以談到這里,另外還有他的 SCM 的配置,相對來說比較復雜,包括 Jenkinsfile,感興趣可以去深入研究,我們還是那個觀點,這些配置都是為了服務我們更好的完成工作的。如果學習成本太高但是又沒有實質性跨越性的提高我們使用能力。有些知識是可以舍棄的。干我們這行要懂得取舍,不然得學的東西實在太多。
