9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Unreal Engine 4 (UE4) その2Advent Calendar 2018

Day 16

【UE4】ボタンポチっでiOS/AndroidのDevelopment/Shippingの計4つのバイナリを作ってDeploygateに上げる【Jenkins】

Last updated at Posted at 2018-12-15

概要

Unreal Engine 4 (UE4) その2 Advent Calendar 2018 の16日目です

みなさんモバイルゲームを複数人で開発している際、バイナリのデプロイはどうしていますか?
iOS/Android, デバッグビルド/リリースビルドの合計4つを手動でビルドし、メンバー全員の端末にインストールする・・・という運用は無理がありますよね?
この手の解決方法でよく聞くのは、jenkinsとdeploygateを用いた自動デプロイです。
これをUE4のプロジェクトでもできるのでしょうか?
ggってみたらUE4 x jenkinsの記事が思ったよりなかったので、これらのやり方を紹介します。

  • 注意
    • Jenkins、deploygateの使い方等はあまり説明しません
    • iOSの開発者登録は済んでいて、証明書などは組み込み済みなことを想定しています
    • Path等はご自身の環境によって違いますので、いいかんじに読み替えてください

やりたいこと

図で表すとこんな感じです。
ビルドボタンをポチらなくてもビルドを走らせることができますが、開発の都合上今回はやってません。
Graph.001.png

そして今回のビルドはここの「プロジェクトをパッケージ化」から行うことを想定しています。
(Project Lancher/Unreal Frontendから行うものではありません)
build.png

用意したもの

  • UE4.21.0
  • Jenkins 2.149
  • Windows10
  • Mac Mini(Mojave)(ちなみにBlueprintオンリー && 純正のUE4ならMacはいりません)
  • GitHubのアカウント(LFS課金した)
  • Deploygateのアカウント

やりかた

ビルドする際のコマンドがわかればbat/shに組み込めるようになり、jenkinsで運用できるようになります。
そして、ビルドする際のコマンドは「プロジェクトをパッケージ化」を行った際の「アウトプットログ」に書いてあります。
このコマンドは「プロジェクト設定」に書かれているものを反映したコマンドになっています。
command.png

そして、「アウトプットログ」に書かれている AutomationToolEpic Games/UE_4.バージョン番号/Engine/Binaries/DotNET/ にあります。
これさえわかれば勝ったようなものです。
jenkinsに組み込みましょう。

Macで AutomationTool.exe を動かすには mono が必要です。
予めHomebrew等でインストールしておきましょう。
また、開発をWindowns、jenkinsサーバーをMacとしている場合、MacにもUE4のインストール・iOSの開発者証明書等・AndroidSDK等のインストールもお忘れなく。

Jenkinsの立ち上げ・初回設定は割愛します。ほかの記事を参照してください。

では「フリースタイル・プロジェクトのビルド」でジョブを作成します。
私の場合はパラメーターとして以下を設定できるようにしました。
スクリーンショット 2018-12-15 15.55.45.png

Githubの設定もします。
Git LFSを使っている場合はその設定も忘れずに。
スクリーンショット 2018-12-15 15.56.32.png

ビルドにてシェルスクリプトを記述します。
私は以下のように書きました。
スクリーンショット 2018-12-15 15.56.45.png

iOSの場合
mono "/Users/Shared/Epic Games/UE_4.21/Engine/Binaries/DotNET/AutomationTool.exe" -ScriptsForProject="${WORKSPACE}/${project_name}.uproject" BuildCookRun -nocompile -nocompileeditor -installed -nop4 -project="${WORKSPACE}/${project_name}.uproject" -cook -stage -archive -archivedirectory="/Users/ユーザー名/Documents/UnrealPackages/${project_name}" -package -clientconfig=${config} -ue4exe=UE4Editor -pak -prereqs -nodebuginfo -targetplatform=IOS -utf8output

projectName="${project_name}"
if [ ${config} == "Shipping" ]; then
    projectName="${project_name}-IOS-Shipping"
fi

if [ ${upload_deploygate} == true ]; then
    curl -F "token=deploygateのトークン" -F "file=@/Users/ユーザー名/Documents/UnrealPackages/${project_name}/iOS/$projectName.ipa" -F "message=config: ${config}" https://deploygate.com/api/users/deploygateのユーザー名/apps
fi

Androidの場合はビルドする際に選択したテクスチャ圧縮形式によってコマンドが若干かわるので注意してください。

