YAMADA TAISHI’s diary

ゲームについてとか私の日記とか。このブログのあらゆるコードは好きにどうぞ。利用規約があるものは記事内のGitHubのRepositoryのリンクで貼られていると思うので、そちらを参照ください。

Unity1WeekJamに参加する前に自動ビルドを導入しよう

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。

Unity1WeekJamに参加するにあたって自動ビルドを行いました。
理由は自動ビルドを今回行った理由は開発時間の短縮化のためです。
自動ビルドの設定をゲームジャム前に行っていればゲームジャム中楽が少しだけ出来ます。
今回はその時の知見を共有したいと思い記事化しました。
自分で全て構築したのは初めてです。
少し間違ってる点、他にもっといいやり方などがあるかも知れませんが、許してください。

目次


前提


Jenkinsを使用
構築はMacBook pro
OSはmacOS mojave
また今回はUnityをビルドするためにJenkinsのUnity3d pluginを使用しました。
Gitを使うのでそれぞれの端末にGitを入れておく
Githubを利用
Slackに通知もさせます

欠点・利点

ゲームジャムにおけるJenkinsのビルドを使う欠点


  • 設定が少し多く素早く用意できない

素早く用意したいならUnity公式のCloudBuildが良いかも?

  • 準備が必要

何はともあれビルドように準備が必要

  • 1台では意味がない

私はPCが2台あるのでもう1台の方でビルドという手段が取れますが、1台しかPCがない方は無理です。
Unityを立ち上げているとコマンドビルドが多重起動になってビルド失敗します。別手段を考えなければいけないため効率が良くないかも?
因みに私の会社ではMacProをビルドマシンにしてます。
スマホゲームのアプリのビルドはiPhome・AndroidどちらともビルドできるMacに構築するのが主流のため、UnityのJenkinsビルドの情報はMac向けが多いと思います。
とある会社さんではMacMiniをビルドマシンにしてるところもあるみたいですね。

developer.aiming-inc.com

ゲームジャムにおけるJenkinsのビルドによる利点


  • 無料

Unity公式のCloudBuildはProもしくは Unity Team Advanced に入ってないと使えないので無料で使えるのは嬉しいですね。

  • バグに早く気づける

UnityのWebGLは制限機能が多く実際にビルドしてみて初めて気づくエラーなども多いです。

  • ビルドの時間短縮

別PCでビルドすればメインPCを専有することなく開発時間が少し捻出出来ます。


Jenkinsセットアップ


MacBook proをビルド機として使うので
まずMacBook Proに私はインストールして行きます。

1.Jenkinsのダウンロード

Jenkins公式サイトのURLにアクセスして「Download」をクリックします。 jenkins.io

下の方にあるリンクのMac OSXを選択してpkgをダウンロード。
(私は安定版にした)

2.インストールしていく

インストーラーに従ってインストール

3.Administrator passwordの入力

Administrator passwordを求められるので入力を行う
Administrator passwordは指定されているファイルに値があるので、その値を入力
適当にsudo suとかでスーパーユーザーになってcatでファイルを見にいく。

4.Customize Jenkins選択

ちゃんとカスタマイズして入れていってもいいんですが、推奨プラグインのInstall suggested pluginsにしておきます。
何を入れれば良いか私は知らないので。
後で足りない分は追加します。

5.ユーザー作成

Jenkinsのadminユーザー作成を求められるので適当に作成

後はそのまま進めます

進めるととりあえずJenkinsのインストール完了

Credential Pluginの設定


GitHub等にログインできるようにCredential Pluginの設定の設定をします。
(Install suggested pluginsを選択していればあるはずですが、なければ追加してください)

Jenkins>認証情報>System>グローバルドメイン
認証情報を追加をクリック。

今回はグローバルで作成。
ユーザー名とパスワードGitHubのアカウントを設定。
それとGitのアカウントとして
SSHユーザー名と秘密鍵 でGitのSSHの鍵を設定
(私の設定が悪いのかもしれませんがhttp認証設定だと上手く認証が動かないっぽいです)
SSHの作り方は割愛します。
後でSlackのアカウントも設定しますが一旦ココはこれだけ設定。

