🐷
【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などが生成されます
match init
Step 2. 証明書管理リポジトリを作成して 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されます
Fastfile
を修正してlaneを定義
Step 4. 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による社内配信の効率化は非常に効果的です。
参考記事
Discussion