4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

クラウド上で macOS アプリをビルド・テスト(Devin Outposts × Namespace)

4
Last updated at Posted at 2026-08-09

Devin Outposts がリリースされたことも、Namespace というサービスで macOS の VM が使えることも、知ってはいました。試したいとも思っていましたが、それでも手を付けられずにいたのは、単純に設定が大変そうな気がしたからです。macOS の CI 環境まわりで消耗した経験があると、腰が重くなります。

手の動いたきっかけは Cognition の Nader Dabit の投稿でした。

これを見て、ようやく自分でも設定して試してみました。この記事はその経緯です。

結論から言うと、Mac 実機を 1 台も追加せずに AI エージェント(Devin)に macOS ネイティブアプリの xcodebuild を回させることができました。設定は拍子抜けするほど簡単で、私が実際にやった操作はアカウント作成とリポジトリ連携、あとは blueprint を 1 つ作っただけです。

そして回してみたら、CI が緑だったはずの main が特定の Xcode では壊れていることが判明しました。そのまま修正 PR → マージ → 同じ環境で再検証まで、人間はほぼ承認ボタンを押すだけで終わっています。

しかも クレジットカードは未登録、請求は 0 円でした(トライアル期間中)。

なお、この環境では「GUI が無いので視覚検証は無理」と最初は結論したのですが、これは誤りでした。スクリーンショットもクリックも XCUITest も動きます。そちらは別記事にまとめています。

この記事の対象

  • AI エージェントにネイティブアプリを触らせたい人(Swift に限らず、「エージェントはコードを書けるがビルドを確認できない」問題全般)
  • Devin を使っていて、macOS / iOS のリポジトリで詰まっている人
  • Xcode Cloud や GitHub Actions の macOS runner との使い分けを知りたい人

題材は自作の macOS リアルタイム翻訳字幕アプリ kinopeee/interpreter-openai(Swift 6 / AppKit / XcodeGen)です。

何が問題だったか

Devin のセッションは通常 Linux(や Windows)の VM 上で動きます。ところが対象が macOS ネイティブアプリだと xcodebuild が存在しないため、

  • コードは Devin が書ける
  • ビルドが通るかは人間が手元で確認するしかない

という、いちばん面倒な部分だけが人間に残ります。エージェントに任せたいのは「書く」ことより、むしろ「通るまで直す」ループの方なのに。

これを解決するのが Devin Outposts です。

Devin Outposts とは

  • Devin のエージェントループ(推論・計画)は Devin のクラウドで動く
  • コマンド実行・ファイル編集・リポジトリ操作は自分たちのマシンで動く
  • マシン側は Devin CLI の worker を起動しておくだけ。必要なのはアウトバウンド HTTPS のみで、インバウンドポートも公開 IP も VPN も要らない

自前 Mac mini に worker を常駐させる構成も可能ですが、今回はパートナー統合の Namespace を使いました。こちらはセッションごとに Apple Silicon の macOS Devbox が自動で立ち上がり、終われば破棄されるので、マシンの面倒を一切見なくて済みます。

参考: Devin Outposts 公式ドキュメント

手順

私が実際にやった操作は、Namespace のアカウント作成(Google 認証)、GitHub リポジトリ連携、Devin 連携の認証、そして blueprint を 1 つ作っただけです。

0. 前提

項目 必要なもの
Devin 側 account で Outposts が有効/account.enterprise_settings.manage 権限を持つ管理者
Namespace 側 Namespace アカウント(30 日トライアルあり、クレカ登録不要)

1. Namespace で Devbox blueprint を作る

Namespace のダッシュボードで Devboxes → Blueprints → New Blueprint と進みます。

TODO-01-blueprint.png

設定した内容:

項目 値 補足
Name macos-26-xcode26 この名前が Devin 側の選択肢に出る
Operating system macOS (Apple Silicon)
macOS version / Xcode Tahoe / Standard 26.3.1 with Xcode 26.3 アプリの deployment target が macOS 26 のため
Instance size M 足りなければ L に上げる
Ephemeral OFF
Volume size 150 GB
Git repository 対象リポジトリ Devbox 起動時に clone される
Access mode Workspace-wide (shared) ← Devin 連携ではこれが必須
Auto-stop timeout on idle 15 min

2. Devin と接続する

同じ blueprint 画面の Integrations にある「Connect with Devin」を押すと、ブラウザで Devin 側の承認画面が開きます。

