Unity Cloud BuildでTestFlight, Google Play Console, DeployGateへのデプロイを網羅する

# 目次
[はじめに](#はじめに)
[DeployGate へのデプロイ](#deploygate-へのデプロイ)
[TestFlight へのデプロイ](#testflight-へのデプロイ)
[Google Play Console (内部テスト)へのデプロイ](#google-play-console-内部テストへのデプロイ)
[さいごに](#さいごに)
[参考記事](#参考記事)

# はじめに
みなさんどうもこんにちは。[プレティア・テクノロジーズ](https://corporate.pretiaar.com/ja/)でUnity Engineer をしているharuya_i と申します 🍵

この記事では、私が会社でおこなっているプロジェクトで「Unity Cloud Build を使ってCI/CD を整備したら、開発環境そこそこいい感じになった。やったー 😀」となった事例から、実際に私が何をやったか、どうやったか、をサクッとお話しできればと思っております。

### この記事を読んできっと得られること
```
1. TestFlight, Google Play Console, DeployGate へのアプリ配布環境が整う
2. 「へぇ〜、Unity Cloud Build も悪くないね」感 😀
```
1つ目は言わずもがな、です。
2つ目は、世の中にJenkis やCircle CI、Bitrise といった非常に豊富な種類のCI/CDツールがあり、それぞれに良し悪し、向き不向きが少なからず存在します。それはもちろんUnity Cloud Build も同じです。
そんな良し悪しを比較検討して、皆さんは自分やチームにどのCI/CDツールを導入するべきかと選択する場面があるかと思います。そんな時に、**「へぇ〜、Unity Cloud Build も悪くないね」** と思える判断材料の1つになるかもしれません。

### 私がやったこと
具体的には、
**「Unity Cloud Build を使って、Git へのプッシュからTestFlight, Google Play Console(内部テスト), DeployGate へのアプリのデプロイを自動化した」**
です。（長い🤦‍♂️）

簡単に図にすると以下のようなフローを整えました。
![UCB-flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906060/4a7be906-d518-c797-ccf6-bd7a8e32f28a.png)

といいましても、そのほとんどは後述する「[参考記事](#参考記事)」の寄せ集めといった感じで、私自身が加筆した部分はわずかになります。（インターネットってすげー 😌）

### 前提
**Untiy Cloud Buildで、任意のGitクライアントからipa、 apk（およびaab）ファイルをビルドするフローが完結していること** 

「Unity Cloud Build でアプリをビルドする方法が知りたいのに〜」という方は、後述するDeployGate へのデプロイを行うにあたって大変参考にさせていただいた[こちらの記事](https://note.com/hikohiro/n/n1abdb928fee6
)が役に立つかと思います 💁‍♂️

環境はUnity 2020.3.26f1, macOS Montereyで行いました。
ただ、基本的にはUnity Cloud Build側の設定で色々変えられるので、皆さんの環境に合った設定をしていただければと思います 😌

さて、それでは早速行ってみましょう。

# DeployGate へのデプロイ

DeployGate、便利ですよね。

Unity Cloud Build では、ビルドされたアプリをインストールできるリンクを生成する機能が元々備わっているのですが、
DeployGate にアプリをデプロイしておくと色々都合がいいです 😌

Unity Cloud Build からDeployGate へのデプロイは以下の記事が非常に参考になりました。

https://note.com/hikohiro/n/n1abdb928fee6

こちらの記事では、Unity Cloud Build の設定から丁寧に解説してくれているので、「Unity Cloud Build の設定からやりたいんだけどな〜」って人にとっても、とてもとてもありがたい記事となっております♫

さて、Unity Cloud Build側の設定が終わった後、Unityプロジェクトの好きなところに、好きな名前の以下のようなシェルスクリプト2つを配置します。
それぞれipa, apkファイルデプロイ用です。

**ipa用シェルスクリプト**
``` bash
#!/bin/bash

echo "Deploy iOS app to deploygate"

build_number=`awk -F\\" '/"buildNumber"/{print $4}' build_manifest.json`
version_number=`awk -F: '/bundleVersion/{print $2}' ProjectSettings/ProjectSettings.asset | sed -e "s/ //g"`
commit_id=`awk -F\\" '/"scmCommitId"/{print $4}' build_manifest.json`
comment=`git show ${commit_id} --no-patch --pretty=%B`

curl \\
 -H "Authorization: token <YOUR API TOKEN>" \\
 -F "file=@$2/build.ipa" \\
 -F "message=${version_number} (${build_number}) by Unity Cloud Build
 ${comment}" \\
 -F "distribution_key=<YOUR KEY>" \\
 "<https://deploygate.com/api/users/<YOUR NAME>/apps>"
```
**apk用シェルスクリプト**
``` bash
#!/bin/bash

echo "Deploy Android app to deploygate"

build_number=`awk -F\\" '/"buildNumber"/{print $4}' build_manifest.json`
version_number=`awk -F: '/bundleVersion/{print $2}' ProjectSettings/ProjectSettings.asset | sed -e "s/ //g"`
commit_id=`awk -F\\" '/"scmCommitId"/{print $4}' build_manifest.json`
comment=`git show ${commit_id} --no-patch --pretty=%B`

curl \\
 -H "Authorization: token <YOUR API TOKEN>" \\
 -F "file=@$2/<TARGET'S NAME>.apk" \\
 -F "message=${version_number} (${build_number}) by Unity Cloud Build
 ${comment}" \\
 -F "distribution_key=<YOUR KEY>" \\
 "<https://deploygate.com/api/users/<YOUR NAME>/apps>"
```

そして対象のUnity Cloud BuildターゲットのConfigurations にある**Advanced Options > Post-Export Method** に`(任意のパス)/(任意のファイル名).sh`と記入します。
こうすることで、Unity Cloud Build がipa, apkファイルをビルドした後に、このシェルスクリプトが実行されます。


それぞれのシェルスクリプトにいくつか埋めてもらうところがあります。
1. `<YOUR API TOKEN>`
DeployGate のAPIトークンです。
DeployGate のダッシュボードの右下から見ることができるはずです。
2. `<YOUR KEY>`
アプリ配布ページにあるDistributio Key なるものです。
ぜひ、先ほども紹介した[こちらのありがたい記事](https://note.com/hikohiro/n/n1abdb928fee6)を参考にしていただけるとわかりやすいです 💁‍♂️
3. `<YOUR NAME>`
ここにはDeployGate に登録しているユーザー名が入ります。Organaization でアプリを配布する場合はそのOrganization名です。
ちなみに、私はここで数時間つまずいたのですが、このOrganization名はブラウザなどで表示されている名前とは別なので、DeployGate が提供している[List Your Organizations](https://docs.deploygate.com/reference/organizations-index) というREST API を使ってOrganization名を確認すると確実です👍
4. `(Androidのみ) <TARGET'S NAME>`
ipaファイルは決まって`build.ipa`というファイル名でビルドされるっぽいのですが、なぜだかわかりませんが少なくとも私の環境では、apkファイルはUnity Cloud Build のターゲット名に依存するようです。しかも、ターゲット名を途中で変えたとしても書き出されるapkファイル名は変わらずでした。
多分別でどこかに名前の情報を持ってるのでしょうが、あまりこだわるところでもないので、深追いはしませんでした。原因・解決方法分かる方おりましたらコメントいただけると嬉しいです 🤲

DeployGate へのデプロイは以上ですっ！😉

# TestFlight へのデプロイ

続きましては、TestFlightへのデプロイです 💻

DeployGate でも十分アプリのテスト環境は整いますが、TestFlight だとApple ID のみでテストユーザーが追加できたり、結局アプリをApp Store Connect にアップロードするので、TestFlight でテストしておいた方が色々と都合がいいことありますよね。

そんなTestFlight へのデプロイですが、以下の@ramieさんのありがたい記事を参考にさせていただいております。
というかもうそのままです。（ありがたすぎる、、！🥹）

https://qiita.com/ramie/items/e797c337274a95b9275b

上記の記事で紹介されている[こちら](https://scrapbox.io/bexide-tech-blog/UnityCloudBuild%E3%81%A7TestFlight%E3%81%B8%E3%81%AE%E9%85%8D%E4%BF%A1%E3%82%92%E5%AE%8C%E5%85%A8%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B)にあるように、
1. 「輸出コンプライアンスの確認」チェックの回避
2. iOSビルド番号のインクリメント

をUnity のC#スクリプト側でやっておくと大変スムーズなのでオススメです 💁‍♂️

# Google Play Console (内部テスト)へのデプロイ

TestFlight にもデプロイできたので、この流れでGoogle Play Console の内部テストにもデプロイしちゃいましょう♫

参考にさせていただいた記事は、以下のUnityフォーラムと、noteの記事です。

https://forum.unity.com/threads/unity-cloud-build-fastlane-for-android.1186918/

https://note.com/shcahill/n/n1c7d72df3c4d

1つ目の記事ではUnity Cloud Build で使うシェルスクリプトについて、
2つ目の記事ではそのシェルスクリプト内で使うGoogle Play Console API のJSONキーの書き出し方法が説明されています。

Unityプロジェクトに配置するシェルスクリプトは以下のような感じです。ここではaabファイルを内部テストにデプロイしています。

**aab用シェルスクリプト**
``` bash
#!/bin/bash
 
PACKAGE_NAME=$(cat "$WORKSPACE/build.json" | jq -j '.[].bundleid')
UNITY_PLAYER_PATH="$2/<TARGET'S NAME>.aab"
KEY_WITH_NEWLINES=$(echo $PLAYSTORE_KEY | jq '.private_key |= sub(" (?!PRIVATE|KEY)"; "\n"; "g")' -c -j)

fastlane supply \
--package_name "$PACKAGE_NAME" \
--aab "$UNITY_PLAYER_PATH"  \
--json_key_data "$KEY_WITH_NEWLINES" \
--release-status completed \
--track internal
```

Unity Cloud Build にあるConfigurations にて、Environment Variables を1つ追加する必要があります。key に`PLAYSTORE_KEY`、value にGoogle Play Console API のJSONキーを丸ごとぶち込みます。

私の方では試してはいないのですが、最後のコマンドの`--track internal`を
`--track alpha`や`--track beta`、`--track production`にすれば、クローズドテストやオープンテスト、製品版にデプロイすることができるはずです 🧐

また、Google Play Console API の権限以外にも、[国/地域]が設定されていないとデプロイに失敗します。

この辺りやその他詳細については、以下のfastlane公式のドキュメントを読むのが良さそうです 😉

https://docs.fastlane.tools/actions/supply/

また、Google Play Console ではPlayerSettingsにある`BundleVersionCode`が同じapk/aabファイルはアップすることができないので、
例えば以下のように、`OnPreprocessBuild`などでAndroidプラットフォームでのみ`BundleVersionCode`を自動的に上げる処理を書いておくと便利です。
``` C#
public void OnPreprocessBuild(BuildReport buildReport)
{
#if UNITY_ANDROID
    PlayerSettings.Android.bundleVersionCode = Int32.Parse(DateTime.Now.ToString("yyyyMMddHH"));
#endif
    ...
}
```

# さいごに

以上となります 😌🍵

Unity Cloud Build を使った開発は、個人や比較的小規模のチームではだいぶコスパ良く開発環境の改善ができるかと思いますので、もしよかったら試してみてください。

現在プレティア・テクノロジーズでは、「共に達成する喜びを届ける」というミッションを一緒に目指す仲間を絶賛募集しています。

グローバルな環境でARというチャレンジングな分野に積極果敢に取り組んでいます。私もMeetyでカジュアル面談をやってますので、よかったら気軽にまずは雑談でもしましょう 😌

### 採用
https://herp.careers/v1/pretia/NAtCfsG_2Vh6

https://herp.careers/v1/pretia/P-cEsHmCDkhg

### カジュアル面談（私と）
https://meety.net/matches/ufxRuFEilnJg

# 参考記事
- [Unity Cloud Buildを使ってiOSアプリの自動配布環境を構築する](https://note.com/hikohiro/n/n1abdb928fee6)
- [[Unity][iOS] UnityCloudBuild を使って TestFlight にアップロードするお話。](https://qiita.com/ramie/items/e797c337274a95b9275b)
- [UnityCloudBuildでTestFlightへの配信を完全自動化する](https://scrapbox.io/bexide-tech-blog/UnityCloudBuild%E3%81%A7TestFlight%E3%81%B8%E3%81%AE%E9%85%8D%E4%BF%A1%E3%82%92%E5%AE%8C%E5%85%A8%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B)
- [Unity Cloud Build Fastlane for Android](https://forum.unity.com/threads/unity-cloud-build-fastlane-for-android.1186918/)
- [Google Play Console APIを使う方法](https://note.com/shcahill/n/n1c7d72df3c4d)
- [supply - fastlane docs](https://docs.fastlane.tools/actions/supply/)