iOS開発でのJenkins導入

#iOS開発でのJenkins導入
＊Jenkinsの構築は記載してません。
＊Apple申請手順は記載してません。
##構成(やりたい事)
####Gitで管理しているプロジェクトをJenkinsを使ってビルドしてDeployGateへ登録する(アップル申請用ipaファイルも作成)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/8c04edd7-156f-5314-5e76-467816377609.png)

##1. Jenkins導入4つのメリット
###(1)いざという時に自信を持ち安心してリリースできる
・リポジトリへのPush時にビルドテストを実施したり、デイリービルドを行うことでいつでも何処でも安定した成果物を所持できる。
###(2)継続的なフィードバックを得られる
・開発環境を持っていない人にも最新のアプリを動かしてもらえるようになる。
・継続的にフィードバックを得ることで実装の軌道修正が早期の段階で可能になる。
###(3)ビルドの手間を削減できる
・プログラマーの開発環境に依存し、別の環境だとビルドできないことを無くせる。
・ビルドを人の手で行うとヒューマンエラーが生じやすい。
・ルーチンワークを自動化することで作業時間を減らせる。
###(4)品質を向上させることができる
・継続的にビルド、テストをすることで問題のある部分を早期に発見しやすく原因も特定しやすい　　　
・問題を早期に修正でき品質を向上させることができる

*＊面倒臭い小さな作業もコツコツと自動化することによって開発チームにとっての資産になるのではないでしょうか*

##2.iOSリリースの問題点
・リリース手順がAndroidに比べて煩雑
・チームで開発していると開発環境とリリース物で動作が異なる可能性がある
・リリース作業が特定の人が行い秘伝のタレ化する

##3. 構築手順(ビルド〜配布、通知まで)
###(0)必要なもの
・開発作業用PC
・Jenkins用サーバ
・iOSビルド用PC

###(1)Jenkinsインストール
####(1-1)サーバにJenkinsをインストール
####(1-2)ノード作成
*＊「ノード」スレーブと呼ばれるビルドを行うためのマシンのこと*
・「Jenkinsトップページ」=>「Jenkinsの管理」=>「ノードの管理」=>「新規ノード作成」
・ノード名を入力 => Permanent Agentを選択 => 「OK」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/caef9f56-ccdb-90e4-3e29-71514ca446cd.png)
・「リモートFSルート」「ラベル」「起動方法」を設定して「保存」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/71a3c19c-047c-5f15-a963-c8c714b86be9.png)
・slave-agent.jnlpを取得する(下記画像の名前「slave_iOS」をクリック => 「Launchボタン」ダウンロード)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/7abdcbf6-9f24-b3ca-aee2-442ef3b73e5a.png)


###(2)ノード(slave)起動
####(2-1)ビルド用PC(Mac)にダウンロードした「slave.jar」を渡す
####(2-2)ダウンロードの際にJenkinsの画面に表示されていた起動スクリプトを実行(ビルド用PC側で実行)
EX)$ java -jar slave.jar -jnlpUrl http://12.345.678.111:8080/computer/slave_iOS/slave-agent.jnlp -secret a6c13f732185037f4a6ad0f2b5e3f4074163482da20f5c22fe8048006d1b212a
*(2)の作業でビルド用マシーンとJenkinsマシーン接続された状態になります。

###(3)XCodeプロジェクト(アプリ)設定
####(3-1)Certificate作成(Apple Developper)
####(3-2)AppID作成(Apple Developper)
####(3-3)Provisioning作成(Apple Developper)
####(3-4)開発マシーンにProvisioningProfile、Certificate、秘密鍵を登録
####(3-5)ビルド用PC(Mac)にProvisioningProfile、Certificate、秘密鍵を登録

###(4)ジョブ作成(Jenkins)
Jeninsトップの「新規ジョブ作成」から「任意のジョブ名」を入力し、「フリースタイル・プロジェクトのビルド」を選択しOK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/3e55d474-4f3c-6c52-76e6-8bd8f7581ec8.png)
####(4-1)ラベルを指定して実行するノードを制限する
ノード作成時に入力したラベルを指定(入力)する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/86017a87-a35b-9e77-2023-9cf931d6ce91.png)

####(4-2)Gitリポジトリを指定する
ビルドする対象プロジェクトのGitリポジトリを指定する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/1838c58c-f1cf-9faf-3afa-02073b6f6fd7.png)
＊SSHで接続する場合はgithubに登録した公開鍵に対応する秘密鍵を認証情報に追加する

####(4-3)ビルド開始前にワークスペースを削除する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/9ed0e349-511d-abac-f055-7f03200d3158.png)

####(4-4)実行するシェルを作成
#####シェルで実行させること
- ビルド
- ipaファイル作成(DeployGate用、Apple申請用)

#####事前準備1
各ファイル名を控えておく

- ワークスペース名(プロジェクト名.xcworkspace)   *プロジェクトの場合はプロジェクト名.xcodeproj
- スキーム名
- 証明書名
- プロビジョニング識別子(例:1122f333-e4e4-5fd5-b666-78984b1f2018)
- プロビジョニング名
- チームID(例:123R4VHX5T)