TODO-02-connect-with-devin.png

  • Outpost 名(既定は namespace-devbox。私は macos-26-xcode26 にしました)
  • Platform: macOS を選択

承認すると、Devin の Settings → Environment → Outposts に Outpost が登録されます。

承認には Devin 側の管理者権限(account.enterprise_settings.manage)が必要です。

3. セッションで選ぶ

Devin の新規セッション画面で Settings → Virtual environment を開くと、Hosted(Ubuntu / Windows)と並んで Outposts セクションに作成した環境が出てきます。これを選べば終わりです。

TODO-03-virtual-environment.png

まずは動作確認に、こんなプロンプトが手軽です。

What is the OS version and flavor? Also run `xcodebuild -version` and `swift --version`.

実際に動かした結果

環境

項目 結果
macOS 26.3.1 (arm64)
Xcode 26.1.1 (17B100)
Swift 6.2.1
Homebrew あり
git 2.53.0
ffmpeg なし
sudo パスワード不要で利用可
xcodegen なし(brew install xcodegen で 10 秒)

blueprint で Xcode 26.3 を選んだのに実際は 26.1.1 でした。後述しますが、この「思っていたのと違う Xcode」がむしろ収穫になります。

build / test

brew install xcodegen
xcodegen generate

xcodebuild -scheme RealtimeTranslator -destination 'platform=macOS' \
  -derivedDataPath ./build/DerivedData CODE_SIGNING_ALLOWED=NO build
# => BUILD SUCCEEDED / 約 10 秒

xcodebuild test -scheme RealtimeTranslator -destination 'platform=macOS' \
  -derivedDataPath ./build/DerivedData CODE_SIGNING_ALLOWED=NO
# => Executed 236 tests, with 0 failures / 約 16 秒

ビルド 10 秒、テスト 16 秒。Apple Silicon なので普通に速いです。

CI が緑なのに main が壊れていた

環境確認のつもりで走らせた最初のテストが、いきなりコンパイルエラーで落ちました。

TODO-04-compile-error.png

RealtimeTranslator/Tests/CodecFixtureTests.swift:285:36: error:
cannot convert value of type 'String?' to expected argument type '[String]'

犯人はこの 1 行。

let keywords = (fixture["keywords"] as? [Any] ?? []).map(SharedFixtures.text)

型注釈が無いと ?? が (T?, T?) -> T?(T = Any)として解決されることがあり、受け手が Any? になって Array.map ではなく Optional.map が選ばれ、結果が String? になります。Swift のバージョン依存の罠です。

手元の Xcode では通る。GitHub Actions(macos-26 runner)でも緑。でも Devbox の Xcode 26.1.1 / Swift 6.2.1 では落ちる。

修正は 1 行で済みました。

-        let keywords = (fixture["keywords"] as? [Any] ?? []).map(SharedFixtures.text)
+        let keywords: [String] = (fixture["keywords"] as? [Any] ?? []).map(SharedFixtures.text)

発見から再検証までが 1 本の線でつながる

面白かったのはここからで、「Devbox が動くか見る」だけのつもりが、そのまま修正まで流れました。

  1. macOS Outpost セッションが Devbox 上でコンパイルエラーを検出
  2. 原因を特定し、1 行の型注釈で通ることをその場で確認(この時点では commit せず revert)
  3. Devin が修正ブランチを切って PR を作成 → PR #43
  4. GitHub Actions の 6 チェックすべて green を確認してマージ
  5. マージ後の main(5fb8068)を、もう一度 macOS Outpost で clean に build / test → Executed 236 tests, with 0 failures

TODO-05-pr43-checks-green.png

人間がやったのは「PR を出していい?」に OK を出したのと、マージボタンを押したことだけです。

ポイントは 5 だと思っていて、CI が緑になったことと、実際に落ちていた環境で通ることは別の話です。今回は「壊れていた環境そのもの」で直ったことまで確認して閉じられました。

そして 3〜4 の対比が示すのは、macos-26 runner が Xcode バージョンを固定していない以上、CI が緑でも「特定の Xcode では落ちるコード」は普通に main に入るということ。手元と違う Xcode を 1 つ増やすだけで環境依存の脆さが炙り出せるのは、Outposts の副次的な効能として地味に大きいです。

ハマりどころ・注意点

