背景
一大早剛到公司沒多久,測(cè)試妹妹小韓跑過來:“老王,麻煩給我發(fā)一份xxx項(xiàng)目的最新安裝包唄?”
老王:“啥,昨天不是發(fā)你一個(gè)了嗎?”
小韓:“我要回歸下昨天已解決的bug,所以~”
于是,老王蹭蹭蹭打開IDE,N分鐘后一個(gè)安裝包通過QQ扔給了小韓。五分鐘后,小韓又跑過來了
小韓:“昨天你關(guān)閉的xxx bug好像沒解決吧,我操作給你看下~”
老王放下手中的山東煎餅,盯著小韓的操作看了一遍。
老王:“不科學(xué)哇,我昨天肯定解決了,你裝的是我剛發(fā)給你的嗎?”
小韓:“肯定是啊,我剛卸載了重新按裝的。。?!?/p>
老王:“難道是接口出問題了?你等下,我調(diào)試下。。。”
老王:“fuck,我用的正式環(huán)境的接口。。。稍等下,我一會(huì)兒再給你一個(gè)?!?/p>
N分鐘之后,測(cè)試小韓終于告訴老王昨天的那個(gè)bug沒問題了~
然后,小韓又跑去找iOS開發(fā)小李去了。。。此處省略500字~
反思
上面這個(gè)小故事,相信在不少公司都會(huì)存在。在測(cè)試階段,測(cè)試人員在不斷測(cè)試和回歸的過程中,會(huì)和開發(fā)人員溝通,期間可能會(huì)發(fā)布N個(gè)安裝包。
一般情況下,都是開發(fā)直接打包,然后發(fā)給測(cè)試人員。測(cè)試人員此時(shí)處于一個(gè)被動(dòng)地位,只能被動(dòng)的接受開發(fā)給的安裝包,然后去做相關(guān)測(cè)試。
另外,打包對(duì)于開發(fā)來講,可能覺得沒啥技術(shù)含量的事情,夾雜著情緒去做事情遲早也會(huì)出紕漏。
Jenkins
Jenkins是一個(gè)持續(xù)集成工具,它可以在設(shè)定的某個(gè)時(shí)間點(diǎn)(或者代碼有更新等情況)自動(dòng)去構(gòu)建安裝包,同時(shí)可以將安裝包上傳到第三方平臺(tái),比如:Bugly、蒲公英,這樣測(cè)試人員可以通過微信、QQ掃一掃直接安裝(Bugly的鏈接可以直接在微信內(nèi)打開,這是我選擇它的原因)。
當(dāng)然,如果你需要,也可以將構(gòu)建的結(jié)果(成功、失?。?,通過Email發(fā)送給相關(guān)人員,以便及時(shí)發(fā)現(xiàn)問題。
那么下面我們講解如何使用Jenkins構(gòu)建Android和iOS安裝包,并自動(dòng)上傳Bugly平臺(tái)吧~
軟件環(huán)境
- Mac OS X EI Capitan
- Jenkins 2.19.3
- Tomcat
- AndroidStudio & Gradle等Android開發(fā)環(huán)境
- Xcode & 企業(yè)證書
Jenkins安裝
打開Jenkins官網(wǎng),選擇“Download Jenkins”

選擇左側(cè)的“LTS Release”相對(duì)穩(wěn)定的版本,我們看到Jenkins提供了很多平臺(tái)的支持。
我是Mac環(huán)境,一般很多人都會(huì)去選擇Mac OS X,直接選擇這個(gè)可以省去Tomcat的安裝。但經(jīng)過我反復(fù)的實(shí)踐,選擇安裝包安裝的話,會(huì)生成一個(gè)Jenkins用戶,后續(xù)的工作空間會(huì)在這個(gè)用戶下,我遇到了各種文件夾權(quán)限問題,如果你去授予了讀寫權(quán)限,又會(huì)遇到Jenkins打不開的問題了~
所以,后來我直接放棄了,雖然網(wǎng)上有各種辦法,可能他們的版本比較舊。最后,受到高人指點(diǎn),我直接下載了.war文件,知道的朋友應(yīng)該明白,這個(gè)文件是直接放在Tomcat下webapps下,然后你就可以使用了,它的權(quán)限就是當(dāng)前用戶,所以就不存在問題了~
所以下載好.war文件之后,我們就開始安裝Tomcat吧。
Tomcat安裝
下載地址:http://tomcat.apache.org/download-70.cgi

選擇zip壓縮文件,下載完成后解壓縮到你的目錄,我放在
/Users/hiphonezhu/Desktop/D/software/apache-tomcat-8.5.8,
然后,把上面一步下載好的Jenkins.war放到apache-tomcat-8.5.8/webapps目錄下。
運(yùn)行Jenkins
命令行進(jìn)入Tomcat安裝目錄bin文件夾下,執(zhí)行如下命令:
$ cd /Users/hiphonezhu/Desktop/D/software/apache-tomcat-8.5.8/bin
$ startup.sh

打開瀏覽器,輸入http://localhost:8080/, 看到這個(gè)頁面表示Tomcat啟動(dòng)成功了

點(diǎn)擊“Manager Apps”,會(huì)提示輸入用戶名和密碼,Tomcat默認(rèn)是沒有用戶名和密碼的,那怎么辦呢?
我們點(diǎn)擊取消,會(huì)出現(xiàn)這個(gè)頁面:

它提示我們?cè)?code>conf/tomcat-users.xml文件中可以配置用戶,打開文件,在最后加入用戶:

重新啟動(dòng)Tomcat:
$ cd /Users/hiphonezhu/Desktop/D/software/apache-tomcat-8.5.8/bin
$ shutdown.sh
$ startup.sh
再次點(diǎn)擊“Manager Apps”,輸入用戶名和密碼,進(jìn)入Tomcat管理界面:

如果你剛剛下載了
Jenkins.war并放到了apache-tomcat-8.5.8/webapps目錄下,此時(shí)會(huì)看到/jenkins這個(gè)應(yīng)用,如上圖紅色區(qū)域,點(diǎn)擊我們就打開Jenkins了。
安裝Jenkins插件
初次打開Jenkins會(huì)提示你輸入密碼,按照提示找到文件并打開,然后填入密碼即可,這里不貼圖了。
然后會(huì)提示你安裝插件,我們首先選擇推薦安裝推薦的插件。經(jīng)過漫長(zhǎng)的等待,我們終于進(jìn)去Jenkins管理界面了

選擇“Manager Jenkins”,進(jìn)入設(shè)置界面

選擇“Manage Plugins”進(jìn)入插件管理界面

我們額外需要安裝的插件有:
- Git
- Gradle
- Xcode
因?yàn)槲业拇a托管在自建的gitblit上,所以源碼管理工具選擇了Git。如果你的代碼放在Github上,還需安裝GitHub插件。
當(dāng)然,如果你使用SVN,那么還需安裝SVN相關(guān)插件,這里不做更多介紹。
新增構(gòu)建項(xiàng)目(通用)
回到Jenkins主頁,點(diǎn)擊“New Item”

輸入項(xiàng)目名稱,點(diǎn)擊“OK”,進(jìn)入配置界面

選擇“Source Code Management”,設(shè)置Git的地址ssh://zhuhfxxxxxxxxx,選擇認(rèn)證方式“Credentials”,點(diǎn)擊“Add”

我們選擇“SSH Username with private key”認(rèn)證方式,“Username”隨意填寫,只是Jenkins的存儲(chǔ)的用戶而已。
“Private Key”就是“SSH Key”,首先你要在本地生成一對(duì)“私鑰”和“公鑰”,然后把公鑰填到你的源碼管理庫里面去,這里的key填寫的是私鑰,不熟悉的朋友可以參考這篇文章:http://jingyan.baidu.com/article/a65957f4f0acc624e67f9bc1.html
設(shè)置成功后,選擇你剛剛填寫的用戶,如果認(rèn)證成功,則沒有提示,如果失敗下圖紅色區(qū)域會(huì)出現(xiàn)紅色錯(cuò)誤提示(寫本篇文章的時(shí)候,嘗試填寫錯(cuò)誤的居然不提示了,我發(fā)誓一開始我輸錯(cuò)了確實(shí)提示了~):

設(shè)置構(gòu)建條件

經(jīng)常用到的是以下兩個(gè):
Build periodically:周期進(jìn)行項(xiàng)目構(gòu)建(它不care源碼是否發(fā)生變化)。
Poll SCM:定時(shí)檢查源碼變更(根據(jù)SCM軟件的版本號(hào)),如果有更新就checkout最新code下來,然后執(zhí)行構(gòu)建動(dòng)作。
參數(shù)配置參考:
http://blog.csdn.net/xueyingqi/article/details/53216506
http://blog.csdn.net/yezicjj/article/details/52763700
通用的設(shè)置介紹完了,下面我們介紹Android和iOS不同的構(gòu)建參數(shù)設(shè)置。
Android構(gòu)建

Build選擇“Add build step”,因?yàn)锳ndroid使用Gradle打包的,所以我們選擇“Invoke Gradle script”。

正常情況下,只需要設(shè)置Tasks的參數(shù)。
Tasks的參數(shù)其實(shí)就是./gradlew xxx后面的參數(shù),比如我們填寫的assembleDebug,最終執(zhí)行的命令就是:
$ ./gradlew assembleDebug
表示最終打包出來的是Debug版本,這個(gè)和你在AndroidStudio中使用命令行打包是一個(gè)道理,我們可以使用
$ ./gradlew tasks
來查看你的項(xiàng)目可以執(zhí)行的任務(wù)

如果你的項(xiàng)目在命令行使用
$ ./gradlew assembleDebug
$ ./gradlew assembleRelease
或者其他命令(多個(gè)productFlavors)可以正常打包,那么Jenkins也是可以正常打包的。
這里需要說明的是,如果你需要打Release包,那么你的app/build.gradle文件中需要有簽名的配置:

配置完成后,點(diǎn)擊“Save”按鈕,回到你新建的項(xiàng)目。主動(dòng)構(gòu)建,點(diǎn)擊“Build Now”

在“Build History”中:
- 正在構(gòu)建的會(huì)顯示當(dāng)前構(gòu)建的進(jìn)度;
- 如果最后顯示藍(lán)色的表示構(gòu)建成功;
- 紅色表示構(gòu)建失??;
- 灰色表示構(gòu)建被終止,可能是用戶主動(dòng)點(diǎn)擊了“x”號(hào)。
選擇某一次構(gòu)建記錄,點(diǎn)擊“Console Output”,可以查看構(gòu)建的過程

成功情況,最后你會(huì)看到“BUILD SUCCESSFUL”字樣

最終apk的輸出目錄,和我們用AS開發(fā)一致,在
app/build/outputs/apk文件夾中:

Android的構(gòu)建,我們暫且到此,自動(dòng)上傳至Bugly平臺(tái)因?yàn)锳ndroid和iOS基本是類似的,所以會(huì)在文章最后統(tǒng)一講解。
下面我們來看下iOS的構(gòu)建步驟吧~
iOS構(gòu)建

Build選擇“Add build step”,選擇“Xcode”

這里有一點(diǎn)需要說明,因?yàn)闀?huì)影響到下面的配置。
以前我們?cè)谑褂玫谌綆斓臅r(shí)候,一般都是手動(dòng)下載到本地,然后加入到項(xiàng)目中。
現(xiàn)在很多項(xiàng)目都是用CocoaPods來管理第三方庫,這個(gè)和Android的Gradle非常類似,可以方便的安裝和升級(jí)使用第三方庫。
不使用CocoaPods,你的項(xiàng)目文件是xxx.xcodeproj,使用之后我們要通過xxx.xcworkspace來打開項(xiàng)目,這個(gè)非常重要,直接影響了我們接下來的配置。
如果你沒使用CocoaPods,那么Target這一項(xiàng),需要填寫你項(xiàng)目的Target,也就是下圖紅色區(qū)域的文字:

如果你使用了CocoaPods,那么這一項(xiàng)請(qǐng)留空,我們會(huì)在后面的scheme中填寫。
記?。簍arget和project一起使用,scheme和workspace配套使用,更多信息請(qǐng)查看workspace, project, target, scheme 解析。
我們繼續(xù),點(diǎn)擊“General build settings”中的“Settings...”按鈕,展開更多選項(xiàng):

- 我們將“Clean before build?”打鉤,build之前清理一下,總歸保險(xiǎn)一點(diǎn),有時(shí)候清理下,問題就沒了~
- Configuration有兩個(gè)值,“Debug”和“Release”,這個(gè)和Xcode “Edit Scheme”中的“Build Configuration”的值一致:


Debug和Release最多的用途,還是用于測(cè)試環(huán)境和正式環(huán)境不同的配置,比如常用的接口API的地址:

它與發(fā)布AppStore或者第三方平臺(tái)內(nèi)測(cè),沒有太多直接的關(guān)系。
ipa命令規(guī)則:

“Pack application and build .ipa?”,選擇打鉤,表示需要生成ipa文件。
- .ipa filename pattern,ipa文件的命名規(guī)則,如果不填寫默認(rèn)規(guī)則是:target-version-build,例如xxx-1.0.0-2.ipa。
你可以使用 ${VERSION} 、${BUILD_DATE} (yyyy.MM.dd)等系統(tǒng)的值來組合最終的名稱,也可以像紅色區(qū)域一樣,寫一個(gè)固定的名稱。
注意:這里不需要填寫.ipa后綴,Jenkins會(huì)自動(dòng)幫我們加上的。
- Output directory,建議不清楚的不要填寫,它表示ipa輸出目錄,是一個(gè)相對(duì)路徑,相對(duì)于CONFIGURATION_BUILD_DIR這個(gè)默認(rèn)的Build目錄或者你修改之后的Build目錄;
- Manifest Plist URL,打ipa包的時(shí)候可以直接生成plist文件,它的plist的url填寫成你的服務(wù)的地址,這個(gè)地址加上文件名就組成了可下載ipa包的https服務(wù)地址url。這個(gè)plist url中jenkins會(huì)自動(dòng)后面加上ipa文件名。
如果你用的自己的HTTPS服務(wù)器,來提供Ad Hoc或者In-House類型的ipa包發(fā)布,那么這里可以填寫你的服務(wù)器地址(現(xiàn)在要權(quán)威機(jī)構(gòu)頒發(fā)的證書才能使用,自建的https無法訪問)。
因?yàn)槲覀兪褂胋ugly作為分發(fā)平臺(tái),所以這里就不配置了,有興趣的自行搜索下~
Code signing & OS X Keychain options

- Change bundle ID?,用于動(dòng)態(tài)修改bundle ID,你需要指定新的bundle ID和plist文件的路徑。一般情況不用修改,有時(shí)候測(cè)試包和正式包需要共存,這里可以修改下;
-
Code Signing Identity,用于簽名的證書名稱,如果開發(fā)或者發(fā)布證書不是你創(chuàng)建的,讓創(chuàng)建者導(dǎo)出p12和mobileprovision文件給你,安裝p12之后,打開鑰匙串,把證書的名字復(fù)制填入即可
Paste_Image.png
這里涉及到iOS簽名證書的制作和生成,不是本文討論的重點(diǎn),不懂的同學(xué)可以參考文章最后的鏈接。
- Sign IPA at build time,表示對(duì)編譯的時(shí)候?qū)PA包簽名,不打勾的話執(zhí)行xcrun命令的時(shí)候,不會(huì)加上--sign 參數(shù),這據(jù)說是Xcode的一個(gè)bug~
- Embedded Profile,這個(gè)是填寫mobileprovision描述文件的完整路徑。
Code Signing Identity和Embedded Profile這兩個(gè)空都可以不填,這樣會(huì)使用Xcode中的配置,如下圖:

Unlock Keychain

IPA簽名的時(shí)候,需要你的Mac電腦當(dāng)前登錄的用戶授予權(quán)限。保守起見,建議打鉤;并在“Keychain password”中,輸入Mac電腦當(dāng)前用戶登錄的密碼。(測(cè)試下來,使用war包方式,此項(xiàng)不勾選也是ok的~)
Advanced Xcode build options

