使用 Jenkins 搭建 iOS/Android 持續集成打包平臺【轉】

背景描述

根據項目需求,現要在團隊內部搭建一個統一的打包平臺,實現對iOS和Android項目的打包。並且爲了方便團隊內部的測試包分發,但願在打包完成後能生成一個二維碼,體驗用戶(產品、運營、測試等人員)經過手機掃描二維碼後就能直接安裝測試包。html

該需求具備必定的廣泛性,基本上全部開發APP的團隊均可能會用到,所以我將整個需求實現的過程整理後造成此文,而且真正地作到了零基礎上手,到手即飛、開箱即用,但願能對你們有所幫助。java

首先,先給你們展現下平臺建設完成後的總體效果:正則表達式

 

 

 

 

該平臺主要實現的功能有3點:docker

  • 按期對GitHub倉庫進行檢測,如有更新則自動執行構建打包;
  • 構建成功後根據ipa/apk生成二維碼,並可在歷史構建列表中展現各個版本的二維碼,經過手機掃描二維碼可直接安裝對應版本;
  • 在構建結果頁面中展現當次構建的成果物(Artifact,如.ipa.app.apkinfo.plist等文件),供有須要的用戶進行下載。

接下來,本文就開始對平臺建設的完整實現過程進行詳細介紹。shell

安裝Jenkins

Jenkins依賴於Java運行環境,所以須要首先安裝Java安全

安裝Jenkins的方式有多種,能夠運行對應系統類型的安裝包,能夠經過docker獲取鏡像,也能夠直接運行war包。服務器

我我的傾向於直接運行war包的形式,只需下載jenkins.war後,運行以下命令便可啓動Jenkins。markdown

$ nohup java -jar jenkins_located_path/jenkins.war --httpPort=88 &

若是不指定httpPort,Jenkins的默認端口爲8080。網絡

Jenkins插件

Jenkins有很是多的插件,能夠實現各類功能的擴展。oracle

針對搭建的iOS/Android持續集成打包平臺,我使用到了以下幾個插件。

  • GIT plugin
  • SSH Credentials Plugin
  • Git Changelog Plugin: 獲取倉庫提交的commit log
  • build-name-setter:用於修改Build名稱
  • description setter plugin:用於在修改Build描述信息,在描述信息中增長顯示QRCode(二維碼)
  • Post-Build Script Plug-in:在編譯完成後經過執行腳本實現一些額外功能
  • Xcode integration: iOS專用(可選)
  • Gradle plugin: Android專用(可選)

安裝方式也比較簡單,直接在Jenkins的插件管理頁面搜索上述插件,點擊安裝便可。

建立項目(Job)

在Jenkins中,構建項目以Job的形式存在,所以須要針對每一個項目建立一個Job。有時候,一個項目中可能有多個分支同時在進行開發,爲了分別進行構建,也能夠針對每一個分支建立一個Job。

建立Job的方式有多種,本次只須要建立Freestyle project類型的便可。

Main page -> New Item -> Freestyle project

對於一個持續集成打包平臺,每次打包都由4步組成:觸發構建、拉取代碼、執行構建、構建後處理。對應的,在每一個Job中也對應了這幾項的配置。

配置Git代碼倉庫

要對項目進行構建,配置項目的代碼倉庫是必不可少的。因爲當前咱們的項目託管在GitHub私有倉庫中,所以在此須要對Git進行配置。

【Source Code Management】配置欄目下,若是以前GIT plugin安裝成功,則會出現Git選項。

配置Git代碼倉庫時,有三項是必須配置的:倉庫URL地址(Repository URL)、倉庫權限校驗方式(Credentials),以及當前Job須要構建的代碼分支(Branches to build)。

在配置Repository URL時,選擇HTTPS URLSSH URL都可。不過須要注意的是,Credentials要和Repository URL對應,也就是說:

  • 若是Repository URLHTTPS URL形式的,那麼Credentials就要採用GitHub用戶名密碼的校驗方式;並且,若是在GitHub中開啓了2FA(two-factor authentication),那麼還須要在GitHub中建立一個Personal access token,輸入密碼時將這個Personal access token做爲密碼進行輸入。
  • 若是Repository URLSSH URL形式的,那麼就須要先在Jenkins所在的服務器上建立一個SSH祕鑰對,並將公鑰添加到GitHub的SSH keys中,而後在填寫Credentials時,選擇SSH Username with private key的校驗方式,填入GitHub Username、SSH私鑰、以及建立SSH祕鑰對時設置的Passphrase

若是對Git權限校驗的概念還比較模糊,能夠參考《深刻淺出Git權限校驗》。

在配置Branches to build時,能夠採用多種形式,包括分支名稱(branchName)、tagNamecommitId等。其中分支名稱的形式用的最多,例如,如果構建master分支,則填寫refs/heads/master,如果構建develop分支,則填寫refs/heads/develop

