目錄
一制跟、什么是持續(xù)集成?
二酱虎、我們?yōu)槭裁匆贸掷m(xù)集成雨膨?
三、安裝環(huán)境配置
四读串、iOS 項(xiàng)目配置
五聊记、Android 項(xiàng)目配置
六、寫在最后
一恢暖、什么是持續(xù)集成排监?
持續(xù)集成指的是頻繁主動(dòng)的將代碼集合并到代碼倉庫當(dāng)中,方便產(chǎn)品保持高質(zhì)量的快速迭代杰捂。持續(xù)集成的好處主要有:
1)快速發(fā)現(xiàn)錯(cuò)誤舆床。每完成一點(diǎn)更新,就集成到主干,可以快速發(fā)現(xiàn)錯(cuò)誤挨队,定位錯(cuò)誤也比較容易谷暮。
2)防止分支大幅偏離主干。如果不是經(jīng)常集成瞒瘸,主干又在不斷更新坷备,會(huì)導(dǎo)致以后集成的難度變大,甚至難以集成情臭。
在一次的集成都必須通過自動(dòng)化的構(gòu)建(包括編譯省撑、打包、發(fā)布俯在、自動(dòng)化測試等)來驗(yàn)證竟秫,從而盡早的發(fā)現(xiàn)集成當(dāng)中的錯(cuò)誤。
與持續(xù)集成相關(guān)的跷乐,還有兩個(gè)概念肥败,分別是持續(xù)交付和持續(xù)部署:
持續(xù)交付(Continuous delivery)指的是,頻繁地將軟件的新版本愕提,交付給質(zhì)量團(tuán)隊(duì)或者用戶馒稍,以供測試。如果測試通過浅侨,代碼就進(jìn)入生產(chǎn)階段纽谒。
持續(xù)部署(continuous deployment)是持續(xù)交付的下一步,指的是代碼通過評(píng)審以后如输,自動(dòng)部署到生產(chǎn)環(huán)境鼓黔。
二、我們?yōu)槭裁匆贸掷m(xù)集成不见?
團(tuán)隊(duì)中目前最大的痛點(diǎn)就是開發(fā)的時(shí)間被碎片化澳化。隨著產(chǎn)品種類越來越多,也冒出來了各種各樣的測試Case稳吮,特定的環(huán)境缎谷、特定的跳轉(zhuǎn)、特定的需求灶似,開發(fā)同學(xué)在打包上花費(fèi)的時(shí)間也是越來越多慎陵。任務(wù)經(jīng)常性的被打斷,還有可能分心導(dǎo)致代碼質(zhì)量的下降等等喻奥。為了解決這種問題,我們打算為內(nèi)部同學(xué)提供一套簡單自動(dòng)的開發(fā)者環(huán)境捏悬,引入了Jenkins 持續(xù)集成撞蚕。前期主要的目的就是提供一套可以動(dòng)態(tài)配置常用參數(shù)、自動(dòng)構(gòu)建安裝包过牙、自動(dòng)分發(fā)下載的平臺(tái)甥厦。后期會(huì)接入QA 相關(guān)的自動(dòng)化測試纺铭、靜態(tài)代碼檢測,安裝包內(nèi)也會(huì)加大對(duì)開發(fā)者功能的支持刀疙。
三舶赔、安裝環(huán)境配置
由于要支持iOS 與Android 兩種不同系統(tǒng),最終選擇Mac 系統(tǒng)當(dāng)做服務(wù)器系統(tǒng)谦秧,版本10.12.4竟纳。Jenkins 版本2.46.2,這里就不贅述Jenkins 的安裝方法與登錄方法了疚鲤。
以下列舉了目前使用到的Jenkins 插件和版本號(hào)锥累,吐槽一下,配置過程中發(fā)現(xiàn)有些以前教程里的插件現(xiàn)在根本搜不到集歇,無奈只能用其他方式解決:
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 項(xiàng)目配置
這里最主要使用的兩個(gè)Jenkins 插件是Xcode integration和Keychains and Provisioning Profiles Management。
1. 配置Keychains and Provisioning Profiles Management
安裝好本插件后诲宇,進(jìn)入Jenkins--系統(tǒng)管理會(huì)多出來一個(gè)“Keychains and Provisioning Profiles Management” 選項(xiàng)际歼。
首先進(jìn)行上傳login.keychain 文件,查找地址是
/Users/用戶名/Library/keychains/login.keychain
接下來指定Code Signing Identity姑蓝,可以從Xcode 里的Signing 選項(xiàng)中或者通過命令行查看login.keychain 內(nèi)包含的:
security find-identity -p codesigning 地址/login.keychain
比如這里我選擇了正式打包時(shí)使用的鹅心,
iPhone Distribution: XXXXX (Beijing) Network Technology Co., Ltd (3GEKQMXXXX)
配置Provisioning Profiles 目錄,這里最好將整個(gè)開發(fā)機(jī)上的鑰匙串和配置文件目錄都拷貝到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)新建--構(gòu)建一個(gè)自由風(fēng)格的軟件項(xiàng)目
2)選中“丟棄舊的構(gòu)建”巴帮,普遍選擇保留3天,30個(gè)構(gòu)建個(gè)數(shù)虐秋。
3)選擇“參數(shù)化構(gòu)建過程”榕茧,可根據(jù)業(yè)務(wù)配置動(dòng)態(tài)參數(shù),使用${NAME} 可得到選擇的值客给。
4)源碼管理選擇Git用押,填寫Repository URL 代碼倉庫地址,Credentials 新建這里我選擇了username 和password 的方式進(jìn)行訪問靶剑。
這里需要注意下系統(tǒng)Git 的版本號(hào)蜻拨,如果Git 版本低于1.8 可能會(huì)一直出現(xiàn)401 權(quán)限問題,需要升級(jí)Git 版本到1.8 以上桩引。
5)構(gòu)建觸發(fā)器
可以配置定時(shí)任務(wù)缎讼、觸發(fā)式任務(wù)等,觸發(fā)式任務(wù)可定期檢測代碼倉庫是否有更新坑匠,并自動(dòng)執(zhí)行構(gòu)建操作血崭。配置規(guī)則Jenkins 的幫助寫的很詳細(xì),這里就簡單列一下:
第一個(gè)參數(shù)代表的是分鐘 minute,取值 0~59夹纫;
第二個(gè)參數(shù)代表的是小時(shí) hour咽瓷,取值 0~23;
第三個(gè)參數(shù)代表的是天 day舰讹,取值 1~31茅姜;
第四個(gè)參數(shù)代表的是月 month,取值 1~12月匣;
最后一個(gè)參數(shù)代表的是星期 week钻洒,取值 0~7,0 和 7 都是表示星期天桶错。
如H/15 * * * * 表示的就是每15分鐘檢查一次源碼變化航唆。
6)構(gòu)建環(huán)境,選中Keychains and Code Signing Identities院刁,Keychain 行選擇之前配置的login.keychain 即可糯钙。
彈出的選擇框中可能無法選擇Keychain,這個(gè)時(shí)候先選中Keychain and Code Singing Identities 選項(xiàng)退腥,先保存一下當(dāng)前配置任岸,重新進(jìn)入Jobs 配置頁面就可以正常選擇了。
7)構(gòu)建
由于要執(zhí)行pod 和動(dòng)態(tài)參數(shù)改變狡刘,構(gòu)建前先執(zhí)行我們自己的腳本文件享潜。增加構(gòu)建步驟,選擇Execute shell嗅蔬,注意位置要放在“構(gòu)建”模塊的第一位剑按。
#bin/bsah - l
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
cd $WORKSPACE/你的項(xiàng)目文件
/usr/local/bin/pod update --verbose --no-repo-update
#這里可以做一些動(dòng)態(tài)參數(shù)的替換,例如:
oldParm="www.baidu.com"
newParm="www.sina.com"
parmSed="sed -i \"\" \"s/$oldParm/$newParm/g\" main.pch"
eval $parmSed
再次增加構(gòu)建步驟澜术,選擇Xcode 插件艺蝴。General build settings:
如果當(dāng)前有Target ,就填寫鸟废;我們項(xiàng)目因?yàn)橛玫搅薚oday 插件猜敢,不止一個(gè)Target,就不填寫盒延。
選中Clean before build?缩擂,每次編譯前Clean 一下。
選中Generate Archive?
通過Configuration 可以選擇當(dāng)前是Release 版本還是Debug 版本添寺。
選中Pack application and build .ipa?胯盯,指定生成ipa 包,.ipa filename pattern 包名規(guī)則自定義计露,這里為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}胶坠,鑰匙串密碼這里為系統(tǒng)用戶登錄密碼君账。
Advanced Xcode build options:
配置Xcode Schema File,可以通過Xcode 的Manage Schemas... 查看現(xiàn)有的Schema沈善。
Custom xcodebuild arguments 配置為PROVISIONING_PROFILE=${項(xiàng)目Target_PROVISIONING_PROFILE}乡数。
Xcode Workspace File 配置為${HOME}/Home/workspace/AppForiOS/xxxx,這里指向的是項(xiàng)目的xcworkspace文件闻牡,但是在構(gòu)建過程中Jenkins 會(huì)自動(dòng)追加.xcworkspace 后綴名净赴,填寫時(shí)需要注意。注意:這個(gè)參數(shù)配置了罩润,下面的Xcode Project File 參數(shù)配置就無效了玖翅。
Xcode Project Directory 配置為包含了xcodeproj 文件的目錄,只需要單獨(dú)一個(gè)目錄名就可以割以,這里是相對(duì)路徑從$workspace 開始金度。
Xcode Project File 如果要配置的話指向xcodeproj 文件即可。
Build output directory 輸出指向${WORKSPACE}/build/严沥,這里的輸出不止包括.ipa 安裝包猜极。
8)構(gòu)建后操作
構(gòu)建后的流程是上傳至蒲公英后在Jenkins 的構(gòu)建歷史中顯示下載地址、二維碼等消玄,或者可以FTP 上傳到內(nèi)部服務(wù)器跟伏、發(fā)送郵件等,根據(jù)需求選擇翩瓜。
增加構(gòu)建后操作步驟選擇Post build task受扳,勾選Run script only if all previous steps were successful,腳本執(zhí)行蒲公英上傳功能:
#蒲公英上的User Key
uKey="3f9526ca10b8d43f3fa881b98xxxxx"
#蒲公英上的API Key
apiKey="95f337f90fe42dad8bb84xxxxxxx"
cd build
name="$(find . -maxdepth 1 -name '*.ipa')"
#要上傳的ipa文件路徑
IPA_PATH="${WORKSPACE}/build/$name"
#執(zhí)行上傳至蒲公英的命令
curl -F "file=@$IPA_PATH" -F "uKey=$uKey" -F "_api_key=$apiKey" https://qiniu-storage.pgyer.com/apiv1/app/upload
再次增加構(gòu)建后操作步驟奥溺,選擇Set build description(注意上下順序)辞色,
Regular expression 配置"appQRCodeURL":"(.*)",這里可以根據(jù)正則從日志中匹配到想獲得的值浮定,在Description 里使用\1相满、\2等展示正則匹配的值,這里就自由發(fā)揮了桦卒。如果要以HTML 的方式(顯示圖片等)展示描述信息立美,需要將Jenkins--系統(tǒng)管理--Configure Global Security--Markup Formatter 選項(xiàng)改為“Safe HTML”。
4. 配置中的問題
由于Jenkins 是以“Jenkins”用戶的身份進(jìn)行操作方灾,構(gòu)建過程中會(huì)出現(xiàn)各種的權(quán)限問題建蹄,我都是比較暴力的直接修改文件的權(quán)限進(jìn)行解決碌更。
構(gòu)建出現(xiàn)錯(cuò)誤:xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH。
解決方法:發(fā)現(xiàn)Xcode 8.3 以后已經(jīng)廢棄了PackageApplication洞慎,所以解決方式就是從舊版上復(fù)制一份來使用痛单。
https://pan.baidu.com/s/1kVqP8xx 下載PackageApplication
拷貝至/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ 目錄下
執(zhí)行命令 sudo xcode-select -switch/Applications/Xcode.app/Contents/Developer/
chmod +x/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication
執(zhí)行pod 命令時(shí)出現(xiàn)ERROR: SSL verification error at depth 1: unable to get local issuer certificate (20)
解決方法:出現(xiàn)這個(gè)問題的原因主要是Ruby環(huán)境需要2.2版本以上,所以要更新Ruby環(huán)境劲腿。
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設(shè)為默認(rèn):$ rvm use 2.3.0 --default
執(zhí)行pod 時(shí)出現(xiàn)env: ruby_executable_hooks: No such file or directory
解決方法:嘗試升級(jí)ruby旭绒、嘗試安裝executable_hooks、嘗試修改命令腳本引用焦人、嘗試修改Jenkins 環(huán)境變量PATH挥吵。
這個(gè)卡的時(shí)間比較長,也是各種資料查花椭。因?yàn)樵诜?wù)器機(jī)器上執(zhí)行pod忽匈,或者配置Path 后終端都可以正常使用,但是在執(zhí)行Jenkins 構(gòu)建的時(shí)候卻一直失敗矿辽。一開始以為是環(huán)境版本太低丹允,能升級(jí)的都升了。后來還嘗試安裝了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 執(zhí)行Shell 腳本時(shí)的環(huán)境與服務(wù)器的系統(tǒng)環(huán)境不相同奕污,嘗試在Shell 腳本中輸出一些變量值進(jìn)行觀察萎羔,因?yàn)閷?duì)Shell 腳本不是很熟悉,最后去Jenkins--系統(tǒng)管理--系統(tǒng)設(shè)置--全局屬性中碳默,新增鍵值對(duì)PATH贾陷,值指向新版本ruby(/Users/Shared/Jenkins/.rvm/rubies/ruby-2.3.0/bin:$PATH)
五、Android 項(xiàng)目配置
配置好iOS 項(xiàng)目后嘱根,再進(jìn)行Android 的配置就簡單很多髓废,這里主要是對(duì)Android 的開發(fā)環(huán)境進(jìn)行配置,主要使用的Jenkins 插件是Gradle Plugin该抒。
1. 環(huán)境配置
Jenkins--系統(tǒng)管理--系統(tǒng)設(shè)置
選中Environment variables慌洪,新增鍵值對(duì)ANDROID_HOME,指向Android 的SDK目錄凑保。
Jenkins--系統(tǒng)管理--Global Tool Configuration
Gradle 安裝冈爹,隨便起一個(gè)Gradle 配置名稱,GRADLE_HOME 配置/Applications/Android Studio.app/Contents/gradle/gradle-x.x欧引。
2. Jobs 配置
其他部分與iOS 配置類似频伤,只需要增加構(gòu)建步驟從Xcode 切換成Invoke Gradle script 插件,
選中Invoke Gradle芝此,Gradle Version 選擇剛才已經(jīng)配置好的Gradle 名稱憋肖。
Task 任務(wù)內(nèi)填入clean build因痛,表示執(zhí)行clean 和build 兩個(gè)操作。這里需要注意build 操作會(huì)將項(xiàng)目中build.gralde 配置文件中buildTypes 下所有的配置都執(zhí)行一遍岸更,第一次時(shí)沒有注意就執(zhí)行了build鸵膏,結(jié)果10+個(gè)配置一共執(zhí)行了45分鐘。如果想打單獨(dú)配置的包怎炊,填入assemblerelease 包较性,根據(jù)buildTypes 內(nèi)的定義即可。
Root Build script结胀,配置${workspace}/app/,這里指向的是項(xiàng)目使用的build.gradle 文件目錄责循。如果build.gradle 文件就在項(xiàng)目根目錄糟港,則不用填寫。
Post build task院仿,增加APK 簽名命令秸抚,jarsigner -verbose -keystore keystore地址 -signedjar 簽名后的文件名 -digestalg SHA1 -sigalg MD5withRSA 未簽名的安裝包地址 keystore的alias -storepass keystore的密碼
3. 配置中的問題
Jenkins構(gòu)建Android 出現(xiàn)/Users/Shared/Jenkins/.android/analytics.settings(No such file or directory)
解決:創(chuàng)建.android 目錄
SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable
解決:項(xiàng)目中缺少local.properties文件,主動(dòng)創(chuàng)建歹垫,填寫內(nèi)容sdk.dir=“sdk目錄”
Jenkins A problem occurred configuring project‘:app’. > The SDK directory‘/User/用戶/Library/Android/sdk' does not exist
解決:將改目錄的權(quán)限全部設(shè)置成了777
六剥汤、寫在最后
目前只是實(shí)現(xiàn)了簡單的基礎(chǔ)功能,發(fā)現(xiàn)坑確實(shí)不少排惨,但不得不說Jenkins 的日志真的很詳細(xì)吭敢,定位問題很方便。以上就是Jenkins 的一些經(jīng)驗(yàn)暮芭,特此記錄總結(jié)一下鹿驼。
參考鏈接
阮一峰 http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html
七、補(bǔ)充匯總
在新復(fù)制一個(gè)帶有“Git Parameter”插件的項(xiàng)目后辕宏,點(diǎn)擊“Build with Parameters” 時(shí)畜晰,選擇分支的選擇框內(nèi)提示“null Please look at the log”。
解決:由于在Jenkins workspace 目錄下沒有任何相關(guān)的代碼瑞筐,只需要直接進(jìn)行構(gòu)建凄鼻,拉取一次遠(yuǎn)程代碼到本地,再次點(diǎn)擊就會(huì)正常顯示分支信息了聚假。?
在配置iOS 靜態(tài)代碼掃描時(shí)块蚌,使用sonar-objective-c-plugin-0.5.0-SNAPSHOT.jar 插件進(jìn)行掃描,該插件版本與sonarQube 系統(tǒng)版本相關(guān)魔策,需要注意匈子。目前遺留問題是OC 的掃描規(guī)則太少,掃描結(jié)果只能掃出壞味道闯袒,Bug 和漏洞都無法掃到虎敦。配置文件增加了如下配置也沒有效果:
sonar.objectivec.oclint.report=oclint.xml
sonar.objectivec.oclint.reportPath=sonar-reports/oclint.xml