AWS で構築した認証付き GitLFS サーバーを利用しつつ、Unity Cloud Build を利用する。
「Happy Elements Advent Calendar 2023」 12月12日の記事です。
はじめに
『メルクストーリア』グループ所属のゲームエンジニアの岸本と申します。
本記事では、Amazon Web Services (AWS)
で構築した認証付き GitLFS サーバーを利用しつつ、機微情報を Git にコミットすることなく、Unity Cloud Build
を利用する方法をご紹介したいと思います。
前提環境
弊社では、基本的に各プロジェクト単位にビルドマシンを用意してビルド環境を構築していますが、小規模なプロジェクトでは Unity Cloud Build
を活用する場合もあります。
また、GitLFS のコンテンツ保存先として、GitHub 標準のものではなく、Amazon Simple Storage Service (Amazon S3)
を採用しています。
正確には、Amazon API Gateway
で公開した API を用いて、AWS Lambda
で Basic 認証 と S3 Presigned URL 発行 を行い、Amazon S3
で GitLFS コンテンツ管理 を行っています。
このように独自にホストした GitLFS サーバーを利用する場合、.lfsconfig
に URL を指定することで解決でき、上記の環境であれば、以下のような設定にすることで利用できます。
[lfs]
url = https://{username}:{password}@{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}
問題点
さて、上記 URL のままだと、Basic 認証に必要な ユーザー名 や パスワード といった機微情報も一緒に Git にコミットしてしまうことになります。
また、ユーザー単位に認証情報を変更したりすることも難しくなるため、Basic 認証にあたる {username}:{password}@
の部分を記載せず、下記のような .lfsconfig
であることが理想的かと思います。
[lfs]
url = https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}
このように認証情報がない場合、初回のプルのタイミングなどで認証が求められ、認証に成功すれば Git Credential Manager
に認証情報が記録され、その後は良しなに利用できるようになります。
ここまでの内容で、ユーザーが直接操作する通常の運用であれば問題無さそうに思いますが、Unity Cloud Build
のようなクラウド環境で扱う場合、認証情報の入力が必要なタイミングでエラーとなり、ビルド自体に失敗してしまいます。
[error] fatal: could not read Username for 'https://{restapi_id}.execute-api.{region}.amazonaws.com': Device not configured
[error] Error downloading object: Assets/xxxxx.png : Smudge error: Error downloading Assets/xxxxx.png (xxxxx): batch response: Git credentials for {restapi_id}.execute-api.{region}.amazonaws.com not found.
この問題を解決するにあたり、Git に機微情報をコミットしないという運用は維持しつつ、Unity Cloud Build
で認証付き GitLFS を扱う方法についてお話したいと思います。
解決方法
今回は、Unity Cloud Build
で利用可能な Environment variables に認証情報付き URL を設定し、Pre-build script で .lfsconfig
を認証情報付き URL のものにパッチすることで、解決したいと思います。
Environment variables 設定
Unity Cloud Build
のビルド設定の Advanced settings / Environment variables で任意の環境変数を設定することができます。
Unity Cloud Build
では、GitHub の Secrets や Jenkins の Credentials のように、いい感じに機微情報を扱える機能がないため、環境変数で代用します。
そのため、運用にあたってはアクセス可能なユーザーを限定するなどの工夫も必要ですし、ログに出力した場合マスクなどもされないため、取り扱いには注意が必要になります。
GIT_LFS_SKIP_DOWNLOAD_ERRORS
Unity Cloud Build
の既定の動作で、リポジトリをプルしたタイミングの .lfsconfig
を使って、自動的に GitLFS コンテンツもプルします。
ただし上記のとおり、このタイミングの .lfsconfig
には認証情報が不足しているため、認証に失敗してエラーとなります。
[error] fatal: could not read Username for 'https://{restapi_id}.execute-api.{region}.amazonaws.com': Device not configured
[error] Error downloading object: Assets/xxxxx.png : Smudge error: Error downloading Assets/xxxxx.png: batch response: Git credentials for {restapi_id}.execute-api.{region}.amazonaws.com not found.
今回、この問題を解決するために、後述の Pre-build script
を利用したいところですが、このエラーによって Pre-build script
の実行まで辿りつけないため、GitLFS の設定でダウンロード時のエラーをスキップできる GIT_LFS_SKIP_DOWNLOAD_ERRORS=1 の環境変数を設定しておきます。
GIT_LFS_URL
後述の Pre-build script
で使用する 認証情報付き GitLFS の URL
を設定します。
https://{username}:{password}@{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}
Pre-build script 設定
Unity Cloud Build
のビルド設定の Advanced settings / Script hooks で任意のスクリプトを設定することができます。
リポジトリのプル ~ ビルド開始前のタイミングにフックして任意のシェルスクリプトを実行できる Pre-build script
が設定できるため、こちらを利用します。
pre-build.sh 実装
Pre-build script
のタイミングで実行するシェルスクリプトを用意します。
内容としては、先ほど環境変数に設定した 認証情報付き GitLFS の URL (GIT_LFS_URL)
で .lfsconfig
をパッチして、再度 GitLFS のコンテンツをプルするというものです。
(パッチの内容自体は、各プロジェクトの .lfsconfig
の内容に応じて、適宜変更が必要です。)
#!/usr/bin/env bash
# .lfsconfig パッチ
LFS_CONFIG=".lfsconfig"
LFS_TAG="[lfs]\n"
LFS_URL=" url = ${GIT_LFS_URL}\n"
cp /dev/null ${LFS_CONFIG}
echo -e ${LFS_TAG} >> ${LFS_CONFIG}
echo -e ${LFS_URL} >> ${LFS_CONFIG}
# GitLFS 再プル
git lfs install
git lfs fetch
git lfs pull
このシェルスクリプトをリポジトリにプッシュすることで、Unity Cloud Build
から使用できるようになります。
ちなみに、Pre-build script
に設定するシェルスクリプトのパスは、ルートからの相対パスになります。
The path (relative to the root of the project) of a shell script you want us to invoke before starting the Unity build process.
Project subfolder path
を使用している場合は、Project subfolder path
がルートになるため、そこからの相対パスになります。
動作確認
ここまでの設定で、Unity Cloud Build
のビルドを実行してみます。
INFO: Executing Script at xxxxx/pre-build.sh
INFO: "/BUILD_PATH/xxxxx/pre-build.sh"
Updated Git hooks.
Git LFS initialized.
fetch: Fetching reference refs/heads/main
INFO: ++++++++++++++++++++++++++++++++++++++++
INFO: + Building with Unity installed at /APPLICATION_PATH/Unity.app/Contents/MacOS/Unity
INFO: ++++++++++++++++++++++++++++++++++++++++
ログの最初の方で、Executing Script at xxxxx/pre-build.sh
のようなログが出力され、pre-build.sh
のシェルスクリプトが実行され、無事に GitLFS コンテンツをプルすることができ、ビルドが開始します。
ビルド自体に問題がない場合は、そのままビルドが完了します。
おわりに
ということで、多少力業感はありますが、独自に構築した認証付き GitLFS サーバーを利用しつつ、機微情報を Git にコミットすることなく、Unity Cloud Build
を利用する方法のご紹介でした。
Unity Cloud Build
でしっかり機微情報を扱う機能があればベストですが、現状そういった機能はないため、普通の環境変数で代用と言った妥協も入っていますが、普段の Git 操作や機微情報の取り扱いを変えることなく、解決できたかと思います。
今回の件以外にも、Unity Cloud Build
のビルドに機微情報を流し込みたいケースは結構あるので、普通に機微情報を扱える機能が欲しいところですね…。
今回のように Git に機微情報のコミットを避けつつ、似たようなビルド環境を構築したいケースなどで何かしらの参考になれば幸いです。
Discussion