なぜ Rork アプリに CI/CD が必要なのか
Rork はプロンプトを書くだけでモバイルアプリを生成できる革命的なプラットフォームです。しかしアプリが成長し、機能追加やバグ修正を繰り返すようになると、毎回手動でビルドしてテストして配布する作業がボトルネックになります。
CI/CD(継続的インテグレーション/継続的デリバリー)パイプラインを構築すれば、コードをプッシュするだけでテスト実行→ビルド→配布が全自動で走ります。Rork が生成するプロジェクトは React Native + Expo ベースなので、GitHub Actions と EAS Build の組み合わせが最適です。
前提条件と準備
CI/CD を始める前に、以下の環境が整っていることを確認してください。
- Rork アカウント(スタンダードまたは Rork Max)
- GitHub アカウント と Rork プロジェクトのリポジトリ
- Expo アカウント(EAS Build に必要)
- Node.js 18 以降がローカルにインストール済み
- Apple Developer Program(TestFlight 配布を行う場合)
Rork でアプリを生成したら、まずプロジェクトをエクスポートして GitHub リポジトリにプッシュしましょう。Rork の「Export」機能を使えば、React Native + Expo のプロジェクト構成がそのまま取得できます。
EAS Build のセットアップ
Expo Application Services とは
EAS(Expo Application Services)は、Expo チームが提供するクラウドビルド・配布サービスです。ローカルに Xcode や Android Studio がなくても、クラウド上で iOS/Android のネイティブビルドを実行できます。
プロジェクトの初期設定
Rork からエクスポートしたプロジェクトのルートで、EAS CLI をセットアップします。
# EAS CLI のインストール
npm install -g eas-cli
# Expo アカウントにログイン
eas login
# プロジェクトの初期設定
eas build:configureeas build:configure を実行すると、プロジェクトルートに eas.json が生成されます。以下のように編集して、開発・プレビュー・本番の3つのビルドプロファイルを定義します。
{
"cli": {
"version": ">= 14.0.0"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"ios": {
"simulator": true
}
},
"preview": {
"distribution": "internal",
"ios": {
"resourceClass": "m-medium"
}
},
"production": {
"ios": {
"resourceClass": "m-medium"
},
"android": {
"buildType": "app-bundle"
}
}
},
"submit": {
"production": {
"ios": {
"appleId": "your-apple-id@example.com",
"ascAppId": "your-app-store-connect-app-id",
"appleTeamId": "YOUR_TEAM_ID"
}
}
}
}認証情報の管理
EAS Build では、iOS の証明書やプロビジョニングプロファイルをクラウドで自動管理できます。初回ビルド時に対話型プロンプトで設定するか、eas credentials コマンドで事前に登録します。
Android の場合はキーストアが自動生成されます。本番リリース用のキーストアは必ずバックアップを取っておきましょう。
GitHub Actions ワークフローの構築
リポジトリにシークレットを追加する
GitHub Actions から EAS Build を実行するために、Expo のアクセストークンをリポジトリの Secrets に登録します。
- expo.dev のアカウント設定からアクセストークンを生成
- GitHub リポジトリの Settings → Secrets and variables → Actions を開く
EXPO_TOKENという名前でトークンを追加
テスト実行ワークフロー
プルリクエストが作成されるたびにテストを自動実行するワークフローを作成します。
# .github/workflows/test.yml
name: Test
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- name: TypeScript 型チェック
run: npx tsc --noEmit
- name: Lint
run: npx eslint . --max-warnings 0
- name: Unit Tests
run: npx jest --coverage --ciこのワークフローは3つのチェックを実行します。TypeScript の型エラーがないか、ESLint のルール違反がないか、そして Jest のユニットテストが通るかを確認します。
ビルド&配布ワークフロー
main ブランチにマージされたら、自動的に EAS Build を実行して TestFlight に配布するワークフローです。
# .github/workflows/build-and-deploy.yml
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build-ios:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: Build iOS (Production)
run: eas build --platform ios --profile production --non-interactive
- name: Submit to TestFlight
run: eas submit --platform ios --latest --non-interactive
build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: Build Android (Production)
run: eas build --platform android --profile production --non-interactiveiOS と Android のビルドは並列で実行されるため、待ち時間を最小限に抑えられます。eas submit コマンドにより、ビルド完了後に自動で TestFlight へアップロードされます。
プレビュービルドで PR ごとに動作確認する
チームで開発している場合、プルリクエストごとにプレビュービルドを配布すると便利です。レビュアーが実機で動作確認できるため、マージ前の品質チェックが格段に向上します。
# .github/workflows/preview.yml
name: Preview Build
on:
pull_request:
branches: [main]
types: [opened, synchronize]
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: Build Preview
run: eas build --platform ios --profile preview --non-interactive
- name: PR にビルドリンクをコメント
uses: expo/expo-github-action/preview-comment@v8
with:
project: your-project-slugPR にビルドリンクが自動コメントされるため、レビュアーはリンクをタップするだけでプレビュービルドをインストールできます。
EAS Update でホットフィックスを即時配信する
ネイティブコードの変更を伴わない JavaScript レベルの修正は、EAS Update(OTA アップデート)で即時配信できます。App Store の審査を待たずにユーザーに修正を届けられる強力な仕組みです。
# .github/workflows/update.yml
name: OTA Update
on:
push:
branches: [main]
paths:
- 'src/**'
- 'assets/**'
- 'app.json'
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: Publish OTA Update
run: eas update --branch production --message "${{ github.event.head_commit.message }}"paths フィルタにより、JavaScript やアセットの変更時のみ OTA アップデートが走ります。ネイティブ依存パッケージの更新時はフルビルドが必要なため、ワークフローを分離しているのがポイントです。
セマンティックバージョニングの自動化
リリースごとにバージョン番号を手動で更新するのは手間がかかりますし、ヒューマンエラーの温床です。app.json のバージョン番号をコミットメッセージから自動でバンプする仕組みを導入しましょう。
# .github/workflows/version-bump.yml
name: Version Bump
on:
push:
branches: [main]
jobs:
bump:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'chore: bump version')"
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Determine version bump
id: bump
run: |
MSG="${{ github.event.head_commit.message }}"
if echo "$MSG" | grep -qi "breaking\|major"; then
echo "type=major" >> $GITHUB_OUTPUT
elif echo "$MSG" | grep -qi "feat\|feature"; then
echo "type=minor" >> $GITHUB_OUTPUT
else
echo "type=patch" >> $GITHUB_OUTPUT
fi
- name: Bump version in app.json
run: npx expo-version-bump ${{ steps.bump.outputs.type }}コミットメッセージに feat: を含めるとマイナーバージョンが上がり、breaking: なら メジャーバージョンが上がります。それ以外はパッチバージョンとして処理されます。
ビルドキャッシュと最適化のコツ
GitHub Actions の実行時間を短縮するためのテクニックをいくつか紹介します。
npm キャッシュの活用: actions/setup-node の cache: npm オプションを指定すると、node_modules のインストール時間を大幅に削減できます。初回は数分かかるインストールが、2回目以降は数秒で完了します。
EAS のリソースクラスを選択する: eas.json の resourceClass を m-medium 以上に設定すると、ビルドマシンのスペックが上がり、ビルド時間が短くなります。無料プランでは m-small に制限されますが、有料プランなら m-large まで選択可能です。
条件付きビルドでコストを抑える: すべてのプッシュでフルビルドを走らせるとEASのビルドクレジットを消費します。paths フィルタや if 条件を活用して、ネイティブ依存の変更時のみフルビルドを実行し、JS のみの変更は OTA アップデートで対応するのがベストプラクティスです。
トラブルシューティング
ビルドが失敗する場合
EAS Build のエラーログは eas build:list コマンドまたは expo.dev のダッシュボードで確認できます。よくある原因は Expo SDK バージョンとネイティブ依存ライブラリの互換性です。Rork が生成したプロジェクトの場合、package.json の依存関係は基本的に整合が取れていますが、手動でパッケージを追加した場合は npx expo-doctor で互換性チェックを行いましょう。
証明書関連のエラー
iOS ビルドで証明書エラーが出た場合は、eas credentials コマンドで証明書の状態を確認します。期限切れの証明書は EAS が自動で再生成してくれますが、Apple Developer アカウントの2要素認証トークンが切れている場合は手動更新が必要です。
GitHub Actions のタイムアウト
EAS Build のキューが混んでいると、GitHub Actions のデフォルトタイムアウト(6時間)内にビルドが完了しないことがあります。ワークフローに timeout-minutes: 120 を設定し、ビルドの完了は EAS のウェブフックで別途通知を受ける方式に切り替えることを検討してください。
全体を振り返って
Rork で生成したアプリに GitHub Actions と EAS Build の CI/CD パイプラインを導入すれば、開発からリリースまでのフローが劇的に効率化されます。
本記事で構築したパイプラインを振り返ると、PR ごとのテスト自動実行でコード品質を維持し、マージ後の自動ビルドと TestFlight 配布でリリースの手間を削減し、OTA アップデートで緊急修正を即時配信できる体制が整いましました。
最初はテストワークフローだけ導入し、慣れてきたらビルドと配布を追加するというステップバイステップのアプローチがおすすめです。一度パイプラインが整えば、あなたはアプリの機能開発に集中できるようになります。