最近一段時間在負責我們游戲項目的客戶端的版本發布,這一環節目前很多都需要手動操著。每當發布一個新的安裝包一個下午的時間就沒了。我們目前只有一個平臺下的android和ios版本, 相對來說平臺還比較少但是隨著項目的推進后面肯定不止這一個平臺,按照這個效率到時肯定會讓人崩潰。于是自己開始思考如何優化這個流程。我們的項目使用的開發引擎是unity ,它可以再不啟動的前提下進行指令運行,基于這樣一個特點,可以通過腳本整合整個打包過程。在unity中制作一個靜態的c#函數輔助打包,這個靜態函數主要你用到Unity 提供的API是PlayerSettings 和 BuildPipeline。
PlayerSettings
這個類提供了關于平臺的一些配置具體可參考官網的:https://docs.unity3d.com/ScriptReference/PlayerSettings.html?下面是一些比較常用的配置
android 和 ios 通用部分?
PlayerSettings.bundleVersion ? ? 用于顯示的版本設置
PlayerSettings.productNam ? ? ? ?用于顯示的軟件名稱
PlayerSettings.bundleIdentifier ? 安裝包的ID
android 特有部分
PlayerSettings.Android.bundleVersionCode ? android迭代版本號,每更新一個包這數值都增加
PlayerSettings.Android.keystoreName ? ? ? ? ? keystore的路徑
PlayerSettings.Android.keyaliasName ? ? ? ? ? keystore 別名
PlayerSettings.keyaliasPass ? ? ? ? ? ? ? ? ? ? ? ? ?keystore 密碼
PlayerSettings.keystorePass ? ? ? ? ? ? ? ? ? ? ? ? ?keystore 密碼
ios?特有部分
PlayerSettings.iOS.buildNumber ? ? ? ? ? ? ? ? ? ?ios迭代版本號,每更新一個包這數值都增加
PlayerSettings.iOS.applicationDisplayName ?應用的顯示名稱
PlayerSettings.iOS.appleDeveloperTeamID ? 團隊id 這里是用到打包時簽名需要用到可以在https://developer.apple.com/account/#/membership看到 如下圖:
在指令運行unity的時候可以傳入一些參數,調用的靜態方法里何獲取這個些傳入的參數方式如下:
string[]args=System.Environment.GetCommandLineArgs();
通過如下方式可以查看所有的傳入參數
for(inti=0;i
Debug.Log("Args-"+i+""+args[i]);
}
BuildPipeline.BuildPlayer?
具體使用可以參考:https://docs.unity3d.com/ScriptReference/BuildPipeline.html android 可以直接導出apk,ios 需要先導出xcode在用xcodebuild命令進行打包,xcodebuild具體使用方式后面介紹 最后整個unity部分的運行指令方式如下:
/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -projectPath {UnityProjectPath} ?-executeMethod {staticMethod} -logFile {logFilePath} -quit otherParameter
其中上面指令的一些參數是:
UnityProjectPath ? ?unity的工程路徑。
staticMethod? ? ? ? ? 需要調用的靜態方法 如: AutomationHelp.BuildApk 就是類AutomationHelp 里面的靜態方法 BuildApk 。
logFilePath ? ? ? ? ? ?是日志文件保存路徑這里的日志是運行過程中的日志輸出包含腳本里面的Debug.Log 輸出。
在導出ipa安裝包過程中,通過Unity指令導出Xcode工程后 需要通過xcodebuild 指令進行ipa導出他需要兩個步驟:
1.生成 archive?
指令是:xcodebuild archive -project {projectName}.xcodeproj -scheme {projectName} -configuration Release -archivePath? {archivePath} PROVISIONING_PROFILE={exportProvisioningProfile}
2.導出ipa
指令是:xcodebuild -exportArchive -exportFormat IPA -archivePath {archivePath} -exportPath {ipaPath}? -exportProvisioningProfile {exportProvisioningProfile}
上面兩條指令的具體參數是:
projectName ?? ??? ??? ??? ?? ? ??? ??? ??工程名具體可以看 xcode 里面的?.xcodeproj 類型文件名稱
archivePath??? ??? ??? ??? ??? ??? ??? ??? ?archive 的存儲路徑
exportProvisioningProfile ??? ??? ???exportProvisioningProfile 文件路徑具體值可以看https://developer.apple.com/account/ios/profile/production如圖2
ipaPath?? ??? ??? ??? ??? ??? ??? ??? ??? ?? ? 導出ipa的路徑
圖2中的 name:字段即為exportProvisioningProfile的值
了解上面的主要技術點之后我接下來就是考慮如何構建這個腳本系統。我對PHP和shell 腳本進行了一些對比之后做了一個結論:是php 對于文本數據和邏輯處理比較方便,shell 對執行指令系統比較簡單,而便邏輯相和數據處理很弱。再對php 與 shell,shell 與 unity的腳本系統交互方式了解后,對整個腳本系統有了一個大概的規劃,我決定將php作為總的調度腳本 ,shell 作為具體的功能模塊的指令集合。最后根據我們項目的特點規劃出了如下一些功能模塊:
1.svn 庫自動化,svn版本管理中提交新添加的多個文件的指令可以使用:svn add `svn status . | grep "^?" | awk '{print $2}'`?
2.ftp自動化 這一塊lftp代替了ftp因為在使用ftp過程中非常麻煩。lftp具體可以參考:http://man.linuxde.net/lftp
3.包裹unity指令
4.本地文件同步系統 主要用到的是rsync指令系統用這個系統的主要目的是他可以過濾掉我不需要同步的文件夾,通過如下指令:sync -avp --exclude-from={excludePath} ? {formPath} ?{toPath}。
excludePath ?? ??? ?是過濾配置文件,里面是過濾的文件名稱或者是文件夾用換行隔開
formPath ?? ??? ? ? ??需要同步的文件路徑
toPath ??? ??? ??? ?? ? 同步到的目標路徑
有關sync命令具體可參考:http://man.linuxde.net/rsync
5.遠程登錄模塊 主要借助expect 工具實現自動登錄
php 調度shell模塊過程中如果有出現某個模塊沒有正常執行 php調度腳本需要終止執行,這里面涉及到 shell 錯誤捕獲以及php錯誤處理機制
shell 錯誤捕獲可以通過語句執行后執行如下語句:
if test $? != 0??; then
?? ?echo $FAIL
? ? exit 1
fi
上的語句主要的作用是來判斷與他相鄰的上一條語句是否成功執行,其中?$FAIL 為一個自定義的標識字段 ,如果在php調用shell模塊后的返回值有這個值,這代表shell 執行不成功這時候php將終止執行或者回滾。以上就是自動化打包系統中的主要技術點。?
所有的技術都不是一成不變,記錄下來以便于回顧。