- Xcode Schema File,如果你使用workspace而不是project此項(xiàng)必填,與target類似,填寫你需要構(gòu)建的schema;
- Xcode Workspace File,.xcworkspace文件的路徑,$WORKSPACE表示的是當(dāng)前項(xiàng)目的路徑,"/"后面就是.xcworkspace后綴的文件名,注意:這里不需要填寫后綴;
- Build output directory,
系統(tǒng)默認(rèn)的Build目錄是CONFIGURATION_BUILD_DIR,我們上文提到的ipa包的輸出目錄,其實(shí)就是相對(duì)于這個(gè)目錄的路徑;建議填寫,比如我們填寫的$WORKSPACE/jenkins-build,上文ipa的“Output directory”填寫ipa,那么最終編譯輸出的文件和ipa包的目錄結(jié)構(gòu)如下:

點(diǎn)擊“Save”,保存我們的配置,我們來嘗試構(gòu)建一下。
選擇某一次構(gòu)建記錄,點(diǎn)擊“Console Output”,查看構(gòu)建的過程:

紅色區(qū)域可以看到,ipa成功打包出來了,路徑和我們上面一張圖的目錄結(jié)構(gòu)一致。
至此,iOS的配置也結(jié)束了。下面我們重點(diǎn)講解下,如何上傳「apk&ipa」到第三方分發(fā)平臺(tái)Bugly~
上傳Bugly
- 打開Bugly官網(wǎng),注冊(cè)完成后,新建一個(gè)項(xiàng)目:
Bugly
填寫完基本信息后,選擇平臺(tái),然后保存。
注意:Android和iOS不能用同一個(gè)產(chǎn)品,否則下文執(zhí)行上傳命令,即使參數(shù)正確,也會(huì)提示“文件上傳成功,但版本創(chuàng)建失?。 ?/p>
-
選擇第一步創(chuàng)建的產(chǎn)品,打開“產(chǎn)品設(shè)置”頁面:
產(chǎn)品設(shè)置
我們要使用App ID 和 App Key這兩個(gè)參數(shù)。
-
打開之前在Jenkins創(chuàng)建的項(xiàng)目,選擇“Configure”來修改配置項(xiàng):
選擇Build,“Add build step”新增一個(gè)腳本“Execute shell”
Execute shell
輸入腳本
Shell
具體如下:cd $WORKSPACE/jenkins-build/ipa curl —-insecure -F "file=@xxx.ipa" -F "app_id=xxx" -F "pid=2" -F "title=xxx" -F "description=xxx" https://api.bugly.qq.com/beta/apiv1/exp?app_key=xxxcd $WORKSPACE/jenkins-build/ipa,表示進(jìn)入ipa輸出文件夾;
curl xxx,curl是一個(gè)命令,百度百科解釋如下:
curl是利用URL語法在命令行方式下工作的開源文件傳輸工具。它被廣泛應(yīng)用在Unix、多種Linux發(fā)行版中,并且有DOS和Win32、Win64下的移植版本。
具體的參數(shù)的解釋:

更多參數(shù)可以參考:Bugly官方文檔
-
上傳成功之后,我們?cè)俅未蜷_“Console Output”查看構(gòu)建日志:
Paste_Image.png
可以看到已經(jīng)成功上傳到Bugly了,
內(nèi)測(cè)分發(fā)
點(diǎn)擊“下載”安裝包,或者打開“預(yù)覽”界面,通過微信、QQ掃一掃來安裝
掃一掃
相信,寫到這里,測(cè)試妹子小韓一定很開心的笑了,以后不需要再去找“隔壁老王”了。。。
也許你跟著本文的步驟,還是會(huì)出現(xiàn)各種問題,你的環(huán)境或者配置錯(cuò)誤都可能是引起的原因。有問題的同學(xué)可以先搜索下,一般都能找到解決辦法,如果還是不能解決,可以給我留言~
參考文章:
Jenkins:
http://www.tuicool.com/articles/7Z3aYna
http://blog.csdn.net/wyb199026/article/details/52225345
http://blog.csdn.net/youtk21ai/article/details/48719807
iOS打包:
http://www.cnblogs.com/zengshuilin/p/5771401.html
http://www.cnblogs.com/tangyuanby2/p/5848230.html
http://www.cnblogs.com/wangbinios/p/5709386.html
http://blog.csdn.net/he_jiabin/article/details/49275191







