すべてのプルリクエストを即座にインストール可能なプレビューに変える方法
開発 • React Native • プロダクト • 2025年12月16日 • 14分で読める
Jacob Clausen エンジニアリング
Expo CICD Workflows、development builds、OTA Updatesを使用して、すべてのプルリクエストをQRコードで開ける、インストール準備完了のプレビューに変える方法を学びましょう。
ブランチを切り替えたり、手動でアプリを再ビルドしたりすることなく、新機能をレビューすることを想像してみてください。互換性のあるdevelopment buildがすでにインストールされていれば、各プルリクエストはQRコードを介してアプリ内で直接読み込めるプレビューになります。
ほとんどの変更はプレビュー可能なアップデートとして配信されます。ネイティブの変更が含まれる場合は、まず新しいビルドが作成され(そしてアップデートがそれに適用される)ため、チームが機能をレビューする方法は変わりません。
開発サーバーなし。セットアップなし。デザイナー、QA、プロダクトが早期にフィードバックループで体験できるプレビューだけです。
アップデートを選択して即座にプレビュー
Expoの同僚であるBeto Moedanoは最近、EASとGitHub Actionsを使用してこのアイデアを説明する優れた動画を公開しました。まだチェックしていない場合は、ぜひご覧になることをお勧めします!
この記事では、似たようなフローを見ていきますが、ExpoのCI/CDソリューションであるWorkflowsの上に構築されています。これらは、プルリクエストからインストール準備完了のプレビューまでのプロセス全体を自動化するクリーンで合理化された方法を提供し、即座のコラボレーションを開発サイクルの自然な一部にします。
Workflowの責任
このワークフローをチームにとってシームレスに感じさせるために、自動化はいくつかの重要な責任を処理する必要があります:
- Android、iOS、iOSシミュレーター用の互換性のあるdevelopment buildsがあるかどうかを判断する
- ビルドが互換性がない場合(詳細は後述)、ワークフローは必要に応じて新しいdevelopment buildsを生成する
- 互換性のあるビルドがすでに存在する場合、ワークフローはビルドステップを省略し、既存の互換性のあるビルドを再利用する
- development buildsを対象としたover-the-airアップデートを公開する - それらがすでに存在していたか、作成されたばかりかに関係なく
- プルリクエストに以下を含むコメントを投稿する:
- 互換性のあるビルドへのリンク
- 互換性のあるdevelopment buildがすでにインストールされている場合に、QRコードをスキャンするか、dev clientから選択することで即座に実行できるアップデートへの直接アクセス
新しいExpoプロジェクトでEAS Workflowsを始める
Workflowsを使い始める前に、いくつかの前提条件があります。このチュートリアルでは、まったく新しいプロジェクトから始めます。
npx create-expo-app my-demo-app
EAS CLIがインストールされ、Expoアカウントにログインしていることを確認してください:
# EAS CLIをインストール
npm install -g eas-cli
# まだログインしていない場合はアカウントにログイン
eas login
次に、EAS Build用にプロジェクトを設定します:
eas build:configure
このコマンドは、プロジェクトのルートにeas.jsonを生成し、一般的なビルドプロファイルを設定します。また、設定にprojectIdを追加することで(app.jsonのexpo.extra.projectId)、プロジェクトをExpoにリンクします。詳細については、EAS Buildドキュメントをご覧ください。
ここで、iOSシミュレーターでアプリを実行するための専用ビルドプロファイルを追加しましょう:
{
"cli": {
"version": ">= 16.28.0",
"appVersionSource": "remote"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"development-simulator": {
"extends": "development",
"ios": {
"simulator": true
}
},
"preview": {
"distribution": "internal"
},
"production": {
"autoIncrement": true
}
},
"submit": {
"production": {}
}
}
Development buildsの設定
この合理化された開発ワークフローを最大限に活用し(開発者とQAの両方に優れた体験を提供するため)、development buildsを使用する必要があります。
プロジェクトにexpo-dev-clientがインストールされていることを確認してください:
npx expo install expo-dev-client
expo-dev-clientは、カスタマイズ可能なランチャーUIを含む、デバッグビルドに役立つ開発ツールを追加します。このUIは、プルリクエストから作成された機能プレビューをアプリ内で直接読み込むことを可能にします。
これらのアップデートが存在すると、チームメイトはプロジェクトをローカルで実行したり、開発サーバーに接続したりすることなく、新機能をレビューできます。development buildからアップデートを選択する(またはQRコードをスキャンする)だけで、テストを開始できます。
自動化されたワークフローのためのExpoプロジェクトとGitHubの接続
Workflowsはターミナルから手動でトリガーできますが、GitHubとの日常的な開発プロセスに統合されたときに真価を発揮します。たとえば、コミットをプッシュしたり、プルリクエストを開いたりするたびに、ワークフローを自動的にトリガーできます。
GitHubリポジトリをEASプロジェクトにリンクするには:
- アプリ用のGitHubリポジトリがあることを確認する
- プロジェクトのGitHub設定に移動する
- プロンプトに従ってGitHubアプリをインストールする
- Expoプロジェクトに一致するリポジトリを選択して接続する
より高速な内部リリースのためのEAS Updateの設定
これが設定されたら、次のステップはEAS Updateを設定することです。EAS Updateを使用すると、重要な修正、改善、さらには新機能を即座にプッシュできます - これはユーザーがすぐに恩恵を受けるものです。また、開発者とQAチームの内部イテレーションを高速化する優れた方法でもあります。
ターミナルで以下のコマンドを実行して開始します:
eas update:configure
このコマンドは以下を行います:
- プロジェクトの依存関係としてexpo-updatesをインストール
- eas.jsonビルドプロファイルにchannelを追加
- app.jsonにupdatesオブジェクトを追加
{
"cli": {
"version": ">= 16.28.0",
"appVersionSource": "remote"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"channel": "development"
},
"development-simulator": {
"extends": "development",
"ios": {
"simulator": true
}
},
"preview": {
"distribution": "internal",
"channel": "preview"
},
"production": {
"autoIncrement": true,
"channel": "production"
}
},
"submit": {
"production": {}
}
}
実行したコマンドはchannelプロパティを追加しました。これはEAS Updateがアップデートを公開する場所を決定するために使用します。それ以外に、development-simulatorビルドプロファイルのchannelを削除したので、developmentチャンネルを継承します。
より多くの設定オプションを探索したい場合は、こちらのドキュメントを参照できます。
互換性のあるビルドと互換性のないビルドの理解
何かを自動化する前に、一部のアップデートが即座に適用でき、他のものがまったく新しいdevelopment buildを必要とする理由を理解することが重要です。この区別が高速なイテレーションを可能にします。
すべてのネイティブビルドには、ネイティブフィンガープリント - プロジェクトのネイティブレイヤーに影響する部分のスナップショット - があります。これから構築するWorkflowでは、フィンガープリントを比較することで、互換性のあるdevelopment buildがすでに存在するかどうかを判断します。
これにより、ワークフローは既存のdevelopment buildを再利用できるか、アップデートを公開する前に新しいものを作成する必要があるかを判断できます。
互換性のあるビルド = アップデートを即座に公開できます。再インストール、再ビルド、待機なし。QAとチームメイトは、実行中の開発サーバーがなくても、数分以内に機能を試すことができます。これがイテレーション速度の最適な状態です。
互換性のないビルド = 新しいdev buildが必要です。これは、ネイティブレイヤーに影響するものを変更したときに発生します - ネイティブコードを持つ新しいライブラリの追加、アプリ設定の変更など。
したがって、ネイティブレイヤーが変更されていない場合、チームは既存のdevelopment buildで機能をプレビューできます。変更されている場合、ワークフローは新しいdevelopment buildを作成してからアップデートを公開するため、プレビューは同じプルリクエストの一部として継続されます。
これがEAS Updateがコラボレーションにとって非常に強力である理由の1つです:ほとんどの機能作業 - UIの磨き上げ、ロジックの調整、コピー、スタイリング、ナビゲーションの変更 - は新しいネイティブビルドを必要としません。チームは、ビルドやセットアップに時間を失うことなく、視覚的かつインタラクティブにイテレーションできます。
ワークフローが互換性をチェックしてアップデートを公開する方法
次に作成するWorkflowは、この意思決定を自動化します。Android、iOS、iOSシミュレーターのフィンガープリントをチェックし、最速のパスを選択します:
- 互換性がある場合は既存のdev buildsを再利用
- 必要な場合のみ新しいdev buildsを生成
- 常にプレビューアップデートを配信
これにより、チームは進行中の作業をテストする信頼性があり予測可能な方法を得られます - 可能な場合は即座に、必要な場合は自動的に再ビルドされます。
ビルドを生成またはアップデートを公開するEAS Workflowの作成
次に、プロジェクトにワークフローファイルを作成しましょう。すべてのワークフローは.eas/workflowsディレクトリ内に存在し、これはEASが自動化を探す場所です。これにより、ワークフロー定義がコードの残りの部分と一緒に整理され、バージョン管理されます。
/
└── .eas/
│ └── workflows/
│ └── create-dev-build-or-update.yml
├── app/
├── eas.json
└── ... その他のファイル
この例では、create-dev-build-or-update.ymlという名前のワークフローを作成します。これは、ビルドの互換性チェック、必要に応じた新しいdevelopment buildsの生成、アップデートの公開を処理します。
ディレクトリとファイルを手動で作成するか、プロジェクトのルートから以下のコマンドを実行して生成できます。
# Mac
mkdir -p .eas/workflows && touch .eas/workflows/create-dev-build-or-update.yml
# Windows
mkdir .eas\workflows && type nul > .eas\workflows\create-dev-build-or-update.yml
ワークフローファイル自体はYAMLファイルで、GitHub Actionsを使用したことがある場合、構文は馴染みがあるでしょう。EAS Workflowsでは完全にカスタムなジョブを定義できますが、多くの一般的なタスクをカバーする豊富な事前パッケージ化されたジョブセットも含まれています。
これらの事前パッケージ化されたジョブは、アプリのビルド、送信、テストなどのための即座に使用可能な構成要素を提供します。すべてのステップを一から書く必要なく、一貫性があり、十分にテストされた基盤を提供します。
このワークフローでは、以下の組み合わせを使用します:
- Fingerprint
- Get Build
- Build
- Update
- GitHub Comment
最初は多くの動く部品のように見えるかもしれませんが、各ジョブは分かりやすく使いやすいように設計されています。このワークフローの目標はシンプルです:チームに機能作業をアプリで直接試すための信頼性があり、摩擦の少ない方法を提供することです。
name: Create development builds or update
on:
pull_request:
branches: ["*"]
jobs:
fingerprint:
name: Fingerprint
type: fingerprint
environment: development
get_android_build:
name: Check for existing android build
needs: [fingerprint]
type: get-build
environment: development
params:
fingerprint_hash: ${{ needs.fingerprint.outputs.android_fingerprint_hash }}
profile: development
get_ios_build:
name: Check for existing ios build
needs: [fingerprint]
type: get-build
environment: development
params:
fingerprint_hash: ${{ needs.fingerprint.outputs.ios_fingerprint_hash }}
profile: development
get_ios_simulator_build:
name: Check for existing ios simulator build
needs: [fingerprint]
type: get-build
environment: development
params:
fingerprint_hash: