お手伝い先でHoloLensでのCI/CDを構築、運用して1年を超えましたが、日々安定してビルドができています。
先日素敵な記事も出てて良い感じです。*1
Azure DevOpsでHoloLensアプリをビルド(MS-hosted編) | NEXTSCAPE with MR
HoloLensのCI環境について、必要な要件、CI環境の選択、Azure DevOpsのMicrosoft-hostedとSelf-hostedの選択を見てみます。
- ビルド環境の選択(OS)
- ビルドの選択(コンテナ)
- Windows のビルドサービス
- ビルド環境としての AzureDevOps Pipeline
- Microsoft-hosted Agent の懸念
ビルド環境の選択(OS)
HoloLensに限定してビルドについて検討すると、UWPビルド = Windows SDKが鍵になります。 現状のWindows SDKは、Windowsでのみインストールが可能であり、結果としてビルド環境もWindowsに限定されます。
UnityはUnity 2019においても動作環境として、Windows Serverを想定していません。(以前サポートにも問い合わせた)
OS:Windows 7 SP1 以降、8、10(64 ビットバージョンのみ)、macOS 10.12 以降 サーバー版の Windows、OS X についてはテストされていません。

Windows Server 2012 R2でUnity起動すると即クラッシュします、対策にはDesktop Heapを広げる必要がありました。 幸いにもWindows Server 2016/Windows Server 2019 では問題なく起動し、ビルドも可能です。*2
今HoloLensビルドを行うなら、Windows Server 2019でビルドが可能です。(やってる)
ビルドの選択(コンテナ)
現状のWindows SDK + Unityをコンテナでビルドするのは難しい感触です。
Windows Containerでコンテナイメージが公開されているようにも見えますがuwpという名はトラップです。中身は、Portal Library (Target UWP 10.0) でありUWPビルドはできません。
coderobin/windows-sdk-10.1 - Docker Hub
UWPのセルフビルドでわんちゃんいけそうですが、ここにUnityが入ると更にサイズが.... 。
https://github.com/coderobin/windows-container/tree/master/windowsservercore/windows-sdk-10.1
コンテナビルドができても、Windows Containerだと旨味が少ないので悩ましいですが..... コンテナだと楽なのも事実なのでなんともです。
なお、HoloLensはすでにIL2CPPビルドがデファクトまったなしなので、C# とVC++ のビルドが必要です。また、vcxproj/csprojはSDK形式ではありません。このため、dotnetではなくmsbuildが必要です。*3
Windows のビルドサービス
Windowsでのビルドを行うとき選択肢はいくつか考えられます。
- Azure DevOps
- AppVeyor
- Jenkins v2
- Drone
- Team City
Managedな環境でWindowsビルドを提供しているのはAzure DevOpsとAppVeyorです。 Self-hosted Agent (自分でWindowsホストにエージェントをインストールして利用する)を提供しているのは、Azure DevOps、AppVeyor(Enterprise)、Jenkins v2、Drone、Team Cityです。
Team Cityを除きどれもYAMLでのビルドを定義できるのでそこは別にいいでしょう。
Open Sourceではビルドをコスト、並列数、時間制約で考えると、Managedな環境であるAzure DevOpsが最も強い選択肢になるのではないでしょうか?*4 AppVeyorは癖があることと、Spin upの遅さから選択しにくいものがあります。
個人的にはCircleCIが好きなので見てみると、Windowビルド対応予定があるように書いてあります。

リポジトリもあり、内容を見てみるとPerformance planでトライアルできるようです。
Windows 向けOrb もあり、使えそうな感触があります。
orbs: win: sandbox/windows-tools@dev:preview
基本的なビルド機能である、caching, workspaces, SSH into the build がサポートされている一方で、Previewの現在、デフォルトでインストールされているのはごく一部のソフトウェアなので注意です。
We install Git, Chocolatey, and 7zip. We don’t install any other dependencies at the moment.
ビルド環境としての AzureDevOps Pipeline
Azure DevOpsのビルド環境には、「おまかせできるMicrosoft-hosted」と「自分で環境を自由に設定できるSelf-hosted」の2種類あります。
- Microsft-hosted Agent: Microsoft がhostして各種ソフトウェアもビルトインで入っている
- Self-hosted agent: ユーザーがWindows/macOS/Linuxのいずれかにインストールしてミドルウェアや環境を好きに構築したうえで動かす
両環境で一番大きく異なるのは、価格、パフォーマンス、実行環境のクリーンさ、ミドルウェアの管理です。
私自身パフォーマンスからSelf-hosted Agentを使う決断を下すことが多かったのですが、現在はHosted agentがいいです。(理由は後述)
この選択に関しては、他のAzure DevOps ユーザーも記事をあげているので参考にするといいでしょう。
Too bad! You still need a private build agent when using VSTS – Henry Been
では、Self-hosted AgentとMicrosoft-hosted Agentののどちらを、どのような観点で選択するといいのか考えてみます。
価格面の違い
価格表があるので見てみましょう。
- Microsoft-hosted Agent : 追加の並列ジョブごとに ¥4,480 (分数制限なし)
- Self-hosted Agent : 追加の並列ジョブごとに ¥1,680 (分数制限なし)

Hosted Agentが1並列ビルドに4480円というのはかなり高く感じます。*5
一方のSelf-hostedは1680円と安く見えるのに加え、MSDN のVisual Studio Enterpriseサブスクライバーはアカウント1つあたり1つの課金済みSelf-hosted Agentライセンスが付きます。*6 開発者一人ずつにMSDN サブスクリプションを会社で付与している場合、実質無料で開発者の数だけPrivate Agentを割り当てて並列ビルドをかけられるので、一見すると大きなメリットに見えます。
The free tier is one parallel job. In addition, you get one free parallel job for each Visual Studio Enterprise subscriber that is a member of your organization. You can get more using paid self-hosted parallel jobs.
実際にSelf-hosted Agentのコストを考えるときは動作するホストやストレージ料金を含めることになります。*7 よくあるケースとして、Self-hosted AgentをAzureVMを実行ホストとして実行することを基準に簡単に価格を考えましょう。*8
ビルドVMにCPUとメモリがほしいのでコスパがいいBシリーズの4 vCPU/16G RAMを採用します。
| インスタンス | VCPU | メモリ | 一時ストレージ | 従量課金制 |
|---|---|---|---|---|
| B4MS | 4 | 16 GiB | 32 GiB | ~¥19,131.84/月 |

Gitで大量のファイルを読み書きし、ビルドで大量のファイルリードがかかります。これが主なストレージ負荷になるため、CIには高I/Oに耐えられるプレミアムストレージが欲しくなるでしょう。

