LoginSignup
15
12

More than 3 years have passed since last update.

JenkinsでUnityのAndroid・iOSビルド (Automatically manage signing,pod install対応) DeployGateにアップまで

Last updated at Posted at 2019-03-16

はじめに

この記事はメモ書きみたいなものなので、詳細な説明は省いています。
気になる方は都度調べてくださいmm

使用環境

  • Xcode10.1
  • Unity2017.4.20f1

Jenkinsインストール

この記事ではHomebrewでインストールします。

brew install jenkins

インストール後下記コマンドで起動します

brew services start jenkins
//launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

停止は下記コマンドです

brew services stop jenkins
//launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

ビルド用のシェルを用意

batchbuild時の-platformの指定をiOSにすればiOSビルドになります。

#!/bin/bash

# Unityアプリケーションパス
UNITY_APP_PATH=/Applications/Unity2017_4_20f1/Unity2017_4_20f1.app/Contents/MacOS/Unity
# 対象のUnityプロジェクトパス
UNITY_PROJECT_PATH=${WORKSPACE}  #自身のプロジェクトによって変えてください

# バッチモードで起動後に呼び出すメソッド
UNITY_BATCH_EXECUTE_METHOD=BatchBuild.Build  #自身の用意した関数名を記述 クラス名.関数名
# Unity Editor ログファイルパス
UNITY_EDITOR_LOG_PATH=~/Library/Logs/Unity/Editor.log

# 指定のUnityプロジェクトをバッチモード起動させて、指定のメソッド(Unity上で用意する)を呼び出す
$UNITY_APP_PATH -batchmode -quit -projectPath "${UNITY_PROJECT_PATH}" -executeMethod $UNITY_BATCH_EXECUTE_METHOD -logfile -platform Android -isRelease false

# Unityでのbuildに失敗した場合は終了
if [ $? -eq 1 ]; then
 cat $UNITY_EDITOR_LOG_PATH
 exit 1
fi

#正常終了
exit 0

Unity側でiOSビルドの設定

Unity > Preference > External Tools > Automatically Signにチェック
Unity > Preference > External Tools > Automatic Signing Team Idに自身のチームIDを入力
Edit > Project Settings > Player > Identificatinにアプリ情報入力

Unity側でビルドスクリプトの用意

#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class BatchBuild{

    private static BuildTarget m_TargetPlatform;
    private static bool m_IsRelease = false;

    // ***** Android KeyStore Settings *****//
    private static string keystorePath = "keyStoreの保存場所";
    private static string keystorePass = "keyStoreのPass";
    private static string keyaliasName = "keyAliasの名前";
    private static string keyaliasPass = "keyAliasのPass";
    // ***** End Android KeyStore Settings *****//

    public static void Build()
    {
        GetCommandLineArgs ();
        if (m_TargetPlatform == BuildTarget.iOS) {
            bool status = BuildiOS (m_IsRelease);
            EditorApplication.Exit (status ? 0 : 1);
        } else {
            bool status = BuildAndroid (m_IsRelease);
            EditorApplication.Exit (status ? 0 : 1);
        }
    }

    public static bool BuildiOS(bool isRelease = false)
    {
        Debug.Log ("[ScriptLog] Start Build iOS");

        // リリースビルドではない場合Profiler等に繋げるようにする
        BuildOptions opt = BuildOptions.SymlinkLibraries;
        if (isRelease == false) {
            opt |= BuildOptions.Development | BuildOptions.ConnectWithProfiler | BuildOptions.AllowDebugging;
        }

        string[] scenes = GetEnabledScenes ();
        string errorMsg = BuildPipeline.BuildPlayer (scenes, "成果物保存場所(Assetsからの相対パス)", m_TargetPlatform, opt);

        if (string.IsNullOrEmpty (errorMsg)) {
            Debug.Log ("[ScriptLog] Success Build iOS");
            return true;
        }

        Debug.Log ("[ScriptLog] Failed Build iOS");
        Debug.Log (System.Environment.NewLine + errorMsg + System.Environment.NewLine);
        return false;
    }

    public static bool BuildAndroid(bool isRelease = false)
    {
        Debug.Log ("[ScriptLog] Start Build Android");

        // リリースビルドではない場合Profiler等に繋げるようにする
        BuildOptions opt = BuildOptions.None;
        if (isRelease == false) {
            opt |= BuildOptions.Development | BuildOptions.ConnectWithProfiler | BuildOptions.AllowDebugging;
        }

        // KeyStoreの設定
        SetAndroidKeyStoreSetting ();

        string[] scenes = GetEnabledScenes ();
        string errorMsg = BuildPipeline.BuildPlayer (scenes, "成果物保存場所(Assetsからの相対パス)", m_TargetPlatform, opt);

        if (string.IsNullOrEmpty (errorMsg)) {
            Debug.Log ("[ScriptLog] Success Build Android");
            return true;
        }

        Debug.Log ("[ScriptLog] Failed Build Android");
        Debug.Log (System.Environment.NewLine + errorMsg + System.Environment.NewLine);
        return false;
    }

    /// <summary>
    /// AndroidのKeyStoreの情報をPlayerSettingsに流す
    /// </summary>
    private static void SetAndroidKeyStoreSetting()
    {
        string keystoreName = System.IO.Directory.GetCurrentDirectory () + keystorePath;
        // KeyStoreの場所とパスワードを設定
        PlayerSettings.Android.keystoreName = keystoreName;
        PlayerSettings.Android.keystorePass = keystorePass;
        // KeyAliasの名前とパスワードを設定
        PlayerSettings.Android.keyaliasName = keyaliasName;
        PlayerSettings.Android.keyaliasPass = keyaliasPass;
    }


    /// <summary>
    /// コマンドライン引数を解釈して変数に格納する
    /// </summary>
    private static void GetCommandLineArgs()
    {
        string[] args = System.Environment.GetCommandLineArgs ();
        // ここで引数を判定
        for (int i = 0, max = args.Length; i < max; ++i) {
            switch (args [i]) {
            case "-platform":
                m_TargetPlatform = (BuildTarget)System.Enum.Parse (typeof(BuildTarget), args [i + 1]);
                break;
            case "-isRelease":
                m_IsRelease = bool.Parse (args [i + 1]);
                break;
            default:
                break;
            }
        }
    }

    /// <summary>
    /// BuildSettingで有効になっているSceneを取得
    /// </summary>
    /// <returns>The enabled scenes.</returns>
    private static string[] GetEnabledScenes()
    {
        EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;

        List<string> sceneList = new List<string> ();

        for (int i = 0, max = scenes.Length; i < max; ++i) {
            if (scenes [i].enabled) {
                sceneList.Add (scenes [i].path);
            }
        }

        return sceneList.ToArray ();
    }
}
#endif

