FastlaneでReactNativeのデプロイを自動化する(ios)

# 手動作業を自動化する

ReactNativeで作成したアプリを内部テスト(TestFlight)する際に、手動でMyAppに上げるところを`Fastlane`を使用し、自動化します。
android版はこちら↓
[FastlaneでReactNativeのデプロイを自動化する(android)](https://qiita.com/kenkono/items/4b58f09eb5ffa177eeeb)

# Fastlaneのインストール
iosフォルダへ移動します。
そして`Gemfile`を作成します。(FastlaneはRuby製のツールです)

```
sudo gem install bundler
cd ios
bundle init
```

`Gemfile`に下記を追加します。

```ruby:Gemfile
gem "fastlane"
```

`Fastlane`インストールのため、updateします。

```
bundle update
```

# MyAppの作成
アプリのアップロード先となるMyAppの作成をFastlaneで実行します。

```
bundle exec fastlane produce
```

質問に答えていきます。

```

// Apple IDの入力
Your Apple ID Username:hogehoge@hogehoge.com
Multiple teams found on the Developer Portal, please enter the number of the team you want to use:
// Teamを選択
1) ****** "HOGEHOGE INC." (Company/Organization)
2) ****** "YourStand, inc." (Company/Organization)
1
// Bundle IDの入力
App Identifier (Bundle ID, e.g. com.krausefx.app):
com.hogehoge.app
// アプリ名
-> check the general at ios/ReactNativePlatform.xcodeproj
App Name: テスト
-> you can choose any name
1) "HOGEHOGE INC." (11111111)
2) "YourStand, inc." (2222222)
1
```

入力が完了すると、apple developer内のMyAppにApp Nameに指定した名前のプロジェクトが作成されます。

# Fastlaneの初期化

```
bundle exec fastlane init
```

質問に答えます。

```
1. 📸  Automate screenshots
2. 👩‍✈️  Automate beta distribution to TestFlight
3. 🚀  Automate App Store distribution
4. 🛠  Manual setup - manually setup your project to automate your tasks
? 3
1. ReactNativePlatform-tvOS
2. ReactNativePlatform
? 2
[18:35:26]: Apple ID Username:
hogehoge@hogehoge.com
Multiple App Store Connect teams found, please enter the number of the team you want to use:
1) ****** "HOGEHOGE INC." (Company/Organization)
2) ****** "YourStand, inc." (Company/Organization)
1
Multiple teams found on the Developer Portal, please enter the number of the team you want to use:
1) "HOGEHOGE INC." (11111111)
2) "YourStand, inc." (2222222)
1
[18:39:54]: Would you like fastlane to manage your app's metadata? (y/n)
y
```
現在地に`fastlane`フォルダができます。

# ratingの作成
`ios/fastlane/Deliverfile`を作成し、下記を記述します（アプリによって、数字は変更してください）

```ruby:Deliverfile
{
    "CARTOON_FANTASY_VIOLENCE": 0,
    "REALISTIC_VIOLENCE": 0,
    "PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,
    "PROFANITY_CRUDE_HUMOR": 0,
    "MATURE_SUGGESTIVE": 0,
    "HORROR": 0,
    "MEDICAL_TREATMENT_INFO": 0,
    "ALCOHOL_TOBACCO_DRUGS": 0,
    "GAMBLING": 0,
    "SEXUAL_CONTENT_NUDITY": 0,
    "GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
    "UNRESTRICTED_WEB_ACCESS": 0,
    "GAMBLING_CONTESTS": 0
  }
```

# fastfileの編集

`ios/fastlane/Fastfile`を下記のように編集します。`hogehogeapp`の部分はアプリ名によって変わってきます。

```
default_platform(:ios)

platform :ios do
  // descは説明文ですので、任意の文を挿入
  desc "Push a new release build to the App Store"
  // releaseに関する設定
  lane :release do
    // build番号をfastlane実行の度に自動で上げる
    increment_build_number(xcodeproj: "hogehogeapp.xcodeproj")
    match(type: "appstore")
    build_app(scheme: "hogehogeapp")
    upload_to_app_store(
      skip_waiting_for_build_processing: true
    )
    clean_build_artifacts
  end

  // testflightに関する設定
  desc "Push a new release build to TestFlight"
  lane :beta do
    increment_build_number(xcodeproj: "hogehogeapp.xcodeproj")
    match(type: "appstore")
    build_app(scheme: "hogehogeapp")
    upload_to_testflight(
      skip_waiting_for_build_processing: true
    )
    clean_build_artifacts
  end
end
```

### cocoapodsを使用している場合
`.xcworkspace`を使用している前提でfastfileを実行したい場合、`pod install`を実施するコードとbuild_appの記述を書き換えることで対応できます。

```
default_platform(:ios)

platform :ios do
  desc "Push a new release build to the App Store"
  lane :release do
    # increment機能は.xcworkspaceには使用できないため削除
    # increment_build_number(xcodeproj: "hogehoge.xcodeproj")
    match(type: "appstore")
    # pod installの実行
    cocoapods
    # workspaceを追加
    build_app(workspace: "hogehoge.xcworkspace", scheme: "hogehoge")
    upload_to_app_store(
      skip_waiting_for_build_processing: true
    )
    clean_build_artifacts
  end

  desc "Push a new release build to TestFlight"
  lane :beta do
    # increment機能は.xcworkspaceには使用できないため削除
    # increment_build_number(xcodeproj: "hogehoge.xcodeproj")
    match(type: "appstore")
    # pod installの実行
    cocoapods
    # workspaceを追加
    build_app(workspace: "hogehoge.xcworkspace", scheme: "hogehoge")
    upload_to_app_store(
      skip_waiting_for_build_processing: true
    )
    clean_build_artifacts
  end
end
```
また、`gemfile`への記述を追加します。

```ruby:Gemfile
gem "fastlane"
gem 'cocoapods'
```


# 証明書の作成
iosのデプロイをfastlaneで実施する場合、事前に証明書関連をgithub上に格納しておき、実行する度にレポジトリを参照することになります。
まず、Github上に任意のrepositoryを`private`で作成します（`public`は推奨されていません)。

