見出し画像

Firebase App Distribution で iOS アプリを自動配信する

Build サービスチームで Solution Architect をしている t_maru です。

前回は fastlane match を使って証明書をプライベートリポジトリから自動的に取得してビルドに使用する方法を紹介しました。
今回はビルドした成果物を開発者やテスター向けに公開するために利用できる Firebase App Distribution について CircleCI などのビルドコンテナ上から使う方法をご紹介します。

※ fastlane match を使わない証明書管理および iOS アプリビルド方法については次回以降ご紹介します。

Firebase App Distribution とは

Firebase App Distribution とは iOS / Android アプリ開発者やテスターに対してアプリを配布するために利用できるサービスです。他の Firebase サービスと同様、フルマネージドサービスなのでビルドした結果の ipa や apk を用意するだけで手軽に利用でき使い勝手がよいサービスです。

そもそもどういった場合にこのサービスを使うと良いかですが、以下のようなケースに有効ではないかと思います。

  • テスターや Product Owner など直接機能開発しているメンバー以外にアプリを配布したいとき

  • 現状の開発状況を逐次開発メンバーが把握したいとき

各開発者が自身で持っている端末に随時インストールして動作確認を行うことが簡単ですが、開発者でないメンバーの場合は App Store 以外からアプリをインストールすることは容易ではないので何かしらの仕組みが必要となります。

また、開発者であってもリアルタイムに他の開発者が開発したものを実機で確認するためには何らかの手段でアプリの配布を自動化しておくことで効率的に開発を進めることができるのではないでしょうか。

Firebase App Distribution の詳細は下記の公式ドキュメントをご確認ください。
https://firebase.google.com/docs/app-distribution?hl=ja

前提条件と配信する方法

Firebase App Distribution を経由したアプリ配布ですが、何でも配信できるかというと、そうではありません。

結論から申し上げると配布できるアプリは Ad Hoc ビルドされたアプリのみです。Ad Hoc ビルドとは、アプリをインストールすることのできる端末を事前に指定した状態で作られる ipa ファイルで、事前に指定された端末にしかインストールできないという特徴があります。

このため、用途としても先程挙げた Project の関係者のように事前に連絡を取ることができメンバーに対する配布に限られてきます。

iOS アプリの場合、Ad Hoc 以外にも TestFlight を経由した配布や企業向けの In House 配布などいくつか配布手段がありそれぞれをビルドするときに必要な証明書なども変わってきます。

証明書についてはこちらの記事で説明をしておりますので興味がありましたら御覧ください。

Ad Hoc タイプでビルドされたアプリの ipa が手元にあれば以下のいずれかの方法で Firebase App Distribution から配信することができます。

  • Web ブラウザで Firebase のコンソールを開き、手動で ipa をアップロードする

  • Firebase CLI を使いコマンドラインで ipa をアップロードする

今回は CircleCI でビルドした成果物を自動的にアップロードする方法 (Firebase CLI を使用した方法) をご紹介します。

CircleCI から自動的にアップロードするには

CircleCI からアップロードする前に、事前に Firebase Console (Web ブラウザ) でやっておく処理がありますので事前に下記を済ませておきます。

  • Firebase プロジェクトに iOS アプリを登録

  • テスターグループを作成し、テスターを追加する

  • Google Cloud Console で必要な権限を持ったサービスアカウントを生成しておく

上記の中で `Google Cloud Console で必要な権限を持ったサービスアカウントを生成しておく` という手順だけ少し解説と設定内容のサンプルが必要かと思いますので補足します。

Firebase に限った話ではありませんが、Cloud 上のサービスに対して何らかの操作を行うためには適切な権限が必要です。

よく `firebase login:ci` で生成される token をコマンドの引数で指定する例が紹介されていると思いますが、この token はログインに使ったユーザーの権限がそのまま割当されます。今回の場合は Firebase App Distribution だけの権限があればよいのに、例えば Firestore や Cloud Functions の管理権限など不要な権限が割当されている状態になってしまいますので、Cloud の大原則である最小限の権限割当を実現できないため注意が必要です。

サービスアカウントについてはこちらの記事で解説しておりますので興味がありましたら御覧ください。

今回のサービスアカウントに必要な権限は下記となりますので、サービスアカウントを作成後、下記の権限を割り当ててください。

  • Firebase アプリ配布管理者

CircleCI の config サンプル

以下に CircleCI から Firebase App Distribution に自動で ipa をアップロードするための workflow config のサンプルを掲載します。

※ 元々動いていた config をもとにしていますが、記事執筆時に再編成しており下記の状態では動作確認しておりません。もし実際に試してエラーが出た場合は、エラーメッセージ等を参考に適宜修正してご利用ください。

Firebase 関連で CircleCI の環境変数に事前に設定が必要な項目は下記です。

  • FIREBASE_APP_ID

    • Firebase に登録した iOS アプリの App ID です。Firebase Console から確認できます。

  • FIREBASE_SERVICE_ACCOUNT

    • 必要な権限を割り当てたサービスアカウントを base64 エンコードした文字列です。

※ これ以外にもアプリビルドに必要なものがありますのでご注意ください。ビルドの際に必要な環境変数については後半で紹介している前回の fastlane match を使った iOS アプリビルドに関する記事をご覧ください。

version: 2.1

commands:
  prepare-build:
    steps:
      - run:
          name: Set Timezone
          command: |
            sudo systemsetup -settimezone "Asia/Tokyo"
      - restore_cache:
          keys:
          - v1-gems-{{ checksum "Gemfile.lock" }}
      - run:
          name: Bundle install
          command: bundle check || bundle install
          environment:
            BUNDLE_JOBS: 4
            BUNDLE_RETRY: 3
      - save_cache:
          key: v1-gems-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

  prepare-firebase:
    steps:
      - run:
          name: Set up firebase-tools
          command: npm install -g firebase-tools
      - run:
          name: Decode Firebase service account
          command: |
            base64 -D -o ./service-account.json \<<< $FIREBASE_SERVICE_ACCOUNT

  upload-to-firebase:
    parameters:
      ipa-file-path:
        type: string
    steps:
      - run:
          name: Upload ipa to firebase app distribution
          command: |
            export GOOGLE_APPLICATION_CREDENTIALS=./service-account.json
            export COMMIT_HASH=$(git rev-parse HEAD)
            export COMMIT_MESSAGE=$(git log -1 --pretty='%s')
            firebase appdistribution:distribute <<parameters.ipa-file-path>>  --app $FIREBASE_APP_ID --groups Project-users --release-notes "${COMMIT_MESSAGE} / ${COMMIT_HASH}"

jobs:
  build-stg-adhoc:
    macos:
      xcode: "14.1.0"
    shell: /bin/bash --login -eo pipefail
    environment:
      BUNDLE_PATH: vendor/bundle
      LC_ALL: en_US.UTF-8
      LANG: en_US.UTF-8
    steps:
      - checkout
      - prepare-build
      - prepare-firebase
      - add_ssh_keys:
          fingerprints:
            - "証明書を保存している Repository に追加した ssh key の fingerprint"
      - run:
          # add_ssh_keys step とこのコマンドにより Additional key として追加した
          # github.com-cert の alias も含めて SSH による GitHub アクセスが適切に使用できるようになる
          command: |
            echo "HostName github.com" >> ~/.ssh/config
            echo "StrictHostKeyChecking no" >> ~/.ssh/config
      - run:
          name: Run tests
          command: make test-all
      - run:
          command: bundle exec fastlane build_stg_adhoc --verbose
      - store_artifacts:
          path: Archives
          destination: archives
      - upload-to-firebase:
          ipa-file-path: Archives/sample-app-stg-adhoc-${CIRCLE_BUILD_NUM}.ipa

workflows:
  build-stg-adhoc-wf:
    jobs:
      - build-stg-adhoc:
          filters:
            branches:
              only: main

上記では fastlane match を使った方法で記載しています。fastlane match を使った iOS アプリのビルド方法については前回の記事をご覧ください。

実際に Firebase App Distribution に iOS アプリをアップロードしているコマンドは下記になります。

firebase appdistribution:distribute <<parameters.ipa-file-path>> --app $FIREBASE_APP_ID --groups Project-users --release-notes "${COMMIT_MESSAGE} / ${COMMIT_HASH}"

ここでは事前に `Project-users` というテスターグループを作っている想定のコマンドで記載していますが、適宜変更していただいて大丈夫です。

`--release-notes` のパラメータで記載した内容は、各ユーザーが iOS 端末にアプリをダウンロードする際に表示されるため、どのような変更が含まれているのかを記載すると良いと思います。

今回は CI 環境から自動デプロイする形にしておりますので、Git のコミットメッセージとコミットハッシュを設定し、必要があればこれらの値から GitHub 上でどのコミットだったのかを追跡できるようにしています。

まとめ

今回は Firebase App Distribution の概要と、どういったケースで利用するのかを紹介し、CircleCI から自動ビルドした結果を CLI を使ってアップロードする方法について解説しました。

ネイティブアプリ開発をしている場合、開発者以外にもアプリを随時触って頂ける状況を作っておくとバグを早く見つけられたり、Product Owner のイメージしている出来になっているのかを早い段階で確認してもらえるようになりますので、こういったツールも活用して効率的にアプリ開発を進めてみてはいかがでしょうか。