除了以上關於Git的必填配置項,有時根據項目的實際狀況,可能還須要對Jenkins的默認配置項進行修改。

比較常見的一種狀況就是對clone的配置進行修改。

在Jenkins的默認配置中,clone代碼時會拉取全部歷史版本的代碼,並且默認的超時時限只有10分鐘。這就形成在某些項目中,因爲代碼量自己就比較大,歷史版本也比較多,再加上網絡環境不是特別好,Jenkins根本無法在10分鐘以內拉取完全部代碼,超時後任務就會被自動終止了(錯誤狀態碼143)。

這種問題的解決方式也很簡單,無非就是兩種思路,要麼少拉取點代碼(不獲取歷史版本),要麼提升超時時限。對應的配置在Advanced clone behaviours中:

  • Shallow clone:勾選後不獲取歷史版本;
  • Timeout (in minutes) for clone and fetch operation:配置後覆蓋默認的超時時限。

配置構建觸發器

代碼倉庫配置好了,意味着Jenkins具備了訪問GitHub代碼倉庫的權限,能夠成功地拉取代碼。

那Jenkins何時執行構建呢?

這就須要配置構建觸發策略,即構建觸發器,配置項位於【Build Triggers】欄目。

觸發器支持多種類型,經常使用的有:

  • 按期進行構建(Build periodically)
  • 根據提交進行構建(Build when a change is pushed to GitHub)
  • 按期檢測代碼更新,若有更新則進行構建(Poll SCM)

構建觸發器的選擇爲複合選項,若選擇多種類型,則任一類型知足構建條件時就會執行構建工做。若是全部類型都不選擇,則該Jenkins Job不執行自動構建,但可經過手動點擊【Build Now】觸發構建。

關於定時器(Schedule)的格式,簡述以下:

MINUTE HOUR DOM MONTH DOW

  • MINUTE: Minutes within the hour (0-59)
  • HOUR: The hour of the day (0-23)
  • DOM: The day of the month (1-31)
  • MONTH: The month (1-12)
  • DOW: The day of the week (0-7) where 0 and 7 are Sunday.

一般狀況下須要指定多個值,這時能夠採用以下operator(優先級從上到下):

  • *適配全部有效的值,若不指定某一項,則以*佔位;
  • M-N適配值域範圍,例如7-9表明7/8/9均知足;
  • M-N/X*/X:以X做爲間隔;
  • A,B,C:枚舉多個值。

另外,爲了不多個任務在同一時刻同時觸發構建,在指定時間段時能夠配合使用H字符。添加H字符後,Jenkins會在指定時間段內隨機選擇一個時間點做爲起始時刻,而後加上設定的時間間隔,計算獲得後續的時間點。直到下一個週期時,Jenkins又會從新隨機選擇一個時間點做爲起始時刻,依次類推。

爲了便於理解,列舉幾個示例:

  • H/15 * * * *:表明每隔15分鐘,而且開始時間不肯定,這個小時多是:07,:22,:37,:52,下一個小時就多是:03,:18,:33,:48
  • H(0-29)/10 * * * *:表明前半小時內每隔10分鐘,而且開始時間不肯定,這個小時多是:04,:14,:24,下一個小時就多是:09,:19,:29
  • H 23 * * 1-5:工做日每晚23:00至23:59之間的某一時刻;

配置構建方式

觸發策略配置好以後,Jenkins就會按照設定的策略自動執行構建。但如何執行構建操做,這還須要咱們經過配置構建方式來進行設定。

經常使用的構建方式是根據構建對象的具體類型,安裝對應的插件,而後採用相應的構建方式。例如,如果構建Android應用,安裝Gradle plugin以後,就能夠選擇Invoke Gradle script,而後採用Gradle進行構建;如果構建iOS應用,安裝Xcode integration插件以後,就能夠選擇Xcode,而後選擇Xcode進行構建。

該種方式的優點是操做簡單,UI可視化,在場景不復雜的狀況下能夠快速知足需求。不過缺點就是依賴於插件已有的功能,若是場景較複雜時可能單個插件還沒法知足需求,須要再安裝其它插件。並且,有些插件可能還存在一些問題,例如對某些操做系統版本或XCode版本兼容不佳,出現問題時咱們就會比較被動。

我我的更傾向於另一種方式,就是本身編寫打包腳本,在腳本中自定義實現全部的構建功能,而後在Execute Shell中執行。這種方式的靈活度更高,各類場景的構建需求都能知足,出現問題後也能自行快速修復。

另外,對於iOS應用的構建,還有一個須要額外關注的點,就是開發者證書的配置。

