Unityゲームの手動デプロイで事故りまくったので自動化した話

Qiitaで読む: Unityゲームの手動デプロイで事故りまくったので自動化した話

これはUnityゲームのデプロイを手動でやったら手元が狂って事故りまくったので、自動化した話です

clpsplug/ucb-webhook-receiver on GitHub

4つって意外と多いんです

私はSteamでUnityゲームを出しているが、そのゲームをSteamにアップデートなどで送る時には「(自分で決定できる)特定のディレクトリ」に置いておかなければならない。

レポジトリ側にはgit-flowを適用しているので、 base ブランチにコミットがあれば、Unity Cloud Buildでビルドが走るようになっている。やっと Windows用のIL2CPPビルドができるようになってよかった。

ビルドされるゲームのバージョンは4つだ。

  • macOS Production Build
  • macOS Developer Build w/ development tools
  • Windows Production Build
  • Windows Developer Build w/ development tools

これらがビルドされたら、私は自分で

  1. それらをダウンロードして
  2. あらかじめ決めた特定のディレクトリにそれぞれのバージョンを配置して
  3. Addressableバンドルを追加する

という作業をしなければならなかった。

問題発生

数ヶ月前のことである。テスターの一人が、あるアップデートでゲームが壊れたと言い出したのだ。

私はログを集めた。Unity上でもテストした。なんなら、ローカルでビルドして試してみた。全く再現しない。というか、彼の受け取ったビルドでそんなことが起こっていること自体あり得ないバグだった。

…と思っていた。

どうやら、ビルドされたゲームをディレクトリに配置していくときに、誤ってProductionバージョンをdevバージョンに配置していたようだ。

FACEPALM

Alex E. Proimos, CC BY 2.0, via Wikimedia Commons

本当に逆じゃなくてよかった。

…よく考えたら、前にも同じような事故をやっていたことに気づいた。その時はテスト用のブランチでテストしていたから、通常のプレイヤーが変なビルドを見ることは回避されていたのだが…

もうたくさんだ。手動なぞやめてしまおう

(╯°□°)╯︵ ┻━┻

調査してみるとUnity Cloud BuildはWebhookを送信できるらしい。どうにかしてこれを受け取って「ダウンロード→配置」までできればOKだ。

ただ、どうやってこのWebhookを受け取るかが問題だ。

レンタルサーバーは持っている。ただしそれはWebページ用だ。ここでやろうとしていることをやったものなら、サーバーにプロセスをぶった切られるリスクがある。
VPSもアカウントはあるが少し高い。静的IPが欲しいからVPNを作るとか、そういう用途でない限りはあまり手を出したくない。

そこで、自分の古いPCからホストできたらどうか、と気づいた。

ちょっと調べてみるとLoopholeという無料トンネルサービスがあることを見つけた。この手法でずっと開いておくのはあまり喜ばれたことではないかもしれないが、個人レベルの自動化プロジェクトならしばらくこれでも大丈夫だろう。これで自分のPCでWebhookを受け取る算段ができた。

loophole/cli on GitHub

あとはどうやってHTTPリクエストに応答しつつ裏でスクリプトを走らせるかを学ぶだけだ。

どうやってサーバ側のコードを書く?

最初、Apache2を使うことも考えたが、よく考えたらやろうとしていることに対して大袈裟すぎる気がした。Apache2は高機能なwebサーバだ。ただただWebhookを受け取りたいだけの目的には機能が多すぎる。
そもそも、Jenkinsも同じような理由で使うのをやめていた。もし、自分のマシンでビルドまでやっていたのであればJenkinsを使う理由もあったが、今やりたいのは「ビルドしたゲームのダウンロードとそのゲームを正しい位置に配置する」ことだけだ。
自分の知っている言語で、あるポートへの通信を監視するだけの軽量なサーバライブラリがあれば十分だった。

調べてみるとPythonで CherryPy という軽量Webフレームワークがあることを知った。裏でプロセスを立ち上げてもHTTPリクエストを処理できることも確認できた。今回は、このフレームワークに乗ることにした。

cherrypy/cherrypy on GitHub

何をダウンロードすれば良い?

ビルド成功時のペイロードはこんな形をしている (ほとんどの情報はダミーに置き換えている):

配列 artifacts はこれ以外にもデバッグ用のシンボルファイルなどの多くの要素を持っているのだが、重要なのは primary キーが true のものだ。ヘッドレスビルドなどをしていない限り、これがゲームとなる。

ちなみに、自分で生成したシークレットキーを登録して、 x-unitycloudbuild-signature を使ってペイロードの検証も可能である。

結果

何回かファイルシステムをメチャクチャにしてしまったが、完成品がこちら:

Clpsplug/ucb-webhook-receiver on GitHub

このプロジェクトは、UCBからWebhookを受け取ったら、ペイロードの指定する成果物をダウンロードし、出力フォルダに配置すると共に、別に追加する必要のあるフォルダ・ファイルもまとめて配置してくれる。

あとはSteamのツールの確認先をこのディレクトリに向ければいいだけだ。もうバイナリの種類を間違うことはないだろう。

ちなみに: 間違ってファイル全消しとかにならないためにも、Dockerコンテナで動かせるようにした。多分こちらの方が安全だと思います

さらにちなみに: 自分の環境以外でテストしていないので、試される方はご注意ください - もし動かない等あればissueを開いていただけると嬉しいです