Expo + EASで実現する週次リリースフローの効率化
はじめに
株式会社Another worksで「複業クラウド」の開発をしている野々山と申します。
モバイルアプリの継続的なリリースは、Web開発と比較してハードルが高いと感じる方も多いのではないでしょうか。ビルド、コード署名、ストア審査...などやることがたくさんあります。
本記事では、Expo + EAS(Expo Application Services)+ GitHub Actions を活用して、週次リリースフローを効率化した事例を紹介します。
対象読者
- React Native / Expo でアプリ開発をしている、またはこれから始めたい
- CI/CD を整備してリリースを自動化したい
EAS / EAS Build とは
知っている方も多いかと思いますが、EAS(Expo Application Services) は、Expoが提供するクラウドサービス群です。
その中核となる EAS Build は、クラウド上でiOS/Androidのネイティブビルドを実行するサービスです。EASのクラウド環境にはXcodeやAndroid SDKがインストールされているため、ローカルに開発環境がなくても eas build コマンド一発でアプリをビルドできます。
主なメリット:
- 環境構築不要: MacがなくてもiOSビルドが可能
- コード署名の自動管理: 証明書やProvisioning Profileを自動で管理
- CI/CDとの連携: GitHub Actionsから簡単に呼び出し可能
GitHub Actions ワークフローの実装
ワークフローは以下の4つのJobで構成しています:
on:
schedule:
- cron: "0 5 * * FRI" # 日本時間で金曜14:00
workflow_dispatch: # 手動実行も可能
jobs:
check-types: # 型チェック
create-tag: # タグ作成 & リリースノート生成
trigger-build: # EAS Build のトリガー
notify-slack: # 失敗時の通知
workflow_dispatch を設定しておくことで、緊急リリースが必要な場合にも手動でビルドを実行できます。
毎週金曜日15:00のQA会に合わせて直前でビルドとリリースノートが作成されます。
ポイント1: リリースノートの自動生成
ビルドのたびにバージョンタグ(v1.2.3 → v1.2.4 → ...)を自動で作成し、GitHub Releaseも同時に生成しています。
gh pr list と jq を組み合わせて、前回タグ以降にマージされたPRからリリースノートを自動生成しています。
# 1. 前回のタグを取得
last_tag=$(git tag -l 'v*' --sort=-v:refname | head -n1)
# 2. 前回タグの日時を取得
since_date=$(git log -1 --format=%aI "$last_tag")
# 3. それ以降にマージされたPRを取得(モノレポの場合はラベルでフィルタ)
pr_json=$(gh pr list \
--state merged \
--base master \
--label my-app \
--json number,title,author,mergedAt)
# 4. 前回タグ以降のPRのみ抽出
release_prs=$(echo "$pr_json" | \
jq --arg d "$since_date" '[.[] | select(.mergedAt > $d)]')
# 5. リリースノート形式に整形
echo "$release_prs" | \
jq -r '.[] | "* \(.title) by @\(.author.login) in #\(.number)"'
生成されるリリースノートの例:
* ユーザープロフィール画面の改善 by @developer1 in #1234
* プッシュ通知のバグ修正 by @developer2 in #1235
* パフォーマンス改善 by @developer3 in #1236
これにより、「このバージョンには何が含まれているか」が自動で可視化され、QAやリリース判断がスムーズになります。
ポイント2: EAS Build のトリガー
expo/expo-github-action を使用してEAS CLIをセットアップし、staging と release の両プロファイルでビルドを実行します。
検証用(staging)と本番用(release)のビルドを同時に生成することで、QAで確認したビルドとストアに提出するビルドが同一のコードベースから生成されることを保証できます。「QAは通ったのに本番ビルドで問題が発生」というリスクを防げます。
EAS の設定
eas.json で development / staging / release の3つのビルドプロファイルを定義しています。
| プロファイル | 用途 | distribution |
|---|---|---|
development |
開発用 | internal |
staging |
QA用 | internal |
release |
ストア提出用 | store |
distribution はビルドの配布方法を指定するオプションです:
- internal: 社内配布用。Expo Dashboardからダウンロードリンクを取得して直接インストールできます。TestFlightや内部テストトラックを経由しないため、すぐにQAを開始できます。
- store: ストア提出用。App Store / Google Play にアップロード可能な形式(ipaやaab)でビルドされます。
app.config.js で APP_ENV 環境変数に応じて設定ファイルを切り替えることで、同じコードベースから staging と production のビルドを生成できます。
ビルドコマンドは以下のオプションを指定して実行しています:
eas build --platform all --profile release --clear-cache --non-interactive --no-wait
-
--platform all: iOS と Android を同時にビルド -
--clear-cache: 毎回クリーンビルド -
--non-interactive: CI環境での実行に必須 -
--no-wait: ビルド完了を待たずに次のステップへ(ビルドは時間がかかるのでCIの時間を削減してコストを下げる)
QAフロー
EAS Buildで distribution: "internal" を指定すると、TestFlight(iOS)や内部テストトラック(Android)を経由せずに直接インストール可能なビルドが生成されます。
QAチームにはExpo Dashboardから対象のビルドを選択し、ダウンロードリンクを取得して共有するだけでOKです。
リリースOKだった場合、審査に提出します。
まとめ
Expo + EAS + GitHub Actions を組み合わせることで、毎週金曜日にビルドからQA、審査提出までを一気に行う週次リリースフローを構築できました。
ビルドの自動化により手作業が減り、リリースノートの自動生成で「何が変わったか」が明確になるため、チーム全体のリリース作業がスムーズになりました。
今後の展望
- EAS Submit: ストア審査提出の自動化
- EAS Update(OTA): JavaScriptのみの変更は審査なしで即時反映
Expoアプリのリリースフローを整備したい方の参考になれば幸いです。
Discussion