Jenkins 持續集成iOS、Android項目


目錄

一、什么是持續集成?

二、我們為什么要用持續集成?

三、安裝環境配置

四、iOS 項目配置

五、Android 項目配置

六、寫在最后


一、什么是持續集成?

持續集成指的是頻繁主動的將代碼集合并到代碼倉庫當中,方便產品保持高質量的快速迭代。持續集成的好處主要有:

1)快速發現錯誤。每完成一點更新,就集成到主干,可以快速發現錯誤,定位錯誤也比較容易。

2)防止分支大幅偏離主干。如果不是經常集成,主干又在不斷更新,會導致以后集成的難度變大,甚至難以集成。

在一次的集成都必須通過自動化的構建(包括編譯、打包、發布、自動化測試等)來驗證,從而盡早的發現集成當中的錯誤。

與持續集成相關的,還有兩個概念,分別是持續交付持續部署

持續交付(Continuous delivery)指的是,頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供測試。如果測試通過,代碼就進入生產階段。

持續部署(continuous deployment)是持續交付的下一步,指的是代碼通過評審以后,自動部署到生產環境。

二、我們為什么要用持續集成?

團隊中目前最大的痛點就是開發的時間被碎片化。隨著產品種類越來越多,也冒出來了各種各樣的測試Case,特定的環境、特定的跳轉、特定的需求,開發同學在打包上花費的時間也是越來越多。任務經常性的被打斷,還有可能分心導致代碼質量的下降等等。為了解決這種問題,我們打算為內部同學提供一套簡單自動的開發者環境,引入了Jenkins 持續集成。前期主要的目的就是提供一套可以動態配置常用參數、自動構建安裝包、自動分發下載的平臺。后期會接入QA 相關的自動化測試、靜態代碼檢測,安裝包內也會加大對開發者功能的支持。

三、安裝環境配置

由于要支持iOS 與Android 兩種不同系統,最終選擇Mac 系統當做服務器系統,版本10.12.4。Jenkins 版本2.46.2,這里就不贅述Jenkins 的安裝方法與登錄方法了。

以下列舉了目前使用到的Jenkins 插件和版本號,吐槽一下,配置過程中發現有些以前教程里的插件現在根本搜不到,無奈只能用其他方式解決:

Android Emulator Plugin ? ? ? ? ? ? ? ? ? ?2.15

Android Lint Plugin ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2.4

build-name-setter ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1.6.5

description setter plugin ? ? ? ? ? ? ? ? ? ? 1.10

GitHub Organization Folder Plugin ? ? 1.6

Gitlab Hook Plugin ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1.4.2

GitLab Plugin ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1.4.5

Global Post Script Plugin ? ? ? ? ? ? ? ? ? ?1.1.3

Gradle Plugin ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1.26

Keychains and Provisioning Profiles Management ? ? ? ? ?1.0.0

Publish Over FTP ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1.12

Xcode integration ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1.4.11

四、iOS 項目配置

這里最主要使用的兩個Jenkins 插件是Xcode integration和Keychains and Provisioning Profiles Management。

1. 配置Keychains and Provisioning Profiles Management

安裝好本插件后,進入Jenkins--系統管理會多出來一個“Keychains and Provisioning Profiles Management” 選項。

首先進行上傳login.keychain 文件,查找地址是

/Users/用戶名/Library/keychains/login.keychain

接下來指定Code Signing Identity,可以從Xcode 里的Signing 選項中或者通過命令行查看login.keychain 內包含的:

security find-identity -p codesigning 地址/login.keychain

比如這里我選擇了正式打包時使用的,

iPhone Distribution: XXXXX (Beijing) Network Technology Co., Ltd (3GEKQMXXXX)

配置Provisioning Profiles 目錄,這里最好將整個開發機上的鑰匙串和配置文件目錄都拷貝到Jenkins/Library 目錄下,

/User/用戶/Library/Keychains

/User/用戶/Library/MobileDevice/Provisioning Profiles

所以配置Jenkins 的Provisioning Profiles Directory Path為:

/Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profiles

3. 配置iOS Jobs

1)新建--構建一個自由風格的軟件項目

2)選中“丟棄舊的構建”,普遍選擇保留3天,30個構建個數。

3)選擇“參數化構建過程”,可根據業務配置動態參數,使用${NAME} 可得到選擇的值。

4)源碼管理選擇Git,填寫Repository URL 代碼倉庫地址,Credentials 新建這里我選擇了username 和password 的方式進行訪問。

這里需要注意下系統Git 的版本號,如果Git 版本低于1.8 可能會一直出現401 權限問題,需要升級Git 版本到1.8 以上。

5)構建觸發器

可以配置定時任務、觸發式任務等,觸發式任務可定期檢測代碼倉庫是否有更新,并自動執行構建操作。配置規則Jenkins 的幫助寫的很詳細,這里就簡單列一下:

第一個參數代表的是分鐘 minute,取值 0~59;

第二個參數代表的是小時 hour,取值 0~23;

第三個參數代表的是天 day,取值 1~31;

