UnityのiOSアプリをアーカイブまでJenkinsで自動化した話
Qiitaより転載
2017/1/16 初投稿
最近Resharperを使いたいが為に開発環境をMacからWindowsに変えた結果iOSのビルドが非常に面倒になった。なのでJenkinsを導入してWindows側でビルドからアーカイブまでほぼ全て自動化出来るように環境を整えてみた。
流れとしては
- WindowsでGit Push
- Mac側でGit Pull
- Unityビルド(このときにちょっとXcodeのplistとか書き換える)
- Xcodeアーカイブ
- Git commit + push
Jenkinsの導入
調べてください★
Jenkinsにジョブの登録
今回はプラグインを使わず素の状態でジョブを作成します。
まずGitから最新の状態のプロジェクトを読み込み
PROJECT_PATH="{プロジェクトの場所}"
cd "${PROJECT_PATH}"
git pull
でUnityのビルド。
/Applications/Unity/Unity.app/Contents/MacOS/Unity \
-batchmode \
-quit \
-logFile ./build.log \
-projectPath "${PROJECT_PATH}" \
-executeMethod BuildClass.BuildiOS
でXcodeでアーカイブ
# 全部のルート
ROOT_FOLDER="{ルート}"
# ビルドが入ってるフォルダ
BUILD_FOLDER="{ビルドが入ってるフォルダ名}"
# 最新のビルドを取得
cd "${ROOT_FOLDER}/${BUILD_FOLDER}"
builds=()
for file in *; do
builds=("${file}" "${builds[@]}")
done
# Scheme
TARGET="Unity-iPhone"
# アーカイブ先
OUTPUT_DIR_ARCHIVE="${ROOT_FOLDER}/build_archive/"
# プロビジョニングプロファイル
PROFILE_PATH="{プロビジョニングプロファイルの場所}"
if [ ! -d ${OUTPUT_DIR_ARCHIVE} ]; then
mkdir "${OUTPUT_DIR_ARCHIVE}"
fi
xcodebuild -project "${ROOT_FOLDER}/${BUILD_FOLDER}/${builds[0]}/${TARGET}.xcodeproj" \
-scheme "${TARGET}" \
archive \
-archivePath "${OUTPUT_DIR_ARCHIVE}/archive" \
DEVELOPMENT_TEAM={自分のチームの10桁のコード}
これで指定した場所にarchive.xcarchive
っていうファイルが出来るので、それをダブルクリックして後はアップロードするだけ。
DEVELOPMENT_TEAMやPROFILE_PATHの値は以下参照:
[Xcode] CIなどを使用するときに必要な値を確認する方法
最後にUnityで行った変更点のPush
cd "${PROJECT_PATH}"
git commit -a -m "iOSのビルドに成功しました。"
git push
Unity側
Unityのビルドのところに書いた-executeMethod BuildClass.BuildiOS
←これは自分で作成する。
場所はAssets/Editor/BuildClass.cs
using UnityEditor;
using UnityEngine;
public class BuildClass
{
/// <summary>
/// iOSのビルドを行います
/// </summary>
public static void BuildiOS()
{
// バージョンのインクリメント
var versionString = PlayerSettings.bundleVersion;
Debug.Log("Version got: " + versionString);
var verstionStrings = versionString.Split('.');
int lastVersion;
if(!int.TryParse(verstionStrings[2], out lastVersion)){
Debug.Log("[Error!] Failed to increment version.");
return;
}
var newVersion = lastVersion + 1;
var newVersionStrings = new [] {verstionStrings[0], verstionStrings[1], newVersion.ToString()};
var newVersionString = string.Join(".", newVersionStrings);
PlayerSettings.bundleVersion = newVersionString;
Debug.Log("New Version set: " + PlayerSettings.bundleVersion);
// Bundleのインクリメント
var buildString = PlayerSettings.iOS.buildNumber;
Debug.Log("Build number got: " + buildString);
int buildNum;
if(!int.TryParse( buildString, out buildNum)) {
Debug.Log("[Error!] Failed to increment build version.");
return;
}
PlayerSettings.iOS.buildNumber = (++buildNum).ToString();
Debug.Log("New Build number set: " + PlayerSettings.iOS.buildNumber);
// ビルドフォルダの名前
var buildFolderName = "alpha_" + newVersionString;
string[] sceneList = {
"./Assets/Scene/Main.unity",
"./Assets/Scene/Menu.unity"
};
string errorMessage = BuildPipeline.BuildPlayer(
sceneList,
"{出力先}" + buildFolderName,
BuildTarget.iOS,
BuildOptions.None
);
if(!string.IsNullOrEmpty(errorMessage)){
Debug.LogError("[Error!]" + errorMessage);
} else {
Debug.Log("[Success!]");
}
}
}
めんどくさいので中身の解説は省略。とりあえずバージョンのインクリメントとかそういうのをここで自動化できる。ただ僕の場合これだけだとTestFlightで内容を更新する際に審査が必要になるので、バージョンを一定にしたりとplistの編集が必要だったので、PostProcessBuildも書いてる。
これの場所はAssets/Editor/XcodeSettingsPostProcesser.cs
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.iOS.Xcode;
using UnityEditor.Callbacks;
using System.Collections;
public class XcodeSettingsPostProcesser
{
[PostProcessBuildAttribute (0)]
public static void OnPostprocessBuild (BuildTarget buildTarget, string pathToBuiltProject)
{
// iOS以外のプラットフォームは処理を行わない
if (buildTarget != BuildTarget.iOS) return;
// Plist変更
string plistpath = Path.Combine(pathToBuiltProject, "Info.plist");
PlistDocument plist = new PlistDocument();
plist.ReadFromFile(plistpath);
// iOS10対策
plist.root.SetString("NSCameraUsageDescription", "Unity/Admob Dependency");
// Testflightの審査を端折る為
plist.root.SetString("CFBundleShortVersionString", "0.0.5");
// plist反映
plist.WriteToFile(plistpath);
}
}
以上
Unity側で少し内容を書き換えてるので更新の前にコンフリクトを解消しないと行けなかったりしてまだ面倒なところはあるけど、とりあえずビルドさせて風呂入って、戻ったら実機テストしてOKだったらアップロード、みたいな感じでだいぶ楽になった。
Discussion