【iOS】fastlaneでipaファイルを作成して、fabric crashlyticsでベータ版を配布し、Slackで完了通知を行う

# fastlaneのインストール

```
sudo gem install fastlane
```

## Bundlerを利用してインストールする場合

```
sudo gem install bundler
```

bundle initでGemfileを用意し、

```
bundle init
```

以下を記述してインストールします。

```:Gemfile
source "https://rubygems.org"
gem 'fastlane'
gem 'cocoapods'
```

インストール実行

```
bundle install
```

bundlerを利用する場合は、bundle exec fastlane (test)で実行します。

# Fastlaneファイルを作成

プロジェクト直下で以下のコマンドを実行してfastlaneファイルを作成します。

```
bundle exec fastlane init
```

initを実行するとAppleID等の質問をされるので、適宜答えていきます。
質問が完了すると、Fastfileが作成されます。

# Fastfileに実行する処理を記入する

初期のFastfileの中身はこのような感じになっています。
ここに実行したい処理を書いていきます。

```:Fastfile
default_platform :ios

platform :ios do
  before_all do
    # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
    
    
  end

  desc "Runs all the tests"
  lane :test do
    scan
  end

  desc "Submit a new Beta Build to Apple TestFlight"
  desc "This will also make sure the profile is up to date"
  lane :beta do
    # match(type: "appstore") # more information: https://codesigning.guide
    gym # Build your app - more options available
    pilot

    # sh "your_script.sh"
    # You can also use other beta testing services here (run `fastlane actions`)
  end

  desc "Deploy a new version to the App Store"
  lane :release do
    # match(type: "appstore")
    # snapshot
    gym # Build your app - more options available
    deliver(force: true)
    # frameit
  end

  # You can define as many lanes as you want

  after_all do |lane|
    # This block is called, only if the executed lane was successful

    # slack(
    #   message: "Successfully deployed new App Update."
    # )
  end

  error do |lane, exception|
    # slack(
    #   message: exception.message,
    #   success: false
    # )
  end
end

```

## cocoapodsのインストール

pod installの実行は、before_allにcocoapodsと書くことで実行されます。

```:Fastfile
lane :pod_install do
  cocoapods
end
```

なお、pod installは毎回行うので、before_allに書いてもいいです。

```:Fastfile
platform :ios do
  before_all do
    cocoapods
  end
end
```

## ipaファイルの作成

ipaファイルの作成は、laneを作って以下の内容を実行します。

```:Fastfile
lane :create_ipa do

  gym(
    workspace: "sample.xcworkspace",
    configuration: "Debug",
    scheme: "sample",
    clean: true,
    output_name: "sample.ipa",
    export_method: "ad-hoc"
  )

end
```

cocoapodsを使わずに、projectファイルで実行する場合は、以下のようになります。

```:Fastfile
project: "sample.xcodeproj"
```

Fastfileを作成したらコマンドを実行します。

```
bundle exec fastlane create_ipa
```

## fabric crashlyticsを利用してipaを配布する

https://fabric.io/kits/ios/crashlytics/install
を参考にセットアップが完了したら、crashlyticsからAPI KeyとBuild Secretを用意します。

Fabricにログインし、
Setting（右上にある歯車マーク） -> ORGANIZATION　-> api tokenを取得したい組織を選択 -> API Key　&　Build Secret
と選択します。

![crashlytics_api_key.png](https://qiita-image-store.s3.amazonaws.com/0/194104/20a92d86-62f6-fd8e-4955-0083466ebe10.png)

ここから、API KeyとBuild Secretを利用します。
Fastfileを開き、配布用のlaneを作成します。

```:Fastfile
lane :deploy_ipa do

  crashlytics(
    crashlytics_path: './Pods/Crashlytics/iOS/Crashlytics.framework',
    api_token: <FABRIC_API_KEY>,
    build_secret: <BUILD_SECRET>,
    ipa_path: 'sample.ipa',
    notifications: true,
    notes: "fastlane deploy ipa",
    groups: "group1"
  )

end
```

**・notes:**
notesはBetaページのRelease Notes表示されるところです。（後で変更可）
**・groups:**
groupsはManage Groupsで設定したグループに送る設定です。

　　
Fastfileを作成したらコマンドを実行します。

```
bundle exec fastlane deploy_ipa
```

成功したら、テスターに登録してある人にメールが届きます。
メールからsafariを開いてアプリのインストールが行えます。

## Slackで完了通知を行う

Slackへ通知するには、SlackのWebhook URLを取得してENV["SLACK_URL"]に設定する必要があります。initの時点では、# でコメントアウトされていますので、# を削除する必要があります。

Slackのteamを作成したら、以下のURLにアクセスして取得します。
https://slack.com/services/new/incoming-webhook

![slack_webhook.png](https://qiita-image-store.s3.amazonaws.com/0/194104/a051e402-d7ae-eeda-ded9-fe085cec477e.png)

右上でteamを選択して、真ん中にある「Choose a channel...」からchannelを選択し、**Add Incoming WebHooks integration** ボタンを押すと、Webhook URLが表示されます。

Webhook URLを**ENV["SLACK_URL"]**に設定します。

```:Fastfile
before_all do
  ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
end

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

after_all do |lane|
  # This block is called, only if the executed lane was successful
  slack(
    message: "Successfully deployed new App Update."
  )
end

error do |lane, exception|
  slack(
    message: exception.message,
    success: false
  )
end
```

after_all doは成功した場合のslackのメッセージとなります。
error doは失敗した時のメッセージとなります。