若是是採用Xcode integration插件進行構建,配置會比較複雜,須要在Jenkins中導入開發證書,並填寫多個配置項。不過,若是是採用打包腳本進行構建的話,狀況就會簡單許多。只要在Jenkins所運行的計算機中安裝好開發者證書,打包命令在Shell中能正常工做,那麼在Jenkins中執行打包腳本也不會有什麼問題。

構建後處理

完成構建後,生成的編譯成果物(ipa/apk)會位於指定的目錄中。可是,若是要直接在手機中安裝ipa/apk文件還比較麻煩,不只在分發測試包時須要將好幾十兆的安裝包進行傳送,體驗用戶在安裝時也還須要經過數據線將手機與計算機進行鏈接,而後再使用PP助手或豌豆莢等工具進行安裝。

當前比較優雅的一種方式是藉助蒲公英(pgyer)fir.im等平臺,將ipa/apk文件上傳至平臺後由平臺生成二維碼,而後只須要對二維碼連接進行分發,體驗用戶經過手機掃描二維碼後便可實現快速安裝,效率獲得了極大的提高。

上傳安裝包文件,生成二維碼

無論是蒲公英仍是fir.im,都有對應的Jenkins插件,安裝插件後能夠在Post-build中實現對安裝包的上傳。

除了使用Jenkins插件,fir.im還支持命令上傳的方式,蒲公英還支持HTTP Post接口上傳的方式。

我我的推薦採用命令或接口上傳的方法,並在構建腳本中進行調用。靈活是一方面,更大的好處是若是上傳失敗後還能進行重試,這在網絡環境不是很穩定的狀況下極其必要。

Jenkins成功完成安裝包上傳後,pgyer/fir.im平臺會生成一個二維碼圖片,並在響應中將圖片的URL連接地址進行返回。

展現二維碼圖片

二維碼圖片的URL連接有了,那要怎樣才能將二維碼圖片展現在Jenkins項目的歷史構建列表中呢?

這裏須要用到另一個插件,description setter plugin。安裝該插件後,在【Post-build Actions】欄目中會多出description setter功能,能夠實現構建完成後設置當次build的描述信息。這個描述信息不只會顯示在build頁面中,同時也會顯示在歷史構建列表中。

有了這個前提,要將二維碼圖片展現在歷史構建列表中貌似就能夠實現了,能直觀想到的方式就是採用HTMLimg標籤,將<img src='qr_code_url'>寫入到build描述信息中。

這個方法的思路是正確的,不過這麼作之後並不會實現咱們預期的效果。

這是由於Jenkins出於安全的考慮,全部描述信息的Markup Formatter默認都是採用Plain text模式,在這種模式下是不會對build描述信息中的HTML編碼進行解析的。

要改變也很容易,Manage Jenkins -> Configure Global Security,將Markup Formatter的設置更改成Safe HTML便可。

更改配置後,咱們就能夠在build描述信息中採用HTMLimg標籤插入圖片了。

另外還須要補充一個點。若是是使用蒲公英(pyger)平臺,會發現每次上傳安裝包後返回的二維碼圖片是一個短連接,神奇的是這個短鏈接竟然是固定的(對同一個帳號而言)。這個短鏈接老是指向最近生成的二維碼圖片,可是對於二維碼圖片的惟一URL地址,平臺並無在響應中進行返回。在這種狀況下,咱們每次構建完成後保存二維碼圖片的URL連接就沒有意義了。

應對的作法是,每次上傳完安裝包後,經過返回的二維碼圖片短連接將二維碼圖片下載並保存到本地,而後在build描述信息中引用該圖片的Jenkins地址便可。

收集編譯成果物(Artifacts)

每次完成構建後,編譯生成的文件較多,可是並非全部的文件都是咱們須要的。

一般狀況下,咱們可能只須要其中的部分文件,例如.ipa/.app/.plist/.apk等,這時咱們能夠將這部分文件單獨收集起來,並在構建頁面中展現出來,以便在須要時進行下載。

要實現這樣一個功能,須要在【Post-build Actions】欄目中新增Archive the artifacts,而後在Files to archive中經過正則表達式指定成果物文件的路徑。

設置完畢後,每次構建完成後,Jenkins會在Console Output中採用設定的正則表達式進行搜索匹配,若是能成功匹配到文件,則會將文件收集起來。

總結

本文主要是對如何使用Jenkins搭建iOS/Android持續集成打包平臺的基礎概念和實施流程進行了介紹。對於其中涉及到的執行命令、構建腳本(build.py),以及Jenkins的詳細配置,出於篇幅長度和閱讀體驗的考慮,並無在文中進行詳細展開。

爲了實現真正的開箱即用,我將Jenkins的配置文件和構建腳本抽離出來造成一套模板,只須要導入到Jenkins中,而後針對具體的項目修改少許配置信息,便可將這一套持續集成打包平臺運行起來,實現和文章開頭插圖中徹底相同的功能效果。

相關文章
相關標籤/搜索