使用 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 指令碼,這樣就省去了很多外掛的配置問題。