第四個參數代表的是月 month,取值 1~12;

最后一個參數代表的是星期 week,取值 0~7,0 和 7 都是表示星期天。

如H/15 * * * * 表示的就是每15分鐘檢查一次源碼變化。

6)構建環境,選中Keychains and Code Signing Identities,Keychain 行選擇之前配置的login.keychain 即可。

彈出的選擇框中可能無法選擇Keychain,這個時候先選中Keychain and Code Singing Identities 選項,先保存一下當前配置,重新進入Jobs 配置頁面就可以正常選擇了。

7)構建

由于要執行pod 和動態參數改變,構建前先執行我們自己的腳本文件。增加構建步驟,選擇Execute shell,注意位置要放在“構建”模塊的第一位。

#bin/bsah - l

export LANG=en_US.UTF-8

export LANGUAGE=en_US.UTF-8

export LC_ALL=en_US.UTF-8

cd $WORKSPACE/你的項目文件

/usr/local/bin/pod update --verbose --no-repo-update

#這里可以做一些動態參數的替換,例如:

oldParm="www.baidu.com"

newParm="www.sina.com"

parmSed="sed -i \"\" \"s/$oldParm/$newParm/g\" main.pch"

eval $parmSed

再次增加構建步驟,選擇Xcode 插件。General build settings:

如果當前有Target ,就填寫;我們項目因為用到了Today 插件,不止一個Target,就不填寫。

選中Clean before build?,每次編譯前Clean 一下。

選中Generate Archive?

通過Configuration 可以選擇當前是Release 版本還是Debug 版本。

選中Pack application and build .ipa?,指定生成ipa 包,.ipa filename pattern 包名規則自定義,這里為app_${VERSION}_${BUILD_DATE}。

Output directory 目錄為${WORKSPACE}/build/ ,指定打包后的ipa 文件輸出目錄。

Code signing & OS X keychain options:

選中sign IPA at build time,選中unlock keychain,Keychain Path 填寫${KEYCHAIN_PATH},鑰匙串密碼這里為系統用戶登錄密碼。

Advanced Xcode build options:

配置Xcode Schema File,可以通過Xcode 的Manage Schemas... 查看現有的Schema。

Custom xcodebuild arguments 配置為PROVISIONING_PROFILE=${項目Target_PROVISIONING_PROFILE}。

Xcode Workspace File 配置為${HOME}/Home/workspace/AppForiOS/xxxx,這里指向的是項目的xcworkspace文件,但是在構建過程中Jenkins 會自動追加.xcworkspace 后綴名,填寫時需要注意。注意:這個參數配置了,下面的Xcode Project File 參數配置就無效了。

Xcode Project Directory 配置為包含了xcodeproj 文件的目錄,只需要單獨一個目錄名就可以,這里是相對路徑從$workspace 開始。

Xcode Project File 如果要配置的話指向xcodeproj 文件即可。

Build output directory 輸出指向${WORKSPACE}/build/,這里的輸出不止包括.ipa 安裝包。

8)構建后操作

構建后的流程是上傳至蒲公英后在Jenkins 的構建歷史中顯示下載地址、二維碼等,或者可以FTP 上傳到內部服務器、發送郵件等,根據需求選擇。

增加構建后操作步驟選擇Post build task,勾選Run script only if all previous steps were successful,腳本執行蒲公英上傳功能:

#蒲公英上的User Key

uKey="3f9526ca10b8d43f3fa881b98xxxxx"

#蒲公英上的API Key

apiKey="95f337f90fe42dad8bb84xxxxxxx"

cd build

name="$(find . -maxdepth 1 -name '*.ipa')"

#要上傳的ipa文件路徑

IPA_PATH="${WORKSPACE}/build/$name"

#執行上傳至蒲公英的命令

curl -F "file=@$IPA_PATH" -F "uKey=$uKey" -F "_api_key=$apiKey" https://qiniu-storage.pgyer.com/apiv1/app/upload

再次增加構建后操作步驟,選擇Set build description(注意上下順序),

Regular expression 配置"appQRCodeURL":"(.*)",這里可以根據正則從日志中匹配到想獲得的值,在Description 里使用\1、\2等展示正則匹配的值,這里就自由發揮了。如果要以HTML 的方式(顯示圖片等)展示描述信息,需要將Jenkins--系統管理--Configure Global Security--Markup Formatter 選項改為“Safe HTML”。

4. 配置中的問題

由于Jenkins 是以“Jenkins”用戶的身份進行操作,構建過程中會出現各種的權限問題,我都是比較暴力的直接修改文件的權限進行解決。

構建出現錯誤:xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH。

解決方法:發現Xcode 8.3 以后已經廢棄了PackageApplication,所以解決方式就是從舊版上復制一份來使用。

https://pan.baidu.com/s/1kVqP8xx 下載PackageApplication

拷貝至/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ 目錄下

執行命令 sudo xcode-select -switch/Applications/Xcode.app/Contents/Developer/

chmod +x/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication

執行pod 命令時出現ERROR: SSL verification error at depth 1: unable to get local issuer certificate (20)

