使用 Jenkins 配置 iOS 持續整合踩坑實錄
我將之前寫的文章逐步遷移到掘金上,也是希望更多人能看到我寫的文章,共同學習。
Jenkins 是一款使用 Java 開發的持續整合工具,下面將介紹如何使用 Jenkins 來進行iOS的持續整合。坑都用粗體標明瞭。
安裝坑
在安裝 Jenkins 之前,首先要安裝 JDK,這裡需要注意 JDK 的版本,必須為1.8 ,過高或者過低均不行。
推薦使用 brew 來安裝 Jenkins。
brew install jenkins 複製程式碼
配置坑
第一步
安裝完畢後,直接在命令列中輸入以下命令:
jenkins 複製程式碼
在這裡需要注意,Jenkins 預設埠是8080 ,如果該埠被佔用,可以使用以下命令切換埠:
jenkins -httpPort 9090 複製程式碼
然後,就可以在瀏覽器中輸入localhost:9090
來進入 Jenkins。在起始頁面會使用一個起始口令來讓你解鎖它,這個口令可以在命令列中,或者在其指定的目錄下可以找到該口令。輸入完畢後,會讓你建立一個賬戶,按照提示來完成操作就好。
第二步
建立完畢後,首先要去繫結你SSH金鑰,方法如下:
Jenkins -> Credentials -> global -> add Credentials 複製程式碼
第三步
繫結完畢後,開始安裝以下外掛:
- Keychains and Provisioning Profiles Management
對的,只有一個,不要使用 Xcode 外掛來進行 iOS 配置,因為 XCode 8 以後,通過 Archive 生成 ipa 需要包括一個 ExportOption.Plist 檔案,這個檔案在該外掛中並不會提供,所以通過指令碼來進行配置,而不是通過 XCode 外掛來配置。
安裝完畢該外掛後,直接通過網上各種渠道的資訊來對該外掛進行配置,配置該外掛基本上不會有太大問題,下面給出 keychains 和 provision 在系統中的路徑。
keychain: /Users/zcating/Library/Keychains provision: /Users/zcating/Library/MobileDevice/Provisioning Profiles 複製程式碼
需要注意的是,上傳的時候,login.keychain-db 會被標記為不合法的檔案,login.keychain 實際上跟 login.keychain-db 是一樣的,只需要複製一份,然後更改 login.keychain-db 為login.keychain,然後就可以上傳了。
第四步
完成上傳後就可以開始構建了,構建步驟如下:
1. 新建專案,選擇自由風格。 2. 勾選 keychain 和 provision。 3. 新增 Git 配置。 4. 增加構建步驟,選擇 Execute shell。 複製程式碼
然後新增以下指令碼:
#需要自定義引數 xcode_project_path="/path/to/your/xcode/project" export_path="/path/to/your/export/path" ipa_name="ipa-name" provision="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # build method,可以輸入以下選項: app-store, ad-hoc, enterprise, development build_method="enterprise" # bundle_id 需要跟專案中的一致 bundle_id="com.yourCompany.yourApp" bundle_name="provision_name" # 簽名型別,可以選擇以下型別: "iOS Developer", "iOS Distribution" sign_cer="iOS Distribution" # 就是你們團隊證書中的使用者名稱 team_id="XXXXXXXXXX" #自定義完畢 export_option_path="$xcode_project_path/ExportOptions.plist" # 寫 ExportOption.plist 檔案 echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> <plist version=\"1.0\"> <dict> <key>compileBitcode</key> <false/> <key>method</key> <string>$build_method</string> <key>provisioningProfiles</key> <dict> <key>$bundle_id</key> <string>$bundle_name</string> </dict> <key>signingCertificate</key> <string>$sign_cer</string> <key>signingStyle</key> <string>manual</string> <key>stripSwiftSymbols</key> <true/> <key>teamID</key> <string>$team_id</string> <key>thinning</key> <string><none></string> </dict> </plist>" > $export_option_path; xcodebuild archive \ -archivePath "$xcode_project_path/build/${ipa_name}.xcarchive" \ -project $xcode_project \ -sdk iphoneos \ -scheme $scheme \ -configuration $build_configuration \ CODE_SIGN_IDENTITY="鑰匙串中的簽名的名稱" \ PROVISIONING_PROFILE=$provision xcodebuild -exportArchive \ -archivePath "$xcode_project_path/build/${ipa_name}.xcarchive" \ -exportPath $export_path \ -exportOptionsPlist $export_option_path \ -allowProvisioningUpdates \ CODE_SIGN_IDENTITY="鑰匙串中的簽名的名稱" \ PROVISIONING_PROFILE=$provision mv ${export_path}/*.ipa ${export_path}/ipa_name.ipa 複製程式碼
需要注意,XCode 專案需要關閉自動簽名配置。
到這裡,只要在 XCode 開啟該專案沒有報錯,並且可以構建,那麼就沒有任何問題了。
Unity 特別篇
使用 Jenkins 來構建 Unity,有以下幾點需要注意的地方。
關閉自動簽名,設定provision。
在 Assets 目錄下新建以下目錄和檔案 /Assets/editor/ProcessBuild.cs,並且在cs檔案中新增以下程式碼。
using System.Collections; using System.IO; using UnityEditor; using UnityEngine; using System.Collections.Generic; using System; class ProjectBuild : Editor{ //在這裡找出當前工程所有的場景檔案. static string[] GetBuildScenes() { List<string> names = new List<string>(); foreach(EditorBuildSettingsScene e in EditorBuildSettings.scenes) { if(e==null) continue; if(e.path == "Dont_Add" || e.path == "post") if(e.enabled) names.Add(e.path); } return names.ToArray(); } //得到專案的名稱 public static string projectName { get { foreach(string arg in System.Environment.GetCommandLineArgs()) { if(arg.StartsWith("project")) { return arg.Split("-"[0])[1]; } } return "test"; } } //shell指令碼直接呼叫這個靜態方法 static void BuildForIPhone() { PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.iOS, "USE_SHARE"); // 構建xcode工程的核心方法了, // 引數1 需要打包的所有場景 // 引數2 需要打包的名字 // 引數3 打包平臺 // 引數4 編譯選項 BuildPipeline.BuildPlayer(GetBuildScenes(), "ios-build", BuildTarget.iOS, BuildOptions.None); } } 複製程式碼
使用以下命令進行自動化構建。
project_dir="" /Applications/Unity/Unity.app/Contents/MacOS/Unity \ -batchmode \ -projectPath $project_dir \ -executeMethod ProjectBuild.BuildForIPhone \ -ios \ -quit \ -logFile $project_dir/BuildXCodeProject.log 複製程式碼
這樣就會在你指定的目錄下生成 XCode 專案。
結語
我使用了 Jenkins 生成 iOS 最終的 ipa,感受到了如絲般順滑的構建流程。生成過程只需一鍵,一鍵就能上傳Testflight,fir.im 或者蒲公英。感覺以後打包真的會方便很多很多倍,省去了各種複雜的步驟。只是在構建 Jenkins 的時候,遇到了很多問題,最終的解決方案還是決定寫一個 Shell 指令碼,這樣就省去了很多外掛的配置問題。