Firebase+CircleCi+FastlaneでAdHoc配信を自動化する

# はじめに

今回は以前投稿したFirebaseAppDistributionのデプロイ作業を`CircleCi`・`Fastlane`を用いて自動化していきたいと思います。実装前に下記の準備項目が必要になります。

#### 事前準備

- Firebaseプロジェクト
- Fastlaneの導入
- AppleDeveloperProgram
- FirebaseCLIの導入
  - [以前の記事に導入手順があります](https://qiita.com/yum_fishing/items/48e9b147380930447d0a#firebasecli%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

# 実装フロー

1. Fastlane Matchを仕様してCI環境でもadhocの証明書を参照できるようにします。

2. CircleCiからadhoc証明書を参照できるように権限を付与します。

3. CircleCiからFirebaseにアクセスするために、環境変数を設定します。

4. FastlaneにAppDistributionにデプロイするためのLaneを追加します。

5. CircleCiのワークフローに`4.`で作成したレーンを追加します。

# Fastlane Matchの導入

まずは、証明書に関する情報を保存して置くためのリポジトリを作成しておきます。

```
  git@github.com:your_github_name/certificates.git
```

次にFastlaneのMatchFileを下記のコマンドで設定します。ここで、設定する`github-url`はHTTPSの場合CIからデプロイするときにErrorが発生する可能性があるので、SSHで設定しておきます。また`Passphrass for Git repo`で設定する値は後々メンバーに共有するなど使用するタイミングがあるので、控えておきましょう。

```
  $ fastlane match init
```

次に開発証明書と配信用証明書をそれぞれGitリポジトリに作成します。

```
  $ fastlane match development
  $ fastlane match adhoc
```

次に作成した証明書とプロファイルを取得し、Xcodeの`Signing&Capabilities`にプロファイルを設定しておきましょう。

```
  $ fastlane match development --readonly
  $ fastlane match adhoc --readonly
```

<img width="648" alt="スクリーンショット 2020-02-14 20.48.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/52c9e5d5-dd8f-9a9d-5527-c93c13fb4887.png">


# CircleCiにCertificatesリポジトリアクセス権限を付与する

CircleCiのプロジェクト画面に移動してカレントユーザのSSH keysを登録します。

https://circleci.com/docs/ja/2.0/add-ssh-key/ の通り`Checkout SSH keys`から登録を行います。

# CircleCiにFirebaseTokenの環境変数を登録する

CI用のFirebaseTokenを`FirebaseCLI`から取得します。

```
  $ firebase login:ci
```

ログインに成功して表示されたtokenをCircleCiの環境変数に登録します。

<img width="272" alt="スクリーンショット 2020-02-14 21.06.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/7b04e2be-95b9-80c6-8771-3a84639e23f7.png">
<img width="700" alt="スクリーンショット 2020-02-14 21.07.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/407526b5-fb6c-3723-7cf1-b71b97def886.png">


# FastFileの実装

まずはFastlaneからAppDistributionを使用するためのプラグインを追加します。

```
  $ fastlane add_plugin firebase_app_distribution
```

FastFileにLaneを追加します。

```Fastfile.rb
default_platform(:ios)
WORKSPACE = "App.xcworkspace"
SCHEME = "App"
platform :ios do
  before_all do
    # https://circleci.com/docs/ja/2.0/testing-ios/
    setup_circle_ci
  end

  desc 'Runs except unit_test tests'
  lane :unit_test do
    scan(
      scheme: SCHEME
    )
  end

  desc 'Deploy to Firebase'
  lane :adhoc do
    # matchでadhoc証明を行います。
    match(type: "adhoc", readonly: true)
    # https://docs.fastlane.tools/actions/gym/ でipaを作成します。
    gym(
      workspace: WORKSPACE,
      scheme: SCHEME,
      configuration: "Staging",
      export_method: "ad-hoc"
    )
    # デプロイ
    firebase_app_distribution(
              app: "1:298717447283:ios:f90cc26d3b9a7423725606",
              testers: "tester_email@firebase.com,
              release_notes: "Lots of amazing new features to test out!",
              firebase_cli_path: "./node_modules/.bin/firebase"
    )
  end
end
```

# CircleCi-Config.ymlの実装

```config.yml
defaults: &defaults
  working_directory: ~/app
  macos:
    xcode: "11.3.0"
version: 2
jobs:
  unit_test:
    <<: *defaults
    steps:
      - checkout
      - run: bundle install --path vendor/bundle
      - run:
          name: Fastlane
          command: bundle exec fastlane unit_test
  adhoc:
    <<: *defaults
    steps:
      - checkout
      - run: bundle --path vendor/bundle
      - run:
          name: Install Firebase Tools
          # FirebaseCLIをインストール
          command: npm install firebase-tools
      - deploy:
          name: Deploy
          # Fastfileで作成したlaneを呼び出す
          command: bundle exec fastlane adhoc

workflows:
  version: 2
  build-and-deploy:
    jobs:
      - unit_test
      - adhoc:
          # unit_test完了後にデプロイ
          requires:
            - unit_test
```

# さいごに

これでPRが作成されるたびにAppのAdHocがテスターに配信されるようになります。Appをインストールする手順は以前の[記事](https://qiita.com/yum_fishing/items/1f0a5eda41426cc1a510)でも投稿しています。