🚀

AWS で構築した認証付き GitLFS サーバーを利用しつつ、Unity Cloud Build を利用する。

2023/12/12に公開

「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 LambdaBasic 認証S3 Presigned URL 発行 を行い、Amazon S3GitLFS コンテンツ管理 を行っています。

このように独自にホストした 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 に機微情報のコミットを避けつつ、似たようなビルド環境を構築したいケースなどで何かしらの参考になれば幸いです。

Happy Elements

Discussion