Androidの場合
mono "/Users/Shared/Epic Games/UE_4.21/Engine/Binaries/DotNET/AutomationTool.exe" -ScriptsForProject="${WORKSPACE}/${project_name}.uproject" BuildCookRun -nocompile -nocompileeditor -installed -nop4 -project="${WORKSPACE}/${project_name}.uproject" -cook -stage -archive -archivedirectory="/Users/ユーザー名/Documents/UnrealPackages/${project_name}" -package -clientconfig=${config} -ue4exe=UE4Editor -pak -prereqs -nodebuginfo -targetplatform=Android -cookflavor=テクスチャの圧縮形式名 -utf8output

projectName="${project_name}"
if [ ${config} == "Shipping" ]; then
    projectName="${project_name}-Android-Shipping"
fi

if [ ${upload_deploygate} == true ]; then
    curl -F "token=deploygateのトークン" -F "file=@/Users/ユーザー名/Documents/UnrealPackages/${project_name}/Android_テクスチャの圧縮形式名/$projectName-armv7-es2.apk" -F "message=config: ${config}" https://deploygate.com/api/users/deploygateのユーザー名/apps
fi

最後にパイプラインジョブを作成します。
パイプラインによって他のジョブを順番に(並列にもできます)実行します。
スクリーンショット 2018-12-15 15.58.58.png

私の場合はパラメーターとして以下を設定できるようにしました。
スクリーンショット 2018-12-15 15.59.12.png

パイプラインスクリプトを記述します。
私は以下のように書きました。
スクリーンショット 2018-12-15 15.59.23.png

計4つのバイナリを生成しdeploygateにアップロードしslackに通知する
pipeline {
    agent none
    stages{
        stage ('iOS Development') {
            steps {
                build job: 'ビルドジョブ名-ios', parameters: [
                    string(name: 'project_name', value: 'プロジェクト名'),
                    string(name: 'config', value: 'Development'),
                    booleanParam(name: 'upload_deploygate', value: env.upload_deploygate),
                ]
            }
        }
        stage ('iOS Shipping') {
            steps {
                build job: 'ビルドジョブ名-ios', parameters: [
                    string(name: 'project_name', value: 'プロジェクト名'),
                    string(name: 'config', value: 'Shipping'),
                    booleanParam(name: 'upload_deploygate', value: env.upload_deploygate),
                ]
            }
        }
        stage ('Android Development') {
            steps {
                build job: 'ビルドジョブ名-android', parameters: [
                    string(name: 'project_name', value: 'プロジェクト名'),
                    string(name: 'config', value: 'Development'),
                    booleanParam(name: 'upload_deploygate', value: env.upload_deploygate),
                ]
            }
        }
        stage ('Android Shipping') {
            steps {
                build job: 'ビルドジョブ名-android', parameters: [
                    string(name: 'project_name', value: 'プロジェクト名'),
                    string(name: 'config', value: 'Shipping'),
                    booleanParam(name: 'upload_deploygate', value: env.upload_deploygate),
                ]
            }
        }
        stage ('post slack') {
            steps {
                script { 
                    if (env.upload_deploygate == "true") {
                        notification()
                    }
                }
            }
        }
    }
}

def notification() {
    def slack_channel = "#通知するチャンネル名"
    def slack_domain = "https://slack名.slack.com/"
    def slack_token = "slackのトークン"
    def slack_color = "good"
    if(currentBuild.result != "FAILURE") {
        def slack_msg = "新しいバイナリがアップロードされました!deploygateから確認できます! \n リリースノート: ${env.release_note}"
        slackSend channel: "${slack_channel}", color: "${slack_color}", message: "${slack_msg}", teamDomain: "${slack_domain}", token: "${slack_token}"
    }
}

これでパイプラインのjobを実行すればiOS/Android, Development/Shippingの4つのバイナリが生成されて、deploygateへとアップロードされます!

トラブルシューティング

Q: jenkinsから実行するとmonoが動かせないんだけど・・・
A: 環境変数をjenkinsで設定しましょう
スクリーンショット 2018-12-15 16.00.12.png

Q: MacでWindows版のゲームのビルドをしたい・・・(´・ω・`)
A: Macではできません・・・(´・ω・`)
iOS/Android/Windowsというビルドをしたい場合はどうしてもビルドするマシンを2台(Windows/Mac)用意しなければならないらしいです・・・

まとめ

UE4のプロジェクトををbat/shを使ってバイナリを生成したいときは、UE4上でビルドして「アウトプットログ」を見ると、そこにコマンドがかいてあります :thumbsup:

おわりに

今回はビルドボタンをポチるようにしましたが、jenkinsの設定をいじれば定期的にビルドしたり、pushがあった時点でビルドを走らせることもできます。
それでは良い開発ライフを!

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?