Unity3dBuilder Pulginの設定


このままではUnityのビルドで使えないのでUnity3dBuilder Pluginを入れます。
バッチモードでUnityを起動してくれていい感じにやってくれるやつです。
Unity3dBuilder Pluginを使わずにCIビルドの設定をしても良いですが、今回はやりやすさ優先。

1. プラグインの検索

Jenkinsの管理>プラグインの管理>利用可能タブ でUnity3dとフィルター検索
Unity3Dが出てくる。

2. プラグインのインストール

Unity3Dを選択(チェックを入れる)、そしてインストール、再起動
Jenkinsが再起動かかったら次の作業へ。

3.プラグインの追加

Jenkinsの管理>Global Tool Configuration>Unity3d>Unity3d追加

名前:(適当に私は「Unity2018.4」にした)
インストールディレクトリ:/Applications/Unity/Hub/Editor/2018.4.xxf1/Unity.app(Unity.appを指定)

指定できたら「Applay」ボタンを押す

Slack通知設定


プラグインの追加

Unity3dBuilder Pulginの設定と同じ様にSlackのプラグインの追加を行います。
Jenkinsの管理>プラグインの管理>利用可能タブ でSlack Notificationとフィルター検索
インストール、再起動

Slackの設定

Slackのワークスペースにて
Jenkins CI というアプリを追加します。

設定でどのチャンネルに投稿するか等設定。
トークンはコピーしておく

Slackアカウント設定

先程開いた、Credential Pluginを開きます。
Secret textを選択
Secretに先ほどコピーしたトークンを貼り付ける。
IDはなしでOK

Slackの通知設定の追加

Jenkinsにて Jenkinsの管理>システムの設定 を選択
Slackの項目にてワークスペース名を設定

CrdentialにCredential Pluginの設定で追加したSlackアカウントを選択

設定が出来たら Test Connection ボタンをクリック
上手く設定できていればSlackに通知が飛びます。
↓こんな感じ

いったんコレでSlackの設定は完了。
ビルド通知との紐付けは後でやります。

BuildScriptを書く


今回はUnity1Week用なのでWebGLのビルドを出来るようにする。
Assets/Editor配下 に以下のようなScriptを追加。
コメントが少ないのは許して。

using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace Editor
{
    public static class BuildScript
    {
        private static void Build(bool isToolBer = false)
        {
            bool isSuccess;
            const string path = "../output";
            FolderCreate(path);

            PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.WebGL, "");
            // ビルド処理
            BuildPlayerOptions buildOption = new BuildPlayerOptions
            {
                options = BuildOptions.None,
                scenes = GetAllScenePaths(),
                target = BuildTarget.WebGL,
                locationPathName = path,
            };
            UnityEditor.Build.Reporting.BuildReport reports = BuildPipeline.BuildPlayer(buildOption);
            isSuccess = (reports.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded);
            

            Debug.Log("isSuccess:"+ isSuccess);
            if(isToolBer){return;} //ツールバーからの実行だったら閉じたくないので終了
            EditorApplication.Exit(isSuccess ? 0 : 1); //上手く動かなかった時の検出に使う
            
        }

        /// <summary>
        /// 出力先フォルダ生成
        /// </summary>
        /// <param name="path"></param>
        private static void FolderCreate(string path)
        {
            
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }

        //GetAllScenePath
        private static string[] GetAllScenePaths()
        {
            var levels = EditorBuildSettings.scenes
                .Where(scene => scene.enabled)
                .Select(scene => scene.path)
                .ToArray();

            return levels;
        }

        [MenuItem("Build/Build Develop App")]
        private static void BuildApp()
        {
            Build(true);
        }
    }
}

ちゃんと動くかメニューから Build/Build Develop App をクリックして確認してみてね。

ビルドの設定


いよいよビルドの設定
Jenkinsの左のメニューより 新規ジョブ を選択
名前を設定して
フリースタイル・プロジェクトのビルド を選択
OKを押す

Generalの設定

特に無し

ソースコード管理の設定

Git を選択

