Jenkinsさんでビルドしてスマホでの確認を楽ちんに

※これ書いたの２年位まえなので情報メガッサ古いので注意してくださいね★

# Unityのビルドが面倒くさい……

会社でスマホ向けのゲームをUnityで作っているのですが、Unityのビルドって面倒くさいですよね！

1. コードをチェックアウトしてくる
2. Unityを起動する
3. Android向けにビルドする
4. iOS向けにビルドする
5. 実機で遊びたい会社の人(エライ人含む)の端末にせっせとインストールする

こんなことやってると一日仕事です！ 僕の一日は adb install をひたすら打ち続けるだけで浪費されてしまいます。
しかも会社にはいろんな人がいます。

* 企画の人 / 営業の人 / マネージャー つまりUnity使わない人
* Windowsで開発してるけど、使ってるスマホはiPhoneの人
* 外部の協力会社の人(テスターさんとか)

こんないろんな人達のためにひたすらインストールし続けるとか非生産的すぎます(　ﾟ皿ﾟ)ｷｰｯ!!

# そこでJenkinsさんの出番です

CI (Continuous Integration)とか継続的インテグレーションが随分と浸透してきました。簡単に言うとプログラムを自動で、継続的に、ビルドしてくれる仕組みとでも思ってください。

CIサーバとしてよく利用されるのが[Jenkins](http://jenkins-ci.org)さんです。Jenkinsさんは継続的インテグレーションの手助けをしてくれるプログラムです。

JenkinsさんにUnityプロジェクトのビルドのやり方を登録してあげれば、あら簡単、リンクをポチるだけで自動でビルドをしてくれるじゃないですか！

![Jenkinsさんで簡単ビルド](http://dl.dropbox.com/u/31504376/Qiita/yuru_jenkins.png)

Jenkinsさんでスマホ向けにビルドをする方法は[【研究課題レポート抜粋】Jenkins+Unityで構築するスマフォアプリビルドサーバー](http://ameblo.jp/principia-ca/entry-11010391965.html) を参考にして構築しました。アメーバさんありがとう！

# ちょっと改良

でも、このとおりだと、ちょっといろいろ、面倒なので若干の改良を加えました。

## ビルド対象のシーンを自動で

先ほどのブログでは、ビルド対象のシーンを配列に登録して管理しています。

```c#:BatchBuild.cs
private static string[] scene = {"Assets/_Scenes/PiggCube.unity"};
```

この方法ですと、シーンが増えるたびに配列にシーンを追加しなおさないと行けないのですごく手間です。
ですので、BuildSettingsのScenes in Buildに入っているシーンを取得して、配列にして返す関数を用意しました。

```c#:BatchBuild.cs
private static string[] GetScenes() {
    ArrayList levels = new ArrayList();
    foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes) {
        if (scene.enabled) {
            levels.Add(scene.path);
        }
    }
    return (string[]) levels.ToArray(typeof(string));
}
```

これを使えばシーンを追加しても、ビルドスクリプト自体に手を入れなくてよくなります。


## Jenkinsが実行するシェルスクリプトにエラー処理を追加

上のスクリプトですと、Unityからプロジェクトを吐き出すところでしかエラーハンドリングがされていません(exit codeも必ず1が返却される……)。
ですので、エラーハンドリングを追加しました。xcodeでappファイルを作るところと、ipaファイルに変換する部分です。

```bash:jenkins-build-script.sh
#----------------------------------------------------------------------
# コマンドラインでのipaと.dSYMファイルの作成
#----------------------------------------------------------------------

#------- xcodeプロジェクトをビルドして .appと.dSYMを生成する -------#
BUILD_OPT_MAKE_DSYM="GCC_GENERATE_DEBUGGING_SYMBOLS=YES DEBUG_INFORMATION_FORMAT=dwarf-with-dsym DEPLOYMENT_POSTPROCESSING=YES STRIP_INSTALLED_PRODUCT=YES SEPARATE_STRIP=YES COPY_PHASE_STRIP=NO"
xcodebuild -project "${XCODE_PROJECT_CONFIG_PATH}" -configuration "${CONFIGURATION}" CODE_SIGN_IDENTITY="${IDENTITY}" $BUILD_OPT_MAKE_DSYM

# xcodeプロジェクトのビルドに失敗した場合
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
  cat "can not build app file"
  exit $EXIT_CODE
fi

#------- .appからipa作成 -------#
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${TARGET_APP_PATH}" -o "${IPA_FILE_PATH}"

# ipaへの変換に失敗した場合
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
  cat "can not build ipa file"
  exit $EXIT_CODE
fi
```

これをやらないと何が困るかというと、例えば**iPhone Developerの証明書の有効期限が切れた時**。
こういう場合は xcodeでのビルドでコケるのですが、エラーハンドリングしていないとJenkinsさんは正常終了したと勘違いして処理を終わらせてしまします。エラーでコケてるのに……。
証明書は忘れた頃に突然有効期限が切れるので、注意が必要です。

# ビルドは楽になったがががが

さてさて、これでビルドは楽になった！
Jenkinsさんでリンクをワンクリックするだけでipaファイルとapkファイルが出来上がる！　ひゃっほー！

……と思ったのですが、これではまだまだ**インストール地獄から解放はされていません**。
apkやipaファイルをJenkinsさんからダウンロードして、みんなそれぞれのマシンで自分のスマホにいれればいいじゃない！　と思うのですが、営業さんや企画さんやエライ人には敷居が高すぎて無理です！
iOS向けはしかたがない……iPhone構成ユーティリティとかxcodeのオーガナイザーから泣く泣くインストールしましょう。。。
でもandroidは……。apkファイルさえダウンロードできれば簡単にスマホにインストールできるじゃないか！

## 企業特有の事情

Jenkinsさんが、手持ちのスマホからアクセスできる場所に設置されていれば問題ありません。
Jenkinsさんにandroid端末からアクセスして、目的のapkファイルをダウンロードすればあっという間にインストール完了です。

でも、多くの企業では社外からアクセスできない社内ネットワーク上にJenkinsさんが置かれているのではないでしょうか？
さらに、スマホの社内ネットワーク接続が禁止されてるとかとかとか。
つまり、インターネットからJenkinsさんにアクセスできない！　というシチュエーションが多いとおもいます。

あー、これは詰んだか。インストール祭りか。楽はできないのかーー。
……諦めたらそこでゲームは終了です。
androidはGoogle アカウントと紐付いています。

そ、そうだ！  **Google様を使おう！**

## Jenkinsでビルドした成果物をGoogle Driveにアップロードする。

Google Drive(旧名：Google Docs)ですが、ここ、わりかしなんでもアップロードできちゃいます。
Jenkinsさんが作った成果物をここにあげちゃえばいいんだ！

でもどうやって？

ここは徹底的に手抜きしましょう。
Google DriveにはMac用のクライアントアプリがあります。
これをインストールすると、**ローカルGoogle Drive用のディレクトリをリモートのGoogle Driveと同期してくれます**
そうです、Jenkinsさんの成果物をこのGoogle Drive用のディレクトリにおいてあげればいいだけです。

前述の、ビルド用のシェルスクリプトに一行

```bash:jenkins-build-script.sh
cp ${コピー元APKファイル} ${Google Drive用ディレクトリ}
```

を追加すればOKです。
あとはandroid端末から、Google Driveにアクセスして、apkファイルをダウンロードすればOK

営業さんや企画やさんやエライ人には「ここからダウンロードしてください」とGoogle DriveのURLを送り付ければあとはみんなが勝手にインストールしてくれるという寸法です！

注意点としては、Google Driveでの共有範囲の設定をきちんとやること。
これ、間違えると開発中のアプリが誰からでもアクセスできるなんていう恐ろしいことになるから注意が必要ですよ……。

**やった！　これでインストール地獄からも解放される！**
おめでとう！　ありがとう！

# で、iPhoneむけはどうすれば簡単になるの？

( ﾟдﾟ)ﾊｯ!

……だれか簡単になる方法があればご教授ください。