前回、Azure DevOpsでHoloLensのビルド環境を行うこと、Microsoft-hosted Agentが今ならいいということを書きました。
今回は、MRTKとMRTKv2をMicrosoft-hosted Agentで現実的にビルドすることを考えてみましょう。 内容としては、次の記事が近いです。
この記事では、MRTKv1とMRTKv2それぞれについてリポジトリとAzure Devops PipelineのYAMLを示しつつ、現実にビルドしていくことに必要なことをカバーします。
Unity のビルドエラーがわからない
Windows上でUnityのバッチビルドをしたときに困るのが、Unityビルドの経過、ログが標準出力に出ないことです。*1
結果Unity内部でどのようなエラーが起こってもエラーの詳細がわからないので、記事にあるUnityBuildTask@2
を使う方法は現実的じゃありません。*2
コンパイルエラー時に、どこでコンパイルエラー出たかわからないのは絶望です。
そのため、Unity Tools for Azure DevOps
でUnityビルドを行うのは厳しいものがあります。
- task: UnityBuildTask@2 displayName: 'Unity Build WindowsStoreApps' name: 'unityBuild' inputs: buildTarget: 'WindowsStoreApps' unityEditorsPathMode: 'unityHub' unityProjectPath: '$(unityProjectPath)' commandLineArgumentsMode: 'default'
代わりに「Unityビルド呼び出しつつlogファイルに吐いたログを読み込んで標準出力に吐く」ラッパーアプリケーションを用意する方法をよく採用されています。
https://chiepomme.gitbook.io/chienote/ci-cd/unity-build-log-to-stdoutchiepomme.gitbook.io
お手伝い先で必要にな使っていただいているのがUnityBuildRunner
です。*3
dotnet global toolとして公開してあるので、dotnet tool install -g UnityBuildRunner
でWindows/Mac問わずサクッとインストールできます。
使い方は単純です。Unityのバッチビルドは次のフォーマットです。
Unity.exe [args]
この引数をUnityBuildRunnerにそのまま渡せばokです。 加えてタイムアウトにも対応してあります。
UnityBuildRunner [-UnityPath|-unityPath|-u] [-timeout|-t 00:60:00] [-version] [-help] [args]
たとえば、MRTKv2でビルドするならこのように書けます。
UnityBuildRunner -UnityPath "C:\Program Files\Unity\Hub\Editor\2018.3.13f1\Editor\Unity.exe" -quit -batchmode -projectPath パス -buildTarget WSAPlayer -logfile Editor.log -executeMethod Microsoft.MixedReality.Toolkit.Build.Editor.UnityPlayerBuildTools.StartCommandLineBuild
Unityパスは環境変数から読むこともできるので次のようにも書けます。
set unityPath=C:\Program Files\Unity\Hub\Editor\2018.3.13f1\Editor\Unity.exe UnityBuildRunner -quit -batchmode -projectPath パス -buildTarget WSAPlayer -logfile Editor.log -executeMethod Microsoft.MixedReality.Toolkit.Build.Editor.UnityPlayerBuildTools.StartCommandLineBuild
MRTKv1 のビルドを行う
MRTKのビルドは、HoloToolkit.Unity.BuildDeployTools.BuildSLN
メソッドを使います。*4
MRTKv2を使ったビルドとYAML定義を含んだリポジトリです。
ビルドのYAML定義を見てみましょう。
途中のコメントを外すとsln一式がartifactsから取得できます。
# if you want to build locally # - task: PublishPipelineArtifact@0 # displayName: 'Publish Pipeline Artifact' # inputs: # artifactName: 'UWP_Sln' # targetPath: 'UWP'
ちなみにMRTKv1のシンプルなシーンをビルドしてみると、ビルドに30min、長い。
プロジェクト固有の情報を知らずビルドするコツとして、VSビルド時にslnファイルを指定するのではなくslnのあるフォルダを指定 + /
と書くことでslnビルドできます。/
がないとslnが見つからないので注意です。
MRTKv2 のビルドを行う
MRTKv2は、Windows SDK 18362が必要ですが、これがHosted Agentに来てビルドできるようになったのは6/25です。 Sprint 153で追加対応が来てから、自分たちのAgentにくるまで約2週間かかりました。
MRTKv2のビルドは、Microsoft.MixedReality.Toolkit.Build.Editor.UnityPlayerBuildTools.StartCommandLineBuild
メソッドを使います。
相変わらずDevelopmentビルドの指定ができないのはアレなのでラッパーを書くことになるでしょう。
MRTKv1を使ったビルドとYAML定義を含んだリポジトリです。
ビルド定義のYAMLは次のようになります。
途中のコメントを外すとsln一式がartifactsから取得できます。
# if you want to build locally #- task: PublishPipelineArtifact@0 # displayName: 'Publish Pipeline Artifact' # inputs: # artifactName: 'sln' # targetPath: 'Builds/WSAPlayer'
MRTKv2のサンプルシーンをビルドしてみると、ビルドに30min、長い。
プロジェクト固有の情報を知らずビルドするコツとして、VSビルド時にslnファイルを指定するのではなくslnのあるフォルダを指定
と書くことでslnビルドできます。先ほどと違い、/
で終わるとslnが見つからないので注意です。
学び
Unityのインストールにかかる時間
Microsft-hosted Agent にはUnityがインストールされていません。 そのためこのYAMLではUnityを都度インストールしています。
このUnityの準備にかかる時間をリードタイムとしてみると、10min程度かかります。 毎ビルドで10minかかるのはアレでもあり、その程度で済むなら許容できるケースも。
Output変数が定義されたタスクの変数はnameを指定することでとれるようになる
UnityGetProjectVersionTask@1で取得したUnityバージョンを変数に出力します。 これを使うことでUnityプロジェクトのバージョンを知ることなく、同じYAMLをどのUnityバージョンでも変わらず使えます。
さて、UIと違ってYAMLではreference variableの設定はサポートされていません。
しかしTASKで出力変数が設定されている場合は、name
をつけることで取得できます。
- task: DinomiteStudios.64e90d50-a9c0-11e8-a356-d3eab7857116.custom-unity-get-project-version-task.UnityGetProjectVersionTask@1 displayName: 'Unity Get Project Version' name: unitygetprojectversion
これで、後段のstepにおいて$(unitygetprojectversion.projectVersion)
で参照できます。
教えてもらって気づきました、これはむりげー。