リポジトリURLを設定(git cloneコマンドと同じ記法)
私は以下のように設定しました。

git@github.com:TripleAt/XXXXX.git

認証情報は先程作ったGitのSSHキーのものを設定

ブランチを指定
私は以下のように設定しました。

*/master

追加処理の設定

  • Advaned checkout behaviours

pullに時間がかかったときにコケるので設定します。
チェックアウトのタイムアウト(分) 20

  • Advenced clone behaviours

フェッチのタイムアウト時間も一応 20分に設定

  • Git LFS pull after checkout

GitLFSをつかってる人は必ず入れましょう。
Pullに失敗します。

ビルド・トリガ

ポーリングをして定期的にコミットを確認しに言ってもらいます。
ビルド・トリガの項目で SCMをポーリング を選択
私は以下のように設定15分ごとにコミットされているか確認しに行ってくれる。

H/15 * * * *

もう少し高頻度でも良かったかも?

ビルド環境の設定

特に無し

ビルドの設定

Invoke Unity3d Editorを選択
Unity3d installation name
Unity3dBuilder Pulginの設定の3で設定したものを選ぶ

Editor command line argumentsに以下のコマンドを設定

-quit -batchmode -executeMethod BuildScript.Build

コマンドの意味
-quit 自動終了
-batchmode Unityをバッチモードで起動
-executeMethod 動かすクラスと関数を指定する

ビルド後の処理

Slack Notificationsを選択
選択はお好みで、私は全部チェック入れました。
これでSlackにビルド通知が飛ぶようになるはず。

他に気をつけること


これで基本的に構築完了です。
しかし、ゲームジャム中運用していて気をつけるべき点がいくつかありました。
書き残しておこうと思います。

  • Macの再起動

MacのOSの再起動をONのままにしており、Macが再起動されていました。
するとローカルホストに立てられているJenkinsは再起動後立ち上げれてないのでGitにPushしても反応しません……。
起動後にサービスを立ち上げるような設定が必要かもしれません。
Jenkinsが落ちても再起動できるようにJenkinsホームがどこになっているかだけは確認しておきましょう……。
そもそもOS更新が入らないようにしておくのが良いかもしれないですね。

  • Macがスリープ

スリープするとビルド自体は動きますが、凄く遅くなってしまうみたいです。
10分ほどで終わるビルドが 41分かかっていました。
またpullに時間がかかり過ぎてタイムアウトで落ちていました。
画面がスクリーンセーバーモードやスリープ状態にならないように設定しておいたほうが良さそうです。

gitをhttp認証にしていたらいつまで立ってもpullやcloneが出来ませんでした。なぜかは分からない。

  • RegisterApplication(), FAILED TO establish the default connection to the WindowServer, CGSDefaultConnection() is NULL. というビルドエラー

Jenkinsの実行権限がないときに起こるみたいです。
私の環境だけなのか、違うのかが分からなかったので上記インストール手順には書きませんでしたが、
起きた場合

sudo vim /Library/LaunchDaemons/org.jenkins-ci.plist

をして、
GroupNameをstaffに
UserNameを自分のユーザーにしてJenkinsを再起動すればいいと思います。

詳しいことは忘れたましたが、Jenkinsのホームを指定して以下コマンドを叩けばいいと思います。
(Jenkinsホームが設定されてないと設定とかの参照が別のところを参照し日本語表記ではなく英語のJenkinsが表示される)

java -jar /Applications/Jenkins/jenkins.war

  • git-lfs: command not found

GitLFSをつかっているのにGitLFSの設定を忘れてたときにコレで怒られます。
インストール手順には書いたので、この記事を読んでる人が引っかる事はないと思いますが念の為。

まとめ


以上がJenkinsの設定でした!
一度Jenkinsを設定したら次回以降設定が使い回せると思います。
思い切って設定をしてみてはいかがでしょうか?
もう一歩踏み込んだビルドだと、自動デプロイまでしてくれるところまで出来たりします。
ここは始まりです。カスタマイズして自分だけの環境を手に入れよう!
自動ビルドは良いぞ!

以上、やまだたいしでした!