準(zhǔn)備工作
Jenkins的安裝
Jenkins依賴于Java環(huán)境,首先需安裝和配置Java環(huán)境(PS:在下載的時(shí)候注意選擇JDK,而非JRE)
1.使用brew安裝:
brew install jenkins
如果報(bào)錯(cuò) brew: command not found
掐禁,這是由于當(dāng)前環(huán)境沒有安裝homebrew
安裝homebrew 允扇,代碼執(zhí)行:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安裝成功后威恼,請重新安裝brew install jenkins
安裝成功后商乎,瀏覽器會(huì)自動(dòng)打開Jenkins網(wǎng)頁服務(wù),如果沒有打開押逼,請?jiān)跒g覽器輸入 http://localhost:8080/习寸。如果不能打開 http://localhost:8080/ ,可能是Jenkins服務(wù)未開啟:
開啟Jenkins :
sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.plist
停用Jenkins :
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
如果報(bào)錯(cuò):/Library/LaunchDaemons/org.jenkins-ci.plist: No such file or directory
可以在命令行中開啟服務(wù):
jenkins
此時(shí)Jenkins會(huì)在命令行里打印相關(guān)的運(yùn)行日志胶惰,再在瀏覽器里輸入: http://localhost:8080/ 這種情況的話,如果關(guān)閉執(zhí)行 jenkins
命令的命令行窗口霞溪,Jenkins也會(huì)停止服務(wù)
Jenkins的配置
點(diǎn)擊系統(tǒng)管理->管理插件孵滞,在插件管理里面下載幾個(gè)比較有用的插件中捆,當(dāng)然可以根據(jù)自己的需求增減
1.插件的安裝
Xcode integration(用來配置打包參數(shù)的,需配置的參數(shù)和步驟較多坊饶,改用腳本打包)
Keychains and Provisioning Profiles Management(用來配置鑰匙串參數(shù)的泄伪,配合Xcode integration一同使用)
GitLab Plugin(用來關(guān)聯(lián)gitlab倉庫)
Gitlab Hook Plugin(用來配置hookurl,使gitlab在獲得push 等事件的時(shí)候能喚起Jenkins)
fir-plugin(用來上傳到fir的插件幼东,易報(bào)錯(cuò)臂容,已改用腳本上傳)
Email Extension Plugin(用來在構(gòu)建后發(fā)送郵件給測試的,smtp配置易出錯(cuò)根蟹,已改用腳步發(fā)送)
Changelog Environment Plugin(用來獲取commits日志的脓杉,獲取插件請?jiān)L問 https://twiceyuan.com/2017/02/21/jenkins-changelog/)
BearyChat Plugin(用來在構(gòu)建后發(fā)送通知給bearchat的,bearchat中選擇Jenkins機(jī)器人即可接受消息)
2.插件的使用
gitlab plugin
倉庫地址
驗(yàn)證方式(用戶名密碼或ssh)
分支(想要構(gòu)建的分支名稱简逮,圖中傳了一個(gè)自定義的參數(shù))
gitlab hook
- 在gitlab中設(shè)置-webhook中加入該URL球散,Jenkins即可在獲取push/merge事件后開始構(gòu)建
changelog plugin
- 勾選該選項(xiàng)后,即可獲取${SCM_CHANGELOG} commit日志參數(shù)散庶,傳入腳步
bearchat plugin
- 勾選該選項(xiàng)后蕉堰,即可在構(gòu)建完成后通知給bearchat中的Jenkins機(jī)器人
項(xiàng)目設(shè)置
在Jenkins中,構(gòu)建項(xiàng)目以Job的形式存在悲龟,因此需要針對(duì)每個(gè)項(xiàng)目創(chuàng)建一個(gè)Job屋讶。有時(shí)候,一個(gè)項(xiàng)目中可能有多個(gè)分支同時(shí)在進(jìn)行開發(fā)须教,為了分別進(jìn)行構(gòu)建皿渗,也可以針對(duì)每個(gè)分支創(chuàng)建一個(gè)Job。
創(chuàng)建Job的方式有多種轻腺,本次只需要?jiǎng)?chuàng)建Freestyle project
類型的即可乐疆。
Main page
-> New Item
-> Freestyle project
對(duì)于一個(gè)持續(xù)集成打包平臺(tái),每次打包都由4步組成:觸發(fā)構(gòu)建贬养、拉取代碼挤土、執(zhí)行構(gòu)建、構(gòu)建后處理误算。對(duì)應(yīng)的仰美,在每個(gè)Job中也對(duì)應(yīng)了這幾項(xiàng)的配置。
1.Jenkins主頁儿礼,點(diǎn)擊左上角的新建按鈕開始新建一個(gè)Item
2.輸入Item的名稱筒占,選擇構(gòu)建一個(gè)自由風(fēng)格的軟件項(xiàng)目
3.這里可以設(shè)置包的保留天數(shù)還有最大個(gè)數(shù)
4.配置參數(shù)化內(nèi)容,如圖,可以用${name}在shell命令中取出對(duì)應(yīng)的值
5.在源碼管理里面選擇git蜘犁,然后配置git信息
要對(duì)項(xiàng)目進(jìn)行構(gòu)建翰苫,配置項(xiàng)目的代碼倉庫是必不可少的。由于當(dāng)前我們的項(xiàng)目托管在Gitlab私有倉庫中,因此在此需要對(duì)Git進(jìn)行配置奏窑。
在【Source Code Management】
配置欄目下导披,如果之前Gitlab plugin安裝成功,則會(huì)出現(xiàn)Git選項(xiàng)埃唯。
配置Git代碼倉庫時(shí)撩匕,有三項(xiàng)是必須配置的:倉庫URL地址(Repository URL)、倉庫權(quán)限校驗(yàn)方式(Credentials)墨叛,以及當(dāng)前Job需要構(gòu)建的代碼分支(Branches to build)止毕。
在配置Repository URL時(shí),選擇HTTPS URL或SSH URL均可漠趁。不過需要注意的是扁凛,Credentials要和Repository URL對(duì)應(yīng),也就是說:
如果Repository URL是HTTPS URL形式的闯传,那么Credentials就要采用Gitlab用戶名密碼的校驗(yàn)方式谨朝;如果Repository URL是SSH URL形式的,那么就需要先在Jenkins所在的服務(wù)器上創(chuàng)建一個(gè)SSH秘鑰對(duì)甥绿,并將公鑰添加到GitHub的SSH keys中字币,然后在填寫Credentials時(shí),選擇SSH Username with private key的校驗(yàn)方式共缕,填入Gitlab Username洗出、SSH私鑰、以及創(chuàng)建SSH秘鑰對(duì)時(shí)設(shè)置的Passphrase图谷。
在配置Branches to build時(shí)翩活,可以采用多種形式,包括分支名稱(branchName)蜓萄、tagName隅茎、commitId等澄峰。其中分支名稱的形式用的最多嫉沽,例如,若是構(gòu)建master分支俏竞,則填寫master绸硕,若是構(gòu)建develop分支,則填寫develop魂毁。
除了以上關(guān)于Git的必填配置項(xiàng)玻佩,有時(shí)根據(jù)項(xiàng)目的實(shí)際情況,可能還需要對(duì)Jenkins的默認(rèn)配置項(xiàng)進(jìn)行修改席楚。比較常見的一種情況就是對(duì)clone的配置進(jìn)行修改咬崔。
在Jenkins的默認(rèn)配置中,clone代碼時(shí)會(huì)拉取所有歷史版本的代碼,而且默認(rèn)的超時(shí)時(shí)限只有10分鐘垮斯。這就造成在某些項(xiàng)目中郎仆,由于代碼量本身就比較大,歷史版本也比較多兜蠕,再加上網(wǎng)絡(luò)環(huán)境不是特別好扰肌,Jenkins根本沒法在10分鐘之內(nèi)拉取完所有代碼,超時(shí)后任務(wù)就會(huì)被自動(dòng)終止了(錯(cuò)誤狀態(tài)碼143)熊杨。
這種問題的解決方式也很簡單曙旭,無非就是兩種思路,要么少拉取點(diǎn)代碼(不獲取歷史版本)晶府,要么提高超時(shí)時(shí)限桂躏。對(duì)應(yīng)的配置在Advanced clone behaviours
中:
Shallow clone
:勾選后不獲取歷史版本;
Timeout (in minutes) for clone and fetch operation
:配置后覆蓋默認(rèn)的超時(shí)時(shí)限郊霎。
6.配置構(gòu)建觸發(fā)器
代碼倉庫配置好了沼头,意味著Jenkins具有了訪問GitHub代碼倉庫的權(quán)限,可以成功地拉取代碼书劝。
那Jenkins什么時(shí)候執(zhí)行構(gòu)建呢进倍?
這就需要配置構(gòu)建觸發(fā)策略,即構(gòu)建觸發(fā)器购对,配置項(xiàng)位于【Build Triggers】欄目猾昆。
觸發(fā)器支持多種類型,常用的有:
- 定期進(jìn)行構(gòu)建(Build periodically)
- 根據(jù)提交進(jìn)行構(gòu)建(Build when a change is pushed to GitHub)
- 定期檢測代碼更新骡苞,如有更新則進(jìn)行構(gòu)建(Poll SCM)
構(gòu)建觸發(fā)器的選擇為復(fù)合選項(xiàng)垂蜗,若選擇多種類型,則任一類型滿足構(gòu)建條件時(shí)就會(huì)執(zhí)行構(gòu)建工作解幽。如果所有類型都不選擇贴见,則該Jenkins Job不執(zhí)行自動(dòng)構(gòu)建,但可通過手動(dòng)點(diǎn)擊【Build Now】觸發(fā)構(gòu)建躲株。
關(guān)于定時(shí)器(Schedule)的格式片部,簡述如下:
分鐘(0-59) 小時(shí)(0-23) 日期(1-31) 月(1-12) 周幾(0-7,0和7都是周日)
7.配置構(gòu)建方式
常用的構(gòu)建方式是根據(jù)構(gòu)建對(duì)象的具體類型,安裝對(duì)應(yīng)的插件霜定,然后采用相應(yīng)的構(gòu)建方式档悠。例如,若是構(gòu)建iOS應(yīng)用望浩,安裝Xcode integration
插件之后辖所,就可以選擇Xcode,然后選擇Xcode進(jìn)行構(gòu)建磨德。
該種方式的優(yōu)勢是操作簡單缘回,UI可視化,在場景不復(fù)雜的情況下可以快速滿足需求。不過缺點(diǎn)就是依賴于插件已有的功能酥宴,如果場景較復(fù)雜時(shí)可能單個(gè)插件還無法滿足需求揩环,需要再安裝其它插件。而且幅虑,有些插件可能還存在一些問題丰滑,例如對(duì)某些操作系統(tǒng)版本或XCode版本兼容不佳,出現(xiàn)問題時(shí)我們就會(huì)比較被動(dòng)倒庵。
我個(gè)人更傾向于另外一種方式褒墨,就是自己編寫打包腳本,在腳本中自定義實(shí)現(xiàn)所有的構(gòu)建功能擎宝,然后在Execute Shell
中執(zhí)行郁妈。這種方式的靈活度更高,各種場景的構(gòu)建需求都能滿足绍申,出現(xiàn)問題后也能自行快速修復(fù)噩咪。
另外,對(duì)于iOS應(yīng)用的構(gòu)建极阅,還有一個(gè)需要額外關(guān)注的點(diǎn)胃碾,就是開發(fā)者證書的配置。
如果是采用Xcode integration
插件進(jìn)行構(gòu)建筋搏,配置會(huì)比較復(fù)雜仆百,需要在Jenkins中導(dǎo)入開發(fā)證書,并填寫多個(gè)配置項(xiàng)奔脐。不過俄周,如果是采用打包腳本進(jìn)行構(gòu)建的話,情況就會(huì)簡單許多髓迎。只要在Jenkins所運(yùn)行的計(jì)算機(jī)中安裝好開發(fā)者證書峦朗,打包命令在Shell中能正常工作,那么在Jenkins中執(zhí)行打包腳本也不會(huì)有什么問題排龄。
8.至此波势,我們的Jenkins設(shè)置就全部完成了
點(diǎn)擊構(gòu)建,就會(huì)開始構(gòu)建項(xiàng)目了涣雕,構(gòu)建一次艰亮,各個(gè)顏色代表的意義如下:
如果構(gòu)建失敗了闭翩,可以去查看Console Output可以查看log日志:
關(guān)于iOS的構(gòu)建
對(duì)iOS源碼進(jìn)行構(gòu)建挣郭,目標(biāo)是要生成.ipa文件,即iOS應(yīng)用安裝包疗韵。
當(dāng)前兑障,構(gòu)建方式主要包括兩種:
xcodeuild:
- 源碼 -> .archive文件 -> .ipa文件
xcrun:(xcode8后已被淘汰)
- 源碼 -> .app文件 -> .ipa文件
這兩種方式的主要差異是生成的中間產(chǎn)物不同,對(duì)應(yīng)的,兩種構(gòu)建方式采用的命令也不同流译,我們只看xcodebuild這種.
源碼 -> .archive
# build archive file from source code
xcodebuild archive -workspace ${project_name}.xcworkspace \
-scheme ${scheme_name} \
-configuration ${build_configuration} \
-archivePath ${export_archive_path}
archive
:對(duì)編譯結(jié)果進(jìn)行歸檔逞怨,會(huì)生成一個(gè).xcarchive
的文件,位于-archivePath
指定的目錄中福澡。
需要注意的是叠赦,對(duì)模擬器類型的sdk無法使用archive命令.
.archive -> .ipa
# export ipa file from .archive
xcodebuild -exportArchive \
-archivePath ${export_archive_path} \
-exportPath ${export_ipa_path} \
-exportOptionsPlist ${ExportOptionsPlistPath}
參數(shù)說明
xcodebuild參數(shù):
- -workspace:需要打包的workspace,后面接的文件一定要是.xcworkspace結(jié)尾的革砸;
- -scheme:需要打包的Scheme除秀,一般與${project_name}相同;
- -configuration:需要打包的配置文件算利,我們一般在項(xiàng)目中添加多個(gè)配置册踩,適合不同的環(huán)境,Release/Debug效拭;
- -archivePath:.xcarchive文件的路徑暂吉;
- -exportPath:導(dǎo)出文件(.ipa)的路徑;
- -exportOptionsPlist:根據(jù)configuration對(duì)應(yīng)的plist文件缎患;
補(bǔ)充說明
1慕的、獲取Targets、Schemes挤渔、Configurations參數(shù)
在填寫target/workspace/scheme/configuration
等參數(shù)時(shí)业稼,如果不知道該怎么填寫,可以在項(xiàng)目根目錄下執(zhí)行xcodebuild -list
命令蚂蕴,它會(huì)列出當(dāng)前項(xiàng)目的所有可選參數(shù)低散。
Information about project "Store":
Targets:
Store
StoreCI
Build Configurations:
Debug
Release
If no build configuration is specified and -scheme is not passed then "Release" is used.
Schemes:
Store
StoreCI
2.清除緩存文件
在每次build之后,工程目錄下會(huì)遺留一些緩存文件骡楼,以便下次build時(shí)減少編譯時(shí)間熔号。然而,若因?yàn)楣こ膛渲缅e(cuò)誤等問題造成編譯失敗后鸟整,下次再編譯時(shí)就可能會(huì)受到緩存的影響引镊。
因此,在持續(xù)集成構(gòu)建腳本中篮条,比較好的做法是在每次build之前都清理一下上一次編譯遺留的緩存文件弟头。
xcodebuild clean -workspace ${project_name}.xcworkspace \
-scheme ${scheme_name} \
-configuration ${build_configuration}
3.處理Cocoapod依賴庫
若項(xiàng)目是采用Cocoapod管理項(xiàng)目依賴,每次拉取最新代碼后直接編譯可能會(huì)報(bào)錯(cuò)涉茧。這往往是因?yàn)槠渌赂铝艘蕾噹欤ㄐ略隽说谌綆旎蛏?jí)了某些庫)赴恨,而本地還采用之前的第三方庫進(jìn)行編譯,從而會(huì)出現(xiàn)依賴庫缺失或版本不匹配等問題伴栓。
應(yīng)對(duì)的做法是伦连,在每次build之前都更新一下Cocoapod雨饺。
# Update pod repository
pod repo update
# Install pod dependencies
pod install
# Install pod dependencies not update spec
pod install --verbose --no-repo-update
4.上傳FIR
fir publish ./xxx.ipa -T xxxxxx
5.提交AppStore(未完成)
/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool --validate-app -f ./xxx.ipa -u xxx -p xxx -t ios --output-format xml
/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool --upload-app -f ./xxx.ipa -u xxx -p xxx -t ios --output-format xml
6.發(fā)郵件
python sendEmail.py "日志" "用戶郵箱"
遇到的問題
Q1:Jenkins Xcode 證書設(shè)置錯(cuò)誤 Code Sign error: No matching codesigning identity found: No codesigning identities
A1:Jenkins 集成Xcode 項(xiàng)目的時(shí)候在證書上遇到了問題。實(shí)際上如果在本地的話惑淳。只要Xcode工程里選擇了項(xiàng)目就不需要重新設(shè)置證書了额港。jenkins會(huì)自動(dòng)找到這個(gè)證書,只要在build setting 里設(shè)置的是正常的歧焦。并且在xcode 里能正常編譯移斩。
Check dependencies
Code Sign error: No codesigning identities found: No codesigning identities (i.e. certificate and private key pairs) that match the provisioning profile specified in your build settings (“qingyunDeveloper”) were found.
如果遇到類似的錯(cuò)誤 解決辦法:
因?yàn)閖enkins運(yùn)行在Mac的守護(hù)進(jìn)程模式,只是認(rèn)為它是一個(gè)不同的用戶绢馍,所以不會(huì)有機(jī)會(huì)獲得鑰匙串或提供個(gè)人資料作為您登錄使用您的憑據(jù)叹哭,而我的證書是裝在“登錄”下的,這會(huì)導(dǎo)致代碼簽名有問題
解決辦法是首先打開keychain keys 找到apple 的開發(fā)者證書痕貌。然后復(fù)制风罩。 再選擇左邊的系統(tǒng)(system)把剛復(fù)制的證書放進(jìn)去。
如果這個(gè)還沒有解決舵稠。
接下來第二步:
找到你用戶下的Provisioning Profiles 文件超升。目錄為 /Users/xxx/Library/MobileDevice/Provisioning Profiles xxx表示你自己的用戶名
把這里面所有的證書復(fù)制到/Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profile 這個(gè)文件。
參考資料:
http://code-dojo.blogspot.co.uk/2012/09/fix-ios-code-signing-issue-when-using.html
Q2:打包iOS有pod的項(xiàng)目哺徊,shell執(zhí)行pod install時(shí)室琢,提示pod command not found
A2:需要在shell第一行加上 #bin/bash -l
就行了,所以最終是這樣:
#!/bin/bash -l
export LANG=en_US.UTF-8
pod install --verbose --no-repo-update
Q3:有pod的項(xiàng)目提示schema找不到
A3:需要用xcode打開一次.xcworkspace就好了落追,或者在shell pod install之后下加上 open x.xcworkspace
Q4:jenkins 命令 command not found
A4:由于jenkins是用jenkins用戶啟動(dòng)的盈滴,所以很多環(huán)境變量就沒有,導(dǎo)致很多命令起不來轿钠,所以需要把jenkins改為自己常用的用戶來啟動(dòng)巢钓。默認(rèn)jenkins的目錄是在/User/Share/Jenkins下的。這是安裝.pkg文件成功后自動(dòng)創(chuàng)建了jenkins用戶疗垛,下面我們開始切換到常用用戶下症汹。
1)我們先把jenkins停掉,執(zhí)行:
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
然后刷新瀏覽器贷腕,發(fā)現(xiàn)jenkins頁面打不開了背镇,說明成功停掉了
2)到Finder->application下找到j(luò)enkins/jenkins.war,雙擊啟動(dòng)泽裳。然后刷新瀏覽器瞒斩,發(fā)現(xiàn)又重新進(jìn)入了jenkins的配置過程,正常配置完涮总,返現(xiàn)jenkins根目錄變了胸囱,變成/User/當(dāng)前用戶/.jenkins/
Q5:jenkins打包的時(shí)候需要鑰匙串密碼
A5:這個(gè)密碼是本地登陸密碼,如果不行,就得用jenkins用戶的密碼,直接重置jenkins密碼妹卿。在命令行執(zhí)行
sudo passwd jenkins
可能要求先輸入當(dāng)前用戶密碼旺矾,然后就提示Changing password for jenkins.設(shè)置新密碼就行了.
Q6:在使用jenkins打包時(shí) 出現(xiàn)xcodebuild: error: The workspace named "XXXX" does not contain a scheme named “XXX"
A6:首先在項(xiàng)目根目錄中使用 xcodebuild -list 獲得schema名稱
然后在該schema中勾選shared選項(xiàng)
Q7:jenkins使用shell命令打IOS包報(bào)錯(cuò):user interaction is not allowed
A7:在編譯命令前加入以下命令:
security unlock-keychain -p "123456" ~/Library/Keychains/login.keychain
或者
echo "123456" | security unlock-keychain ~/Library/Keychains/login.keychain
[要把鑰匙串解鎖,并配置訪問鑰匙串的密碼即可]
Q8:在自動(dòng)化部署的時(shí)候,gitlab中的webhook無法訪問jenkins,報(bào)錯(cuò)execution expired
A8:暫時(shí)沒找到辦法解決,可能是架設(shè)gitlab的局域網(wǎng)網(wǎng)段和jenkins的網(wǎng)段不一致
Q9:不能打包adHuc/appstore包的問題
A9:下載描述文件(需要把extension的描述文件一起下下來) p12文件一起安裝
Q10:在打包時(shí)出現(xiàn)多語言包損壞的問題
A10:不要用cocoapods的beta版
Q11:打包腳本報(bào)錯(cuò)teamid不匹配
A11:Xcode近年來致力于自動(dòng)管理開發(fā)證書,每個(gè)大版本都會(huì)有修改(有方便的地方也有坑的地方)夺克。到了Xcode8箕宙,在target的General設(shè)置面板中直接新增了“Signing”,看得出來铺纽,Automatically manage signing
選項(xiàng)是蘋果推薦的簽名方式柬帕。如果恰巧不幸,你的證書里的App ID與Xcode中的bundle ID不符狡门,就應(yīng)該關(guān)閉該選項(xiàng)陷寝,手動(dòng)為某個(gè)configuration指定打包證書。不要忘記在腳本中-exportOptionsPlist指定的plist中配置對(duì)應(yīng)的teamID其馏。
總結(jié)
- 自動(dòng)打包是iOS開發(fā)中的一項(xiàng)基礎(chǔ)工作凤跑,作為自動(dòng)化工作的一小部分往往被應(yīng)用于CI系統(tǒng)。持續(xù)集成的內(nèi)容很多叛复,還有自動(dòng)化測試仔引、代碼靜態(tài)檢查、持續(xù)交付等內(nèi)容褐奥。這篇文章是概括了其中一些方面咖耘,我們要做的還有很多。
接下來要做什么
-
OCLint -- 做為一個(gè)靜態(tài)代碼分析工具撬码,我們引入 OCLint 的目的主要是為了提高我們的代碼質(zhì)量儿倒。通常我們提高代碼質(zhì)量的方式是通過 CodeReview,但是這個(gè)過程耗費(fèi)的人工和時(shí)間往往較大呜笑,所以我們想通過 OCLint 的一些規(guī)則夫否,讓機(jī)器幫我們完成一部分代碼質(zhì)量的檢測,從而提高我們的工作效率叫胁。
參考鏈接:
-
xcpretty -- 對(duì)xcodebuild的輸出進(jìn)行格式化
-
altool -- 命令行工具提交AppleStore
參考鏈接:
https://itunesconnect.apple.com/docs/UsingApplicationLoader.pdf -
Jenkins + Docker(適配規(guī)模較大慷吊,代碼提交頻繁(意味著構(gòu)建頻繁)