🐷

【2025年最新版】Flutter + GitHub Actions + FastlaneでiOSのテスト配布自動化手順(CD)

に公開

概要

本記事では、develop ブランチにプッシュしたタイミングで、iOSのTestFlight配信を自動で実行する手順を紹介します。
Flutter × GitHub Actions × Fastlaneの構成で、アプリ申請前の社内共有やQA確認を効率化できます。


注意点

今回の自動化を行う上で以下の注意点があります。まずは手動でTestFlight配信できるようにしてから、自動化することをおすすめします(まず動く構成を確認してからカスタマイズする)。

  • 証明書の自動生成はせず、Fastlane Match を用いて初回はローカルで証明書を作成し、Gitリポジトリで管理します
  • 本手順ではApp Storeへの提出までは行わず、TestFlight配信のみ
  • .env.p8ファイルなど、Gitに含めない機密情報は全てGitHub Secretsで管理

前提条件

  • FlutterでiOSアプリをビルドできる状態であること
  • App Store Connectにアプリが登録済みであること
  • 証明書を保存するGitリポジトリを用意済み(例: iOS-Cer

手順

Step 1. Fastlaneの初期化

cd ios
fastlane init
  • 「2: Automate beta distribution to TestFlight」を選択
  • Apple IDログイン(2FAコードの入力あり)
  • Fastfile, Appfile, Gemfileなどが生成されます

Step 2. 証明書管理リポジトリを作成して match init

fastlane match init
  • ストレージ:git
  • リポジトリURL:例)https://github.com/xxxxx/iOS-Cer.git
  • Matchfile が自動生成されます

Step 3. AppStore用の証明書を生成(初回のみ)

fastlane match appstore
  • MATCH_PASSWORD を設定(CIでも使用)
  • Apple Distribution 証明書と App Store用のプロビジョニングプロファイルが作成され、Gitへpushされます

Step 4. Fastfileを修正してlaneを定義

lane :build_testflight do
  prepareBuild
  buildIpa
  deployTestFlight
end

private_lane :prepareBuild do
  create_keychain(
    name: ENV['MATCH_KEYCHAIN_NAME'],
    password: ENV['MATCH_KEYCHAIN_PASSWORD'],
    timeout: 1800
  )

  api_key = app_store_connect_api_key(
    key_id: ENV['ASC_API_KEY_ID'],
    issuer_id: ENV['ASC_API_ISSUER_ID'],
    key_content: ENV['ASC_API_KEY_CONNECT']
  )

  match(
    api_key: api_key,
    type: "appstore",
    readonly: true,
    git_url: ENV['CER_REPO'],
    git_branch: ENV['CER_REPO_BRANCH'],
    git_basic_authorization: ENV['MATCH_GIT_BASIC_AUTHORIZATION']
  )

  update_code_signing_settings(
    path: "Runner.xcodeproj",
    use_automatic_signing: false,
    team_id: ENV['TEAM_ID'],
    code_sign_identity: "Apple Distribution",
    profile_name: "match AppStore com.hayate.dev.karaokeMap",
    bundle_identifier: "com.hayate.dev.karaokeMap"
  )
end

private_lane :buildIpa do
  build_ios_app(
    workspace: "Runner.xcworkspace",
    scheme: "Runner",
    configuration: "Release",
    clean: true,
    output_directory: "build",
    output_name: "release-karaoke-map.ipa",
    export_method: "app-store"
  )
end

private_lane :deployTestFlight do
  upload_to_testflight(skip_submission: true)
end

Step 5. GitHub Secretsの設定

🔐 Fastlane / App Store Connect 関連

シークレット名 用途
APPLE_ID Apple IDのメールアドレス
APP_STORE_CONNECT_API_KEY .p8の中身
ASC_API_KEY_ID App Store ConnectのKey ID
ASC_API_ISSUER_ID Issuer ID
TEAM_ID Apple DeveloperのチームID

✅ match(証明書管理)関連

シークレット名 用途
CER_REPO 証明書保存リポジトリのURL
CER_REPO_BRANCH ブランチ名(例:main
MATCH_PASSWORD 証明書リポジトリの復号パスワード
MATCH_GIT_BASIC_AUTHORIZATION Gitアクセストークン
MATCH_KEYCHAIN_NAME キーチェーン名
MATCH_KEYCHAIN_PASSWORD キーチェーンパスワード

✅ その他

シークレット名 用途
SSH_PRIVATE_KEY 証明書リポジトリへのアクセス用秘密鍵
ENV_FILE .envファイルの中身

Step 5.5 デプロイキー(SSH秘密鍵)の設定

1. SSH鍵をローカルで生成

ssh-keygen -t ed25519 -C "ci-deploy-key-for-cert-repo"
  • .pub 拡張子付きが公開鍵、なしが秘密鍵

2. 公開鍵をGitHubリポジトリに登録

  • 対象:証明書管理リポジトリ(例:iOS-Cer)
  • GitHub → Settings → Deploy Keys → Add deploy key
    • Title:任意
    • Key:公開鍵(.pub)の中身
    • ✅ Allow write access:チェックなし

3. 秘密鍵をSecretsに登録

  • 秘密鍵の中身を SSH_PRIVATE_KEY として登録
  • 以下のように使用:
- name: Setup SSH
  run: |
    mkdir -p ~/.ssh
    echo "$PRIVATE_KEY" > ~/.ssh/id_ed25519
    chmod 600 ~/.ssh/id_ed25519
    ssh-keyscan github.com >> ~/.ssh/known_hosts
    eval $(ssh-agent)
    ssh-add ~/.ssh/id_ed25519
  env:
    PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

Step 6. GitHub Actionsの設定

name: CD_iOS

on:
  push:
    branches: [ develop ]
  workflow_dispatch:

jobs:
  ios_distribution:
    runs-on: macos-15

    steps:
      - uses: actions/checkout@v4

      - name: Setup Flutter
        uses: subosito/flutter-action@v1
        with:
          flutter-version: '3.29.3'

      - run: flutter pub get

      - name: Pod install
        run: |
          cd ios
          pod install

      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "$PRIVATE_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan github.com >> ~/.ssh/known_hosts
          eval $(ssh-agent)
          ssh-add ~/.ssh/id_ed25519
        env:
          PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Restore .env
        run: echo "${{ secrets.ENV_FILE }}" > .env

      - name: Fastlane 実行
        run: |
          cd ios
          fastlane build_testflight
        env:
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
          TEAM_ID: ${{ secrets.TEAM_ID }}
          MATCH_KEYCHAIN_NAME: ${{ secrets.MATCH_KEYCHAIN_NAME }}
          MATCH_KEYCHAIN_PASSWORD: ${{ secrets.MATCH_KEYCHAIN_PASSWORD }}
          MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
          ASC_API_KEY_ID: ${{ secrets.ASC_API_KEY_ID }}
          ASC_API_ISSUER_ID: ${{ secrets.ASC_API_ISSUER_ID }}
          ASC_API_KEY_CONNECT: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
          CER_REPO: ${{ secrets.CER_REPO }}
          CER_REPO_BRANCH: ${{ secrets.CER_REPO_BRANCH }}
          ENV_FILE: ${{ secrets.ENV_FILE }}

      - name: Clean up
        run: rm .env

おわりに

FastlaneとGitHub Actionsを使うことで、iOSのTestFlight配信が完全自動化できます。
特にFlutterアプリのように頻繁にアップデートがある場合、CIによる社内配信の効率化は非常に効果的です。

参考記事

https://qiita.com/SUGYKEN/items/b654eb65478e51554936

Discussion