iOSでXCodeProjectのOtherLinkerやFrameworkを追加する場合

PostProcessBuildでFramework追加処理を挟む
追加したいLinkerやFrameworkが増えた場合、ここに記述していく。

using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;

public static class XCodeBuildPostProcess {

    [PostProcessBuild(100)]
    public static void OnPostProcessBuild(BuildTarget target, string path)
    {
        if (target == BuildTarget.iOS)
        {
            PostProcessBuild_iOS (path);
        }
    }

    private static void PostProcessBuild_iOS (string path)
    {
        string projectPath = PBXProject.GetPBXProjectPath(path);
        PBXProject pbxProject = new PBXProject();

        pbxProject.ReadFromString(File.ReadAllText(projectPath));
        string target = pbxProject.TargetGuidByName("XcodeProject名");

        // OtherLinker追加
        pbxProject.AddBuildProperty(target, "OTHER_LDFLAGS", "追加したいLinker名");

        // Framework追加 第三引数は Requiredならfalse,Optionalならtrue
        pbxProject.AddFrameworkToProject(target, "追加したいFramework", false);

        File.WriteAllText(projectPath, pbxProject.WriteToString());
    }
}

Jenkins側のJob作成

今回はパイプラインではなく、フリースタイル・プロジェクトのビルドで作成します。
パラメータやソースコード管理は適宜設定してください。
BULILD_SHELL_ROOTをJenkinsの環境変数に追加しています。
またシェルの実行時にPermission deniedが出た場合、
シェルの権限設定が間違っているので下記のコマンドを叩いて見てください
chmod 755 作ったシェル名

iOSのシェル

exportOptionPlist.plistは自分で作成してください。
developmentビルド、Releaseビルドなどの設定もここで行う事になります。
自分はこの記事を参考にしました
=> https://qiita.com/roworks/items/7ef12acabf9679561d84

pod installを行うので
Jenkins端末にcocoapodsをインストールしておいてください
また、pod install完了済みのprojectを使用するため、xcworkspaceを指定しています。

sudo gem install cocoapods
pod setup

シェル本文

#!/bin/bash -l

#ビルドシェルの実行
echo "=======================Unity build=============================="
${BUILD_SHELL_ROOT}/iOS_dev.sh

echo "======================pods Install==============================="
cd ${WORKSPACE}/"Unityで指定した保存先"
pod install --repo-update


echo "======================xcodebuild 開始============================"
xcodebuild \
-allowProvisioningUpdates \
-workspace Unity-iPhone.xcworkspace \
-scheme Unity-iPhone \
archive \
-archivePath "${WORKSPACE}/build_archive/archive" \
-configuration Debug

echo "========================ipaExport 開始============================"
xcodebuild \
    -exportArchive -archivePath "${WORKSPACE}/build_archive/archive.xcarchive" \
    -exportPath "${WORKSPACE}/build_archive" \
    -exportOptionsPlist ${WORKSPACE}/Tools/plist/exportOptions.plist

Androidのシェル

特に説明することもなく、シェルを実行すればapkが作られます。

#ビルドシェルの実行
${BUILD_SHELL_ROOT}/android_dev.sh 

DeployGateにアップロード

この記事を参考
https://qiita.com/ginrou@github/items/498d02acbbe9e1327bb7

apkFileの項目にipaを書いても動作します。

15
12
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
15
12