私が実際に踏んだものを挙げておきます。

  • Access mode は Workspace-wide (shared) が必須。Private (just me) のままだと Devin から使えません。
  • 署名証明書が無いので、build / test には CODE_SIGNING_ALLOWED=NO を付ける必要があります。
  • scripts/run.sh のような自前スクリプトはそのままでは動かないことがあります。私のリポジトリのものは CODE_SIGNING_ALLOWED=NO を渡しておらず、No signing certificate "Mac Development" found で失敗しました(ビルド済み成果物を open すればアプリ自体は起動します)。
  • 実マイクが無いので、AVCaptureDevice の audio デバイス列挙は 0 件でした。私のアプリのように「音声を入れて字幕が出るか」を見る E2E は Devbox 上ではできません。
  • XcodeGen などのツールは素の状態では入っていません。brew install は通りますが、セッションごとに新しい Devbox が立つので、入れたものは次のセッションには残りません(/opt/homebrew も /Applications も 150 GB の永続 volume の外で、volume に乗っているのは workspace/ と state/ だけでした)。
  • blueprint で指定した Xcode と実際のバージョンが一致しないことがあります(26.3 指定で実際は 26.1.1)。バージョン厳密性が要る場合は実行時に xcodebuild -version を確認しましょう。
  • screencapture は素の状態では失敗します。ただし GUI が無いからではなく TCC の権限問題で、権限を付与すればスクリーンショットも GUI 操作もできます。この件は長くなるので別記事にしました(次節)。

セッションの冒頭で毎回やること

ここは注意が必要です。直感的には「blueprint に仕込んでおけばいい」と思うところですが、Namespace の blueprint 画面には起動時コマンドの欄がありません。UI で設定できるのは名前・Instance size・Ephemeral・Volume・Git repository・Access mode・Auto-stop・環境変数・Egress policy・Devin 連携だけで、任意コマンドを走らせる sessions は CLI の spec file 側にしかありません。しかもセッションごとに Devbox が作り直されるので、前回入れたものは残っていません。

つまり UI しか使わないなら、次はセッションごとに指示することになります。

  • brew install xcodegen(XcodeGen 前提のプロジェクトなら必須。入っていませんが 10 秒で入ります)
  • ビルド/テストは CODE_SIGNING_ALLOWED=NO 付きで実行する
  • GUI 操作まで使うなら TCC の権限付与(手順は別記事)

Devin の machine dependencies としては git が必須、ffmpeg(録画)と Chrome/Chromium(ブラウザ操作)は任意とされています。この macOS イメージには Chrome は最初から入っています。ffmpeg は入っていませんが、入れても Devin の画面録画は現状失敗します(原因は別記事に書きました)。

GUI 検証もできました(別記事)

この記事を最初に書いた時点では「Devbox に GUI は無いので視覚検証は無理」と結論していました。これは誤りでした。launchctl managername が Background を返すのは GUI の有無とは関係がなく、screencapture が失敗していた真因は TCC の責任プロセス(responsible process)の判定でした。

権限を付与したあとは、スクリーンショット、CGEvent によるマウス・キーボード操作、macOS XCUITest、iOS Simulator まで動きました。診断の過程と再現手順は別記事にまとめています。

GUI はないはずの macOS Devbox で、スクショもクリックも XCUITest も動作!

結果として、この環境でできないことは実マイクを使った音声 E2E だけでした。

コスト感

Namespace は「compute unit(1 vCPU + 2GB RAM × 1 分)」課金で、macOS は Linux の 10 倍レートです。

shape prepaid overage 1 時間あたり
4 vCPU / 7 GB $0.05/min $0.075/min $3.0 / $4.5
6 vCPU / 14 GB $0.06/min $0.09/min $3.6 / $5.4
12 vCPU / 28 GB $0.12/min $0.18/min $7.2 / $10.8

6 vCPU でセッション平均 1 時間とすると、月 10 セッションで $36 前後。Team プラン($100/月・100,000 unit minutes 込み)だと macOS 6 vCPU で約 28 時間分に相当します。

Devbox は idle で自動停止し、停止中は課金されません。Outposts 構成ではセッション終了とともに Devbox が破棄されるので、実質「セッションを回した時間だけ」の課金です。

今回の請求は 0 円

そもそもクレジットカードを一度も登録していません(サインアップ時に不要)。その状態で macOS Devbox のセッションを 2 回回し、build と test を通しました。