#####事前準備2
- SigningをAutomaticallyからmanualに変更するsed用ファイル[ファイル名: ./changeSigning]
- ipaファイル作成用設定ファイル(DeployGate用)[ファイル名: ./Option/exportOptions_DeployGate.plist]
- ipaファイル作成用設定ファイル(Apple申請用)[ファイル名: ./Option/exportOptions_Apple.plist]

```bash:SigningをAutomaticallyからmanualに変更するsed用ファイル
#SigningをAutomatically から 証明書を使うモードに切り替える
s/Automatic/Manual/g
s/iPhone Developer/iPhone Distribution/g
# プロビジョニングプロファイルを設定
s/PROVISIONING_PROFILE = "";/PROVISIONING_PROFILE = "1122f333-e4e4-5fd5-b666-78984b1f2018";/g
s/PROVISIONING_PROFILE_SPECIFIER = "";/PROVISIONING_PROFILE_SPECIFIER = "ProvisioningProfile名";/g
```

```bash:ipaファイル作成用設定ファイル(DeployGate用)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>enterprise</string>
    <key>teamID</key>
    <string>123R4VHX5T</string>
</dict>
</plist>
```

```bash:exportOptions_Apple.plist(ipaファイル作成用設定ファイル*Apple申請用)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>app-store</string>
    <key>teamID</key>
    <string>123R4VHX5T</string>
    <key>uploadBitcode</key>
    <false/>
    <key>uploadSymbols</key>
    <true/>
    </dict>
</plist>
```




シェルスクリプト内に記載して行く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/cba3dfcd-58f5-8026-0357-4273fc1c9beb.png)

#####内容

```bash
# プロジェクト名
PROJECT="ProjectName.xcodeproj"

# ワークスペース名
WORKSPACE="ProjectName.xcworkspace"

# スキーム名 
SCHEME="SchemeName"

# 証明書名(作成した証明書名を設定)
SIGN="iPhone Distribution: Hoge Hoge Corporation"

# ProvisioningProfile
PROVISIONING="ProvisioningProfileName"

#SigningをAutomaticallyからManualへ変更(開発中はSigningをAutomatically manage signingに設定しているため)
sed -f ./changeSigning ./ProjectName.xcodeproj/project.pbxproj > ./ProjectName.xcodeproj/test; rm -rf ./ProjectName.xcodeproj/project.pbxproj; mv ./ProjectName.xcodeproj/test ./ProjectName.xcodeproj/project.pbxproj

#ビルド(DeployGate用)
xcodebuild -sdk iphoneos \
-workspace ./"${WORKSPACE}" \
-scheme "${SCHEME}" \
-configuration Debug archive \
-archivePath ./Archive/Develop \
CODE_SIGN_IDENTITY="${SIGN}" \
PROVISIONING_PROFILE_SPECIFIER="${PROVISIONING}"

#ビルド(Apple申請用)
xcodebuild -sdk iphoneos \
-workspace ./"${WORKSPACE}" \
-scheme "${SCHEME}" \
-configuration Release archive \
-archivePath ./Archive/Release \
CODE_SIGN_IDENTITY="${SIGN}" \
PROVISIONING_PROFILE_SPECIFIER=${PROVISIONING}

#ipaファイル作成(DeployGate用)
xcodebuild -exportArchive -archivePath ./Archive/Develop.xcarchive \
-exportPath ./ipa/develop \
-exportOptionsPlist ./Option/exportOptions_DeployGate.plist

#ipaファイル作成(Apple申請用)
xcodebuild -exportArchive -archivePath ./Archive/Release.xcarchive \
-exportPath ./ipa/release \
-exportOptionsPlist ./Option/exportOptions_Apple.plist
```

####(4-5)ビルド後(DeployGateに登録する)(RocketChatに投稿する)*slackにも投稿できます。

###(5). ビルド後の処理
####(5-1)成果物を保存(ipaファイルを保存する)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/b7297f98-d7cd-f879-1631-326ad9af7c9f.png)
*保存するipaファイルパスを指定

####(5-2)DeployGateに登録する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/08f99fef-34e2-438f-80a6-995a99910633.png)
(API Key)DeployGateのアカウント情報ページに記載されています
(Username)DeployGateでの登録名
(APK File)アップロードするipaファイルパスを指定
(Build Notes)メモ

####(5-3)RocketChatに投稿する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/3fc865a9-998e-21cc-f0b4-8ead8bdcb9ca.png)
*RocketChatのプラグインを入れる


##最後に
必要となる知識が多いので構築するために苦労はあるかもしれませんが一度使えるようになると凄く便利ですので是非。

「必要なモノ、知識」
・Jenkinsをインストールする機器
・ビルドする機器(MacOS)
・Jenkinsの基礎
・iOSアプリリリース知識
・DeployGate
・Bash
・xcode周りのコマンド
・エラー出力から自力で修正する根性

![image.png](https://qiita-image-store.s3.amazonaws.com/0/59015/f34858b3-211f-61f8-cfc2-a2c6cbaf6509.png)