以上を踏まえて、MSDNでSelf-hosted Agentがついてくる環境で、VMとプレミアムストレージを256GB/512GB/1TBの組み合わせと、Hosted agentで (¥4480) で換算して考えてみます。
| VM | Storage | Self-hosted 合計 | Hostedの台数換算 |
|---|---|---|---|
| ¥19,131.84(VM) | ¥4,896.72(Storage 256GB) | ¥24028.56 | 5.3台 |
| ¥19,131.84(VM) | ¥9,430.40(Storage 512GB) | ¥28562.24 | 6.36台 |
| ¥19,131.84(VM) | ¥17,409.28(Storage 1TB) | ¥36541.12 | 8.1台 |
ビルドの数にもよりますが、1VMに載せられるエージェントの数は2-4台程度です。 このため社内マシンを使うなどの選択をしない限り 、Self-hostedは並列度との兼ね合いはかなり悪いものがあります。*9
ビルド環境の手間
ビルド環境はただビルドだけしたいので、手間がかかるのは嫌なものです。 手間をかけるメリットがあるときと、かけないのか判断が必要です。
この観点では、Microsoft-hosted Agentは一般的なビルド環境程度には楽です。
Microsoft-hosted Agent
ビルドエージェントが動作するホスト環境の管理が不要なため、手間が大きく軽減されます。 都度新しい環境でビルドされるので、ビルド環境のボリューム容量も気にする必要がありません。
逆にホストの管理ができないことに割り切れないと手間がかかるでしょう。 都度新しいホストが起動するため前回のジョブ実行状態を再利用できません。 Hosted Agentに入っていない、インストールに手間や時間のかかるミドルウェアを事前にインストールしておいてビルドのための時間を省略できません。 エージェントを選ぶことはできないので、エージェントに高スペック、高I/Oを期待できません。 ジョブごとにクリーンであることが面倒なポイントです。
Self-hosted Agent
ビルドエージェントが動作するホスト環境は管理できることから、うまく使うとビルドを高速化できます。 前回のJon結果やCheckOut結果を再利用して、Gitやdockerのキャッシュをかけておくこともできます。 Unityのようなインストールに時間のかかるミドルウェアをインストールしておくことも可能です。 ミルドウェアの特定のバージョンで問題があったときに、バージョンを固定するのも難しいでしょう。
うまく使う、の度合いが半端なくホストの管理が必要で、手間がかかります。 まずSelf-hosted Agentのインストールが必要です。 ビルドするホストのボリューム容量の管理が必要です。1ホストで複数エージェントを動かす場合、ホストごとにワークスペースを持つためn倍(n=ホストの数)の容量を使います。 ホスト管理の手間があるのは手間の多くを占めます。
VMとストレージが更に増え、それぞれにインストールすることを考えるとなかなか面倒なことがわかります。
Microsoft-hosted Agent と Self-hosted Agent の選択
ビルドの頻度にもよりますが、HoloLens開発でSelf-hosted AgentかMicrosoft-hosted Agentを選ぶ場合、今ならMicrosoft-hosted Agentがいいでしょう。
一見Microsoft-hosted Agedntはスペックが低かったり、1並列ビルドが高かったりしますが、手間がかからない、純粋に並列度で考えられるのは大きなメリットといえます。
IL2CPPが当然になった今、HoloLensの1ビルドにかかる時間は早くても15min、普通に20min~30min程度かかります。 UnityのCacheを持った状態での起動高速化(Library) も、スクリプトの変更に弱かったりするので厳しいものがあります。
総合的にみて、割り切ってMicrosoft-hosted Agentがいい選択肢になるでしょう。
Microsoft-hosted Agent の懸念
Microsoft-hosted Agentは、UWPビルドができる稀なManaged CI環境ですが、Windows SDKが怖い部分でもあります。
MRTKv2は、Windows SDK 18362が必要ですが、これがHosted Agentのビルドで利用できるようになったのは6/25です。
Sprint 153で追加対応が来てから自分たちのAgentにくるまで約2週間かかっています。多くの場合この程度かかることから、Azure DevOpsにおいては2週間程度は新機能の利用まで見ておく必要があります。*10
View linked GitHub activity from the Kanban board - Sprint 153 Update | Microsoft Docs
そういった意味で、Visual Studioはともかくとして*11、MRTKが新Windows SDKに依存した実装を入れたときにCI環境のWindows SDKがなくて悲しい思いをすることはありえます。
とりあえず今のMRTKv2で使ってる最新Windows SDK来たし、まぁしばらくは大丈夫でしょう。
*1:手離れされているので安心して見ていられます。
*2:以前はWindows Serverが使えない縛りからWindows 10をAzureのDev利用などで持って来る必要がありました
*3:dotnet SDKで完結する今どきの.NET環境ではない
*4:無料、10並列、時間無制限
*5:そもそもパイプラインで課金という価値観が、CircleCIの新料金プランで崩れていてつらさがあります
*6:企業でMSDNサブスクリプションを配布しており、このサブスクリプションをビルドに利用したい場合、MSDNサブスクライブ画面で会社のAzureアカウントと紐づけてもらうことで割り当てられます。
*7:人的コストを除外します
*8:EC2に置き換えても結構です
*9:VMやストレージ環境
*10:UIの変更を除く
*11:これは比較的すぐにくるので