TODO-06-usage-zero.png

Workspace → Usage を見ると Compute usage は 0、Unit minutes も -。Usage explorer を macos/arm64 で見ても計上ゼロでした。トライアル期間中はこうなるようです。

試すだけならタダで、カード登録すら要らない。想像以上に敷居が低かったです。もちろんトライアルが終われば前掲のレートで課金されるので、継続するなら Usage の Projection を見ながら判断してください。

Xcode Cloud との違い

「macOS のビルド/テストをクラウドで回す」と聞くと Xcode Cloud を思い浮かべる人も多いと思うので、比較しておきます。

Xcode Cloud とは

Apple 純正の CI/CD サービスで、Xcode と App Store Connect に組み込まれています。

  • Xcode 上でワークフローを定義し、push / PR / タグ / スケジュールをトリガーに、Apple 管理の macOS 環境でビルド・テスト・配布を実行する
  • TestFlight / App Store への配布まで一気通貫(署名周りは Apple 側が面倒を見てくれる)
  • シミュレータや実機でのテスト実行に対応
  • カスタム処理は ci_scripts/ci_post_clone.sh のようなフックスクリプトで差し込む
  • 利用には Apple Developer Program(99 USD/年)が必要。25 compute hours/月が無償で込みで、追加は 100h $49.99 / 250h $99.99 / 1,000h $399.99 / 10,000h $3,999.99 の月額サブスク

決定的な違いは「CI か、エージェントの実行環境か」

Xcode Cloud Devin Outposts (Namespace macOS)
位置づけ CI/CD サービス エージェントが対話的に使うマシン
実行トリガー push / PR / タグ / スケジュール Devin のセッション開始時
任意コマンド実行 不可(定義済みワークフロー+フックスクリプトのみ) 可(シェルそのもの。brew install、root も可)
失敗時の挙動 落ちる。人間がログを見て直して再 push Devin がログを読んで直してその場で再実行
環境の自由度 Apple 管理の固定環境(Xcode バージョンは選択可) macOS / Xcode バージョンを選択、マシンサイズも選択
署名・配布 得意(TestFlight / App Store 連携) 不向き(署名証明書なし)
GUI 検証 シミュレータ上の XCUITest は可 可(macOS XCUITest / iOS Simulator / CGEvent。ただし TCC 付与が必要)
前提 Apple Developer Program (99 USD/年) Namespace アカウント + Devin の Outposts 有効化
料金 25h/月 無償、以降サブスク(100h で $49.99 = 約 $0.5/h) 従量(macOS 6 vCPU で約 $3.6/h)

単価だけ見ると Xcode Cloud が圧倒的に安いですが、やっていることが違います。Xcode Cloud は決められた手順を回すだけなので安く、Outposts はエージェントが試行錯誤するためのマシンを占有するので高い。今回のように「落ちた原因をその場で特定して直す」は、シェルが握れる Outposts だからできたことです。Xcode Cloud なら「赤くなった」で終わり、そこから先は人間の仕事になります。

使い分け

  • リグレッション検知と配布なら Xcode Cloud(あるいは GitHub Actions の macos-26 runner)。安いし、これが本来の仕事です。
  • エージェントに macOS のコードを直させる、ビルドを通させるなら Outposts。人間が「ビルド確認係」をやらなくて済みます。

排他ではなく併用が素直です。実際このリポジトリは、リグレッションは GitHub Actions、Devin に作業させる時は Outposts、という構成にしています。

まとめ

Mac 実機ゼロでも、blueprint を 1 つ作るだけで AI エージェントに macOS の build / test をやらせられました。副産物として CI が緑なのに特定の Xcode で落ちるコードが見つかり、修正 PR からマージ、同じ環境での再検証まで一気通貫で終わりました。トライアル中はカード未登録、0 円です。

「エージェントにコードは書かせられるが、ビルドが通るかを人間が確認している」という状況の人には、かなり効く選択肢だと思います。

この記事について

ここに書いた作業で、私がやったのは指示を出すことだけです。blueprint の設定内容を決めたあとの環境調査、build と test の実行、コンパイルエラーの原因特定、修正 PR の作成まで、実際に手を動かしたのはすべて Devin です。

この記事の下書きも Devin が書きました。そのあとのレビューと手直しは私が入れています。

参考リンク

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?