最近在使用jenkins中踩了很多雷。Jenkins做爲CI第一大神器,擁有龐大的1058個擴展插件。也許你要的答案就在裏面,可是若是沒有好好學習,她也可能把你搞的生活沒法自理~~理想是豐滿的現實是骨幹的,因爲樓主沒有好好學習,本文中用到的一些費勁和曲折方法確定不是正道!都說真理每每是簡捷的,還請路過的大神指點。
場景一: Job構建步驟間的變量傳遞
Jenkins提供了數十種構建方式,咱們以最經常使用的『Execute shell』爲例。有時爲了使Job中的複雜的構建流程更加清晰咱們配置多個構建步驟像下面這樣。圖中包含
兩個構建步驟,步驟2須要根據步驟1中的返回值來判斷是否執行操做:
執行時jenkins將兩個構建步驟生成兩個shell文件,而後分別調用。
do_build_step_1
[Jenkins] $ /bin/bash -xe /tmp/hudson1270042613896791809.sh
do_build_step_2
[Jenkins] $ /bin/bash -xe /tmp/hudson5918908417824291692.sh
理論上兩個shell之間是沒法通訊的,step1執行完以後變量$dostep2就會被回收,要注意試圖在step1中經過export或者其餘腳本方式注入環境變量都是無效的。
解決方案:讀寫文件
要實現它們之間的變量傳遞只能經過讀寫文件的方式。咱們有一個真實應用場景是這樣的,
配置由git push觸發編譯任務,可是並非每一次git的提交都須要觸發編譯,好比說只有前端代碼的提交其實並不影響編譯的結果,咱們只好在step1中加入判斷來卻肯定step2是否真的有必要被執行。
場景二: Job之間的變量傳遞
如今有兩個Project『run_compile』和『run_deploy』,代碼編譯成功後開始執行環境部署。不須要傳遞參數的狀況下能夠選擇「Build other projects「的方式。
須要傳遞參數則須要選擇"Trigger parameterized build on other projects"的方式。
Jenkins Parameterized Trigger plugin能夠實現Job間參數傳遞可是有侷限性,咱們只能選擇傳遞當前build的參數或者環境變量。 (例:$GIT_COMMIT是git plugin提供的一個變量,存着當前build觸發時最新的git code.)
若是要傳遞一個自定義的變量怎麼辦呢? 構建步驟中的自定義變量在執行結束後都會被回收,咱們不可能在"predefined parameters"中取到。
依舊以編譯任務爲例,前端代碼的提交不須要觸發編譯,沒有編譯也就不須要執行接下來的『run_ut』單元測試。(泛指後臺代碼的UT, JS UT這種稀有存在暫不考慮)
如何將編譯的狀態告訴下游的單元測試呢?
聰明的你想起了場景一的解決辦法。對,咱們也能夠經過讀寫文件的方式來解決這個問題嘛!
不過這裏我不推薦你們採用這種方式,理由有兩點:
一,『run_compile』和『run_ut』有可能被部署在不一樣slave上,若是考慮更加智能的CI配置方式會在構建時動態的選擇空閒的slave去執行,這種文件讀寫的方式就有了很大的侷限性;
二,很難確保文件傳遞的準確性,若是『run_compile』寫入文件失敗,『run_ut』中讀到的就是一箇舊值一個不許確的值。
解決方案一:經過properties file的方式傳遞參數。
首先將變量以"xx=xx"的樣式寫入到配置文件『propfile.txt』中。
而後在"Trigger parameterized build on other projects"中選擇"Parameters from preperties file",在propfile裏寫入多個變量就能夠傳遞多個值。
建議勾選"Don't trigger if any files are missing"和刪除舊文件配合使用。
最後在『run_ut』中能夠直接獲取這個變量來使用了。
解決方案二: 經過EnvInject Plugin插件
咱們在構建中增長步驟"Inject environment variables", 將寫在配置文件中的變量${IFUT},注入到環境變量裏。
這樣在"Trigger parameterized build on other projects"就能夠直接選擇"predefined parameters"方式直接傳遞變量了。一樣的在Job『run_deploy』裏就能夠直接訪問變量${IFUT}了。
本次要分享的內容就這麼多。
最後有一個槽點:
爲何jenkins不支持根據條件判斷來決定是否觸發下一個Project呢?
實際上我最但願的是當ifut=false的時候就直接不觸發『run_ut』,『run_ut』不被觸發也就省去了很多無用功。
參考資料: