Unity Cloud BuildでUnityのビルドやバイナリ配布を自動化しよう
お金を払ってProライセンスを使っている人に朗報です。Unityがベータ版として提供する Unity - Cloud Build を使えば、いわゆる継続的インテグレーション(CI)が簡単に行えます。
弊社では「レポジトリの特定のブランチを監視させ、変更があったらiOS版とAndroid版をビルドして配布」という用途のために使用してします。
そうです、TestFlightのような配布機能まで備えており大変便利です。ProユーザーはJenkinsやTestFlightを個別にセットアップする必要がなくなります。
下準備
iOS用ビルドやAndroid用ビルドをするためにはいくつか下準備が必要となります。
identifierの用意
Bundle ID的なものを用意しておく必要があります。iOS Developer CenterでApp IDを作ったりしてiOS向け、Android向けの設定を終えます。あとで必要になるのでビルド用のProvisioning等を用意しておきましょう。つまるところ、手元でビルドするのに必要な準備と大差はないと思います。
手作業による変更が要らない状態に
Xcodeプロジェクトの書き出し後に手作業による設定変更をしている人もいるかもしれませんが、Cloud Buildではそのようなことはできません。プロジェクトの書き出しからビルドまでを完全に自動で通す必要があります。
そこで前回のエントリーUnityでのXcode設定をUnityEditorのスクリプトだけで自動化する につながります。Xcode のプロジェクトを変更する必要がある人はこちらを参考に色々頑張ってみましょう。
Cloud Buildでプロジェクトの設定
Unity - Cloud Build ←まずここからProライセンスを支払っているアカウントでログインし、上部ナビゲーションバーからAdd New
を選択します。
するとこのような画面になるので、監視したいリポジトリのURLを入力しましょう。弊社ではbitbucketを利用しているのでgit@bitbucket:account/repository.git
のようになりました。
次にSSHキーを設定します。この画面で詳しく案内してくれるので特に問題はないでしょう。
どのブランチを監視するのかを決めます。ここで指定したブランチにあるコードを使ってビルドしてくれるようになります。
これまでに設定した内容の確認と、ビルドするプラットフォームを選びます。iOSとAndroidを有効にし、必要であればAuto-build
にもチェックしておきましょう。Auto-build
が有効になっていると、ブランチに対する変更を検知して自動的にビルド→配布を行ってくれます。
予め用意しておいたBundle IDやProvisioning Profile、p12などを入力、アップロードします。
長かったですね。これで自動ビルドのための準備ができました。
次のステップに進むと最初のビルドがスタートします。ビルド完了後は配布URL付きのメールが来ます。
運用例
弊社ではCloud Buildが監視するためだけのブランチを作成しており、区切りのいいタイミングでメインブランチからプルリクエストを作成してビルド用ブランチを更新するようにしています。BitbucketのWebインターフェースでプルリクエストを作ってマージするだけで自動的に実行可能なバイナリを作ってくれるわけです。
もっというとこのプルリクエスト作成→マージの部分はChatOpsな感じで動くようにしています。細かい話は後日書くかもしれませんが、予め登録しておいた命令をbot hogehoge
のような感じでSlackに投稿すると、あとはBotが勝手にマージしてくれるようにしています。
「そろそろメンバー全員に見せておくか」と思ったらSlackにちょっと書くだけで配布まで完了できるわけです。革命的ですね。
UnityでのXcode設定をUnityEditorのスクリプトだけで自動化する
Unityが出力したiOS用プロジェクトの手動編集をなんとかしたいと考えていたら、同じような人がやはり多いようでいろいろな方法がブログエントリで紹介されていました。
- UnityでXcodeのプロジェクト設定を自動化したい(c#でPostProcessBuildを書く場合) - Qiita
- A-Liaison BLOG: Unity の PostprocessBuildPlayer を使って Weak Framework を追加する方法
調べた感じではCodeEditor-for-Unity
やxcodeproj
というRubyのgemを使う方法が多くみられました。前者のライブラリは最近はメンテされていないようですし、後者の場合Rubyが必要になるということで広く導入しにくい(関係者全員にxcodeproj gem入れろとはいえない)ので別の方法がない限りできないかなーと思っていたら、なんとBitbucketにリポジトリを発見しました。
Unity-Technologies / XcodeAPI — Bitbucket https://bitbucket.org/Unity-Technologies/xcodeapi
Unity-Technologiesというアカウント名から察するに公式のツールだと考えて良さそうです。
このコードを使ってXcodeプロジェクト出力後にフレームワークを追加したり設定を変更するような処理を書いてみようと思います。
なお他の手段でできることがこのXcodeAPI
ではまだできないということがあるかもしれないのでその点は注意してください。
導入
準備はほとんど要らなくて、リポジトリからダウンロードしたファイルをUnityのプロジェクト内、Assets
以下の好きなところに突っ込んでおけば大丈夫です。
ビルド後の処理を書く
Assets/Editor
あたりのディレクトリに、例えばModifyXcodeProject.cs
という感じのスクリプトを配置します。
using UnityEngine; using UnityEditor; using UnityEditor.Callbacks; using UnityEditor.iOS.Xcode; // ←さっきいれたXcodeAPI using System.Collections; using System.IO; public class XcodeProjectMod : MonoBehaviour { // ちょっとしたユーティリティ関数(http://goo.gl/fzYig8を参考) internal static void CopyAndReplaceDirectory(string srcPath, string dstPath) { if (Directory.Exists(dstPath)) Directory.Delete(dstPath); if (File.Exists(dstPath)) File.Delete(dstPath); Directory.CreateDirectory(dstPath); foreach (var file in Directory.GetFiles(srcPath)) File.Copy(file, Path.Combine(dstPath, Path.GetFileName(file))); foreach (var dir in Directory.GetDirectories(srcPath)) CopyAndReplaceDirectory(dir, Path.Combine(dstPath, Path.GetFileName(dir))); } [PostProcessBuild] public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iPhone) { string projPath = PBXProject.GetPBXProjectPath(path); PBXProject proj = new PBXProject(); proj.ReadFromString(File.ReadAllText(projPath)); string target = proj.TargetGuidByName("Unity-iPhone"); // システムのフレームワークを追加 proj.AddFrameworkToProject(target, "AssetsLibrary.framework", false); // 自前のフレームワークを追加 CopyAndReplaceDirectory("Assets/Lib/mylib.framework", Path.Combine(path, "Frameworks/mylib.framework")); proj.AddFileToBuild(target, proj.AddFile("Frameworks/mylib.framework", "Frameworks/mylib.framework", PBXSourceTree.Source)); // ファイルを追加 var fileName = "my_file.xml"; var filePath = Path.Combine("Assets/Lib", fileName); File.Copy(filePath, Path.Combine(path, fileName)); proj.AddFileToBuild(target, proj.AddFile(fileName, fileName, PBXSourceTree.Source)); // Yosemiteでipaが書き出せないエラーに対応するための設定 proj.SetBuildProperty(target, "CODE_SIGN_RESOURCE_RULES_PATH", "$(SDKROOT)/ResourceRules.plist"); // フレームワークの検索パスを設定・追加 proj.SetBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks"); // 書き出し File.WriteAllText(projPath, proj.WriteToString()); } } }
iOSプロジェクト書き出し後に[PostProcessBuild]
属性を付けたメソッドが呼ばれます。そこでXcodeプロジェクトの本体である.pbxproj
を編集するためのコードを書けばOKです。
上のコードでは
これらのことをやっています。
このコードもXcodeAPIもソース管理に入れてしまえば誰でも使うことができるので他の方法よりも良いかもしれません。