1.1.2 · 開発基盤

Mac なしで iPhone アプリを build する方法

2026.07.02約7分

00Overview

Tools

  • Apple Developer ProgramApp Store 申請99 ドル/年
  • EAS buildクラウド macOS で buildFree
  • GitHub Codespaces初回の証明書操作Free
  • PC (何でも可)初回のみブラウザ手持ち

01Story

Situation

1.1.1 の開発ループで、Expo Go による動作確認と修正のサイクルは回るようになった。開発中は build なしで進む。

Complication

ただし、App Store に出すとなると話が変わる。Apple に申請するには、アプリを build して submit しなければならない。そして iPhone アプリの build には Mac が必要 — これは Apple のエコシステム上、避けて通れない事実である。

Question

build には Mac が必要。Mac を持たずに、どうやって App Store まで届けるか?

02Solution

Criteria

  • Mac を所有していなくても成立すること (買わない・借りない・置かない)

Answer

# 初回のみ (証明書作成)
PC ブラウザ → GitHub → GitHub Codespaces → EAS (build)

# 2 回目以降 (すべて iPhone から)
iPhone → GitHub → GitHub Actions → EAS (build)
iPhone → GitHub → GitHub Actions → EAS (submit)
        → App Store Connect → TestFlight → iPhone
Mac は必要である。ただし、クラウドの中にあればいい。

EAS (Expo Application Services) の build サービスは、クラウド側の macOS 環境で iPhone アプリを build してくれる。手元に必要なのは、コマンドを投げる端末だけ。それは iPhone で足りる。

Reason

初回だけ PC ブラウザを使ったのは、対話操作のためである。 初回 build では署名用の証明書 (App Store 用の credentials) を作る必要があり、その過程で Y/N を聞かれる対話式の入力が発生する。基本は Y を答えるだけなのだが、これを GitHub Actions で自動化しようとすると、応答のタイミング合わせのような面倒なコーディングが必要になる。年に数回あるかどうかの操作を自動化する価値はないと判断して、初回だけ手動にした。

その手動操作も、Mac は要らない。GitHub Codespaces — GitHub がブラウザ上に用意してくれる VS Code 環境 — を開けば、そこからコマンドを叩ける。個人アカウントの無料枠 (120 コア時間/月) で十分足りる。理屈の上ではスマホのブラウザでも可能だが、ターミナル操作にはさすがに画面が小さすぎたので、ここだけ PC のブラウザを使った。繰り返すが、PC であって Mac である必要はない。

2 回目以降は対話が不要になるので、iPhone から GitHub Actions の workflow を実行するだけで build が走る。build が成功したら、同じく Actions から submit すると、App Store Connect に上がり、TestFlight で実機に降ってくる。申請の直前まで、すべて iPhone で完結する。

Options

  • Xcode Cloud — Apple 純正の CI/CD。ただし初回のセットアップに Xcode つまり Mac が必要で、「Mac を所有しない」という Criteria と矛盾するため見送り。アプリを EXPO で実装している以上、EAS との親和性が高いことも決め手になった。
  • GitHub Actions の macOS ランナー — Actions 上で直接 macOS を立ち上げて build する手もある。ただし macOS ランナーの利用は Linux の 10 倍の分数消費で課金される。無料枠 2,000 分/月がみるみる溶けるので、チャレンジしていない。

03Result

Good

build も submit も EAS に集約されたので、管理が一元化された。EXPO での開発 (1.1.1) と地続きのまま、申請直前の工程までスマホで届く。「Mac が要る」という iPhone アプリ開発最大の参入障壁が、実は「Mac を持つ必要」ではなかったと分かったのは収穫だった。

Bad

無料枠の組み合わせには制約がある。執筆時点の値で:

サービス無料枠備考
EAS buildiOS 15 回/月 (+ Android 15 回/月)build エラーでも回数を消費する
GitHub Actions2,000 分/月Free プランの private リポジトリの場合

通常の開発でこの上限を超えることはまずない。ただし、ネイティブまわりの動作確認でバグが出て build を繰り返すと、一気に持っていかれる。特に痛いのが、build エラーでも回数がカウントされること。設定ミスで 3 連続エラー、などとやると月の 2 割が消える。

Follow-up

EAS の無料枠 build は優先度が低く、キュー待ちが異様に長いことがある。気長に待てばいいのだが、ここに落とし穴がある。Actions 上で build の完了を待っていると、その待ち時間が Actions の 2,000 分/月からも消費されていく。待っても待たなくても build の結果は同じなので、eas build には --no-wait を付けて、trigger したら workflow を即終了させるのが正解である。

