🐡

iOSアプリのTestFlight配信とFastlane + GitHub Actions構成の学習記録(非iOS開発者視点)

に公開

はじめに

あるiOSアプリ開発者の方から「TestFlight配信用のCI/CD構成について調べてみてほしい」という依頼があり、FastlaneとGitHub Actionsを使ってiOSアプリを自動でTestFlightに配信する仕組みを調査・構築しました。

私はiOSアプリの開発経験がないため、TestFlightやFastlaneの概念、GitHub Actionsとの連携の流れを理解することから始め、テンプレートを作成しました。

この記事は、非iOSエンジニアの視点で、TestFlight配信の全体像と自動化の流れをまとめたものです。

なぜ自動化するのか?

まず、自動化しないときにどんな不便があるか調べてみました。

  • 配信手順が複雑で、複数のCLIコマンドを手入力する必要がある
  • 証明書やプロビジョニングプロファイルの管理が面倒
  • ビルドに時間がかかり、失敗の原因がわかりづらい
  • 作業が属人化しやすく、他の人が同じ手順を再現しにくい
  • Mac環境が必須で、CI環境での実行が難しい

GitHub ActionsとFastlaneを組み合わせてCI/CD化する事例が多い のも納得です。


手動配信の流れ

自動配信(CI/CD)の流れ


TestFlightとは?

TestFlightは、Appleが提供するiOSアプリのベータテスト配信プラットフォームです。

  • 開発中のアプリを実機でテスト可能
  • テスターはTestFlightアプリから簡単にインストールできる
  • 外部テスターに公開する場合はAppleの審査が必要(軽微)
  • 配信されたビルドは90日間有効

Fastlaneとは?

Fastlaneは、iOSアプリ開発のビルド・配信プロセスを自動化するCLIツールです。

よく使われるコマンドは以下の通り:

  • match: 証明書・プロビジョニングプロファイルの同期
  • build_app: .ipaファイルのビルド(Xcodeビルドのラッパー)
  • upload_to_testflight: TestFlightへのアップロード

CI(継続的インテグレーション)環境でもよく利用されます。


構成概要

今回は以下の構成で自動化テンプレートを作成しました:


.github/
workflows/
modern-testflight.yml      ← モダン構成(Fastlaneのlane実行)

fastlane/
Fastfile                     ← `lane :beta` を定義

GitHub Actionsから fastlane beta を実行することで、
証明書の同期 → ビルド → TestFlightアップロード が一括で実行されます。


GitHub Actionsワークフローの流れ

.github/workflows/modern-testflight.yml

on:
  workflow_dispatch:
    inputs:
      branch:
        description: 'デプロイ対象のブランチ'
        required: true
        default: 'main'

  push:
    branches:
      - main

jobs:
  build_and_distribute:
    name: Build & Distribute to TestFlight
    runs-on: macos-latest

    env:
      ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
      ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
      ASC_KEY_CONTENT: ${{ secrets.ASC_KEY_CONTENT }}
      MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
      BUILD_NUMBER: ${{ github.run_number }}

    steps:
      - name: コードチェックアウト
        uses: actions/checkout@v3
        with:
          ref: ${{ github.event.inputs.branch || 'main' }}

      - name: Rubyセットアップ
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.1'

      - name: 依存関係インストール
        run: |
          gem install bundler
          bundle install

      - name: Fastlane実行
        run: bundle exec fastlane beta

Fastfile の内容

default_platform(:ios)

platform :ios do
  lane :beta do
    setup_ci

    app_store_connect_api_key(
      key_id: ENV['ASC_KEY_ID'],
      issuer_id: ENV['ASC_ISSUER_ID'],
      key_content: ENV['ASC_KEY_CONTENT'],
      in_house: false
    )

    match(type: "appstore")

    build_app(
      scheme: "YourAppScheme",
      output_directory: "output",
      output_name: "MyApp.ipa"
    )

    upload_to_testflight(
      skip_waiting_for_build_processing: true
    )
  end
end

GitHub Secrets(環境変数)

以下の情報はGitHubの Settings → Secrets and variables → Actions に登録します。

シークレット名 説明
ASC_KEY_ID App Store Connect の API Key ID
ASC_ISSUER_ID Issuer ID
ASC_KEY_CONTENT .p8ファイルの中身(改行込み)
MATCH_PASSWORD Fastlane用のパスワード

実行方法

  • GitHub Actions → ワークフロー → Modern Distribute to TestFlight
  • ブランチを入力して手動実行
  • または main ブランチへの push で自動実行

学んだこと・感想

  • iOSアプリの配信には証明書やApple APIキーの理解が不可欠
  • Fastlaneは初見では難しいが、テンプレート化すれば強力
  • TestFlightの仕組みを知ることで、App Store申請前のチェックがしやすくなる
  • iOSアプリの配信の流れが少し分かった気がする(どうかなー)

Discussion