解決方法:出現這個問題的原因主要是Ruby環境需要2.2版本以上,所以要更新Ruby環境。

1.安裝rvm:$ curl -L get.rvm.io | bash -s stable

2.裝載rvm:$ source ~/.rvm/scripts/rvm

3.安裝2.3.0版本ruby:$ rvm install 2.3.0

4.將2.3.0設為默認:$ rvm use 2.3.0 --default

執行pod 時出現env: ruby_executable_hooks: No such file or directory

解決方法:嘗試升級ruby、嘗試安裝executable_hooks、嘗試修改命令腳本引用、嘗試修改Jenkins 環境變量PATH。

這個卡的時間比較長,也是各種資料查。因為在服務器機器上執行pod,或者配置Path 后終端都可以正常使用,但是在執行Jenkins 構建的時候卻一直失敗。一開始以為是環境版本太低,能升級的都升了。后來還嘗試安裝了executable_hooks(命令sudo gem install --user-install executable-hooks)。嘗試過去修改pod 命令里的引用,直接指到安裝后的ruby 目錄(引用!#/Users/Shared/Jenkins/.rvm/rubies/ruby-2.3.0/bin ruby_executable_hooks)或者修改GEM_PATH(/Users/Shared/Jenkins/.rvm/gems/ruby-2.3.0/environment)等等。最后看到有可能是Jenkins 執行Shell 腳本時的環境與服務器的系統環境不相同,嘗試在Shell 腳本中輸出一些變量值進行觀察,因為對Shell 腳本不是很熟悉,最后去Jenkins--系統管理--系統設置--全局屬性中,新增鍵值對PATH,值指向新版本ruby(/Users/Shared/Jenkins/.rvm/rubies/ruby-2.3.0/bin:$PATH)

五、Android 項目配置

配置好iOS 項目后,再進行Android 的配置就簡單很多,這里主要是對Android 的開發環境進行配置,主要使用的Jenkins 插件是Gradle Plugin。

1. 環境配置

Jenkins--系統管理--系統設置

選中Environment variables,新增鍵值對ANDROID_HOME,指向Android 的SDK目錄。

Jenkins--系統管理--Global Tool Configuration

Gradle 安裝,隨便起一個Gradle 配置名稱,GRADLE_HOME 配置/Applications/Android Studio.app/Contents/gradle/gradle-x.x。

2. Jobs 配置

其他部分與iOS 配置類似,只需要增加構建步驟從Xcode 切換成Invoke Gradle script 插件,

選中Invoke Gradle,Gradle Version 選擇剛才已經配置好的Gradle 名稱。

Task 任務內填入clean build,表示執行clean 和build 兩個操作。這里需要注意build 操作會將項目中build.gralde 配置文件中buildTypes 下所有的配置都執行一遍,第一次時沒有注意就執行了build,結果10+個配置一共執行了45分鐘。如果想打單獨配置的包,填入assemblerelease 包,根據buildTypes 內的定義即可。

Root Build script,配置${workspace}/app/,這里指向的是項目使用的build.gradle 文件目錄。如果build.gradle 文件就在項目根目錄,則不用填寫。

Post build task,增加APK 簽名命令,jarsigner -verbose -keystore keystore地址 -signedjar 簽名后的文件名 -digestalg SHA1 -sigalg MD5withRSA 未簽名的安裝包地址 keystore的alias -storepass keystore的密碼

3. 配置中的問題

Jenkins構建Android 出現/Users/Shared/Jenkins/.android/analytics.settings(No such file or directory)

解決:創建.android 目錄

SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable

解決:項目中缺少local.properties文件,主動創建,填寫內容sdk.dir=“sdk目錄”

Jenkins A problem occurred configuring project‘:app’. > The SDK directory‘/User/用戶/Library/Android/sdk' does not exist

解決:將改目錄的權限全部設置成了777

六、寫在最后

目前只是實現了簡單的基礎功能,發現坑確實不少,但不得不說Jenkins 的日志真的很詳細,定位問題很方便。以上就是Jenkins 的一些經驗,特此記錄總結一下。

參考鏈接

阮一峰 http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html

七、補充匯總

在新復制一個帶有“Git Parameter”插件的項目后,點擊“Build with Parameters” 時,選擇分支的選擇框內提示“null Please look at the log”。

解決:由于在Jenkins workspace 目錄下沒有任何相關的代碼,只需要直接進行構建,拉取一次遠程代碼到本地,再次點擊就會正常顯示分支信息了。?


在配置iOS 靜態代碼掃描時,使用sonar-objective-c-plugin-0.5.0-SNAPSHOT.jar 插件進行掃描,該插件版本與sonarQube 系統版本相關,需要注意。目前遺留問題是OC 的掃描規則太少,掃描結果只能掃出壞味道,Bug 和漏洞都無法掃到。配置文件增加了如下配置也沒有效果:

sonar.objectivec.oclint.report=oclint.xml

sonar.objectivec.oclint.reportPath=sonar-reports/oclint.xml

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容