その代わり build と submit が 1 本の workflow で繋がらなくなるので、EAS のダッシュボードで build の成功を確認してから、Actions で submit を実行する、という 2 段運用にしている。submit 側も同様に --no-wait が使える。

ここまでで「作って届ける」の縦の線が通った。まずはこれでリリースできる。リリースが済んだら、OTA を安全に運用する設定 — 開発用と公開用の配信経路を分ける 1.1.3 EAS Update の安全な運用 — を入れて、改修時の誤配信を防いでおきたい。次は横に広げる話、1.2 多言語対応 に続く。

手動で GitHub Actions を起動しているのだが (Claude のクレジットがもったいないので)、Claude に Actions の起動もお願いしてしまった方が良い気がしている。気がしていると言うか最近そうしている。手動で Actions を起動すると、Claude 上にやったことが残らないため、次に Claude と会話していると「まだリリースしてないから大丈夫ですよね」的な判断をされることがある。Claude の進捗ファイルにアプリの status を記録させるためには、クレジットが多少もったいなくても Claude 経由で指示を出した方がズレることがない。(build した後に「build したよ」と教えてあげれば良いんだけど。)

■ 再現できる方法

この構成を自分で再現したい人向けのメモ。読み物ではないので、指示文は数行だけ表示してスクロールにしてある。

  1. Apple Developer Program に登録 (年 $99、developer.apple.com/programs)
  2. App Store Connect で App ID を発行 (アプリ枠を作る → ascAppId (数値) を控える)
  3. App Store Connect API Key を発行 (Users and Access → Integrations → App Store Connect API)。.p8 ファイル・Key ID・Issuer ID の 3 点を控える (.p8 は再ダウンロード不可なので必ず保存)
  4. GitHub Secrets に 3 つ追加: APPLE_API_KEY (.p8 の全文) / APPLE_API_KEY_ID / APPLE_API_KEY_ISSUER_ID

してから、下記を貼り付けで実行。

このアプリを iOS でビルドして App Store Connect に提出できるようにしたいです。
ビルドは EAS Build、提出は EAS Submit を使い、2 回目以降は GitHub Actions の
手動トリガ(workflow_dispatch)で回せる構成にしてください。

【作ってほしいもの】
1. app.json にビルドに必要な項目を追加
   - ios.bundleIdentifier(私が Apple Developer で登録した値。後で私が差し替える
     ので、いったんプレースホルダで置いてコメントで指示してください)
   - ios.supportsTablet / requireFullScreen など基本項目
   - version(1.0.0 スタート。ビルドのたびに上げる方針をコメントで明記)
2. eas.json
   - production プロファイル
   - submit.production.ios.ascAppId は私が後で入れるのでプレースホルダに
3. .github/workflows/eas-build-ios.yml(workflow_dispatch)
   - buildNumber を YYYYMMDDHHMM で自動採番して app.json に書き込む
   - eas build --profile production --platform ios --non-interactive --no-wait
   - Apple 系の認証は Secrets(APPLE_API_KEY / APPLE_API_KEY_ID /
     APPLE_API_KEY_ISSUER_ID)を env で渡す
4. .github/workflows/eas-submit-ios.yml(workflow_dispatch)
   - Secrets の APPLE_API_KEY を一時ファイル(.p8)に書き出して eas.json に注入
   - eas submit --platform ios --profile production --latest --non-interactive

【重要な注意をコメントで残してほしい】
- 初回ビルドだけは対話シェルで手動実行が必要(証明書発行の対話プロンプトが
  出るため、CI では応答できない)。2 回目以降は CI の非対話モードで通せる、と。
- ビルドのたびに app.json の version を上げる(Apple の重複バージョンエラー回避)

作り終えたら、私が Codespaces で初回ビルドを通すための具体コマンドを
手順で教えてください。

下記を参考にして教えて。
(これは Claude Code への指示ではなく、自分が Codespaces のターミナルで叩くコマンド)

# 1. リポジトリの Codespace を開く(GitHub の Code → Codespaces → Create)
# 2. EAS CLI を入れて Expo にログイン
npm install -g eas-cli
eas login            # Expo のユーザー名 / パスワードを対話入力

# 3. 依存を入れる
npm install --legacy-peer-deps

# 4. 初回ビルド(ここで証明書の対話プロンプトに「Yes」で答えていく)
eas build --platform ios --profile production
# → 証明書は EAS 側に保存されるので、次回以降は CI から非対話で通せる

自分でコマンドを叩くときも、PC のブラウザをスマホで写真を撮っておいて「何すれば良いの?」と Claude に聞くと全部教えてくれる。基本 Y を押すだけで良い。App Store Connect (ブラウザ) でアプリの ID を作らないといけないのだが、それも「Claude で必要な項目足りてる?」と聞くと教えてくれる。