Published on

モバイルアプリを CircleCI 上のみで簡単に配布することができる CircleCI App Distribution をリリースしました!

Authors
CircleCI App Distribution

モバイルアプリを CircleCI 上のみで簡単に配布することができる CircleCI App Distribution をリリースしました。

この記事ではこの CircleCI App Distribution の使い方と特徴について紹介します。


背景

よくある質問と回答

CircleCI ではモバイルアプリケーション(iOS/Android)のビルド、テスト、そして App Store / Play Store へのリリースを自動化することができます。

しかし、ビルドしたアプリケーション(主にデバック版)を iOS/Android デバイスに配布し検証するためには、CircleCI だけで完結することができませんでした。

そのため、これまでは Firebase App DistributionDeployGate などのサービスと連携する必要がありました。

これらの配布を CircleCI 内だけで実現できるようにしたのが、今回紹介する CircleCI App Distribution です。

使い方

CircleCI App Distribution は CircleCI Orb として公開しています。

CircleCI Developer Hub - tadashi0713/app-distribution

iOS/Android プラットフォームへビルドする CircleCI の CI/CD パイプラインの中に、この Orb が提供している upload_android, upload_ios を追加します。

パラメーターの path にはビルドしたバイナリ(apk, aab, ipa)のパスを指定してください。

# Android
steps:
  # Build Android binary
  - app-distribution/upload_android:
      path: demo.apk

# iOS
steps:
  # Build iOS Binary
  - app-distribution/upload_ios:
    path: demo.ipa

実行すると、CircleCI UI の Job の Steps の中に Generate QR Code(You can see QR Code in this step) があり、この Step をクリックするとコンソール画面に QR コードが表示されます。

QR Code

この QR コードを iOS / Android デバイスで読み取ると配布ページが表示され、対象のアプリケーションをインストールすることが可能です。

Distribution Page

GitHub Pull Request へのコメント

CircleCI App Distribution では comment_github_pr を用いることによって、この配信情報を GitHub の Pull Request へコメントすることができます。

事前に Github の Token(GITHUB_TOKEN)を作成し、CircleCIに保存する必要があります。

# Android
steps:
  # Build Android binary
  - app-distribution/upload_android:
      path: demo.apk
  - app-distribution/comment_github_pr

# iOS
steps:
  # Build iOS Binary
  - app-distribution/upload_ios:
    path: demo.ipa
  - app-distribution/comment_github_pr

GitHub PR

GitLab Merge Request へのコメント

CircleCI App Distribution では comment_gitlab_mr を用いることによって、この配信情報を GitLab の Merge Request へコメントすることができます。

事前に GitLab の Token(GITLAB_TOKEN)を作成し、CircleCIに保存する必要があります。

また、セルフホスト版の GitLab を利用している場合には、hostname をパラメーターに追加する必要があります。

# Android + GitLab Cloud
steps:
  # Build Android binary
  - app-distribution/upload_android:
      path: demo.apk
  - app-distribution/comment_gitlab_mr

# iOS + GitLab self-hosted
steps:
  # Build iOS Binary
  - app-distribution/upload_ios:
    path: demo.ipa
  - app-distribution/comment_gitlab_mr:
      hostname: example.gitlab.com
GitLab MR

Bitbucket Pull Request へのコメント

CircleCI App Distribution では comment_bitbucket_pr を用いることによって、この配信情報を Bitbucket の Pull Request へコメントすることができます。

事前に Bitbucket の Token(BITBUCKET_TOKEN)を作成し、CircleCIに保存する必要があります。

また、パラメーターとして対象のプロジェクトの repo_slugworkspace を追加する必要があります。

# Android
steps:
  # Build Android binary
  - app-distribution/upload_android:
      path: demo.apk
  - app-distribution/comment_bitbucket_pr:
      repo_slug: circleci-demo-android
      workspace: tadashi0713

# iOS
steps:
  # Build iOS Binary
  - app-distribution/upload_ios:
    path: demo.ipa
  - app-distribution/comment_bitbucket_pr:
      repo_slug: circleci-demo-ios
      workspace: tadashi0713
Bitbucket PR

Slack への通知

CircleCI App Distribution では notify_slack ステップを用いることによって、この配信情報を特定の Slack チャンネルに投稿することができます。

事前に Slack の Token(SLACK_ACCESS_TOKEN)を作成し、CircleCIに保存する必要があります。

# Android
steps:
  # Build Android binary
  - app-distribution/upload_android:
      path: demo.apk
  - app-distribution/notify_slack:
      channel: test-android

# iOS
steps:
  # Build iOS Binary
  - app-distribution/upload_ios:
    path: demo.ipa
  - app-distribution/notify_slack:
      channel: test-ios
Slack

特徴

  • デバッグ版の配布を CircleCI 上のみで完結することができる
    • 別途サービスを用意・連携する必要がない
  • 簡単にセットアップ・利用することができる
    • upload_android, upload_ios は配布したいバイナリのパスのみ指定すればよく、別途特別なセットアップの必要がない
    • GitHub / GitLab / Bitbucket へのコメントと Slack への通知も数行追加するだけで実現することが可能
  • セキュアに利用することが可能
    • CircleCI の Artifact を利用しているため
      • プロジェクトの閲覧権限がある人のみ利用可能
      • Artifact の保存期間をコントロールすることが可能
  • GitHub, GitLab, BitBucket をサポート
    • 各VCSのCI/CDツール(GitHub Actions, GitLab CI)に依存せず利用することが可能

注意点

実行環境(Executor)

CircleCI App Distribution は CircleCI が提供している Executor で動くことを想定しています。

その他の環境(CircleCI以外が提供しているDockerイメージなど)では、実行に必要なソフトウェアがインストールされずに失敗する可能性があります。

GitHub / GitLab / Bitbucket へのコメントと Slack への通知を利用する場合

GitHub / GitLab / Bitbucket へのコメントと Slack への通知を利用する場合には、同じJobの前のステップで upload_android もしくは upload_ios を実行してください。

下記のように別の Job で実行することはできません。

# NG例
version: 2.1

orbs:
  app-distribution: tadashi0713/app-distribution@1.1.0

jobs:
  build_debug:
    macos:
      xcode: 14.3.1
    steps:
      # Build iOS Binary
      - app-distribution/upload_ios:
          path: demo.ipa
  github_slack:
    steps:
      - app-distribution/comment_github_pr
      - app-distribution/notify_slack:
          channel: test

workflows:
  ios-workflow:
    jobs:
      - build_debug
      - github_slack:
          requires:
            - build_debug

iOSアプリケーションを配布する場合

iOS アプリケーションを CircleCI App Distribution で配布する場合には、アドホック(Ad Hoc)アプリケーションとしてビルドしておく必要があります。

CircleCI と fastlane を使ってアドホック(Ad Hoc)アプリケーションのコード署名・ビルドを行う方法は下記を参考にしてください。

iOS プロジェクトのコード署名のセットアップ - CircleCI

おわりに

今後は要望が多ければ以下の改善を行なっていく予定です。

  • 公式Orb(Certified Orb)への移行
  • Slack通知以外の対応

改善・要望などあれば是非 GitHub の Pull Request・Issue の作成をお願いします。

GitHub - tadashi0713/circleci-app-distribution: Easiest way to distribute your mobile applications all inside CircleCI

(補足) サンプルの設定ファイル

Android サンプル

version: 2.1

orbs:
  android: circleci/android@2.3.0
  app-distribution: tadashi0713/app-distribution@1.1.0

jobs:
  distribute_debug:
    executor:
      name: android/android-docker
    steps:
      - checkout
      - android/restore-gradle-cache
      - run: ./gradlew buildDebug
      - android/save-gradle-cache
      - app-distribution/upload_android:
          path: app/build/outputs/apk/debug/app-debug.apk
      - app-distribution/comment_github_pr
      - app-distribution/notify_slack:
          channel: test

workflows:
  android-workflow:
    jobs:
      - distribute_debug

iOS サンプル

version: 2.1

orbs:
  ruby: circleci/ruby@2.1.0
  app-distribution: tadashi0713/app-distribution@1.1.0

jobs:
  distribute_debug:
    macos:
      xcode: 14.3.1
    resource_class: macos.m1.large.gen1
    steps:
      - checkout
      - ruby/install-deps
      - run: bundle exec fastlane beta
      - app-distribution/upload_ios:
          path: CircleCIDemo.ipa
      - app-distribution/comment_github_pr
      - app-distribution/notify_slack:
          channel: test

workflows:
  ios-workflow:
    jobs:
      - distribute_debug

(補足)各プラットフォームにおけるアーキテクチャー

CircleCI App Distribution は CircleCI Artifact を主に活用しています。

Android アーキテクチャー

upload_android を実行すると、まず対象のバイナリ(.apk, .aab)からアプリ情報(アプリ名、リリースバージョンなど)を解析します。

Android SDK Build-Tools の1つであるAAPT2 を使って解析します。

取得したアプリ情報は、まず HTML ファイルに書き出し、バイナリ(.apk, .aab)と共に CircleCI Artifact にアップロードします。

また、GitHub / GitLab / Bitbucket へのコメントと Slack への通知でこの情報を利用するために、環境変数に保存しておきます。

最後に、アップロードしたHTMLファイルのURLを元にQRCodeを生成し(qrencoder)、CircleCIのジョブコンソールや GitHub Pull Request に表示させます。

QRコード→配布ページ(HTML)→バイナリ(.apk, .aab)をダウンロード・インストール

といった形で、配布された Android アプリケーションをインストールすることができます。

Androidにおけるアーキテクチャー

iOS アーキテクチャー

iOS も同じくupload_ios を実行すると、対象のバイナリ(.ipa)からアプリ情報を解析します。

ipa ファイルの解析には ipa_analyzer を利用しています。

Android と大きく違う部分としては、iOSアプリケーションの場合には直接バイナリ(.ipa)をダウンロードしようとしても正しくインストールすることができません。

iOSアプリケーションをインストールする場合には、アプリ情報とバイナリ(.ipa)のURLが記載されたマニフェストファイル(.plist)経由でインストールする必要があります。

そのため、マニフェストファイル(.plist)・HTMLファイルの2つを作成・アップロードし、

QRコード→配布ページ(HTML)→マニフェストファイル(.plist)をダウンロード→マニフェストファイルに記載されているバイナリ(.ipa)をダウンロード・インストール

といった形で、配布された iOS アプリケーションをインストールする必要があります。

<!-- マニフェストファイル(.plist)をダウンロード -->
<a class="button is-dark" href="itms-services://?action=download-manifest&amp;url=${PLIST_URL}">
  <span class="icon">
    <i class="fas fa-download"></i>
  </span>
  <span>Install App</span>
</a>
iOSにおけるアーキテクチャー