続いて下記コマンドを入力

```
bundle exec fastlane match init
```

質問に答えます。

```
[19:04:30]: fastlane match supports multiple storage modes, please select the one you want to use:
1. git
2. google_cloud
? 1
[19:05:12]: URL of the Git Repo:-> 作成したrepositoryのgit cloneアドレス(SSHの方)

```

`ios/fastlane/Matchfile`が作成され、先程回答したgithub等の情報が記載されています。
続いて証明書を作成し、repositoryに格納します。

```
bundle exec fastlane match development
```

Githubのパスワードを入力します。

```
Passphrase for Git Repo: ******
```
### エラーの発生
証明書が制限数超えており、エラーが出る場合があります。

```
[!] Could not create another Development certificate, reached the maximum number of available Development certificates.
```

この場合、既に期限が切れている証明書を削除して容量を開ける必要があるので`nuke`コマンドを実行します。
公式ドキュメントの説明↓
[Nuke](https://docs.fastlane.tools/actions/match/#nuke)

```
bundle exec fastlane match nuke development
bundle exec fastlane match nuke appstore
```

# Xcode上の設定
`general`に移動します。
- `Automatically manage signing`のチェックを外す。
- Signing(Debug) は `match Development ...`
- Signing(Release)は `match Appstore ...`
![Screen Shot 2019-08-24 at 13.44.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291139/21941961-ff20-6a02-d3c8-01e6c0ce2fc3.png)

`tests`についても下記のように変更します。
Signing(Debug)
- Signing Certificate: iOS Developer  

Signing(Release)
- Signing Certificate: iOS Distribution
![Screen Shot 2019-08-24 at 13.49.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291139/01697228-3a83-0e05-d216-1822a8bcf981.png)

`Build settings`に移動し、`code signing identity`を検索します。
下記のように編集
- Debugは iOS Developer
- Releaseは iOS Distribution 
![Screen Shot 2019-08-24 at 13.52.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291139/aa62af67-ede1-525a-65aa-60c423543d9b.png)

プロジェクト名/info.plistに移動します。
任意の場所で右クリックし、列の追加→`ITSAppUsesNonExemptEncryption`を追加します。
入力すると下記のように`App Uses Non-Exempt Encryption`に変わります。
![Screen Shot 2019-08-24 at 13.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291139/5cdc4e8d-b215-d2d0-4ebf-89f3c775a88c.png)

アプリのアイコン画像も、設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291139/baa84f61-d3dd-c785-5bf1-a7aae5978633.png)


# スクリーンショットの挿入
`ios/fastlane/screenshots`にアップするスクリーンショットを格納しておきます。


# アプリをMyAppにデプロイする

下記コマンドを実行

```
bundle exec fastlane beta
```

終了後MyAppに行くと、アプリがtestflight上にアップされています。

# Bitriseへ組み込む
CIツールの`Bitrise`を使用すると、githubにpushした際に自動的にfastlaneを実行することができます。
詳細は下記へ↓
[FastlaneのコマンドをBitriseに組み込む(ios,ReactNative)](https://qiita.com/kenkono/items/b31bc3c3a5aed236643c)