1. なぜセルフホストの Mac ランナーを使うのか?
GitHub ホスト型の macOS ランナーは便利ですが高価です。1 分あたり$0.08で、月に 75 時間のビルドを実行するチームは約$360を支払うことになります。MyRemoteMac の専用 Mac Mini M4 なら、ビルド分数が無制限で月額$85であり、同等(またはそれ以上)のハードウェアをわずかなコストで利用できます。
| 項目 | GitHub ホスト型ランナー | MyRemoteMac セルフホスト |
|---|---|---|
| コスト | $0.08/分(75 時間で約$350/月) | 月額$85(無制限の分数) |
| アーキテクチャ | Intel x86(一部 M1) | Apple M4(最新) |
| ビルド速度 | 約 12 分(中規模プロジェクト) | 約 4 分(同じプロジェクト) |
| 永続的なキャッシュ | なし(使い捨て) | あり(永続的なディスク) |
| カスタムソフトウェア | 限定的 | 完全な root アクセス |
| 同時ジョブ数 | 5(無料)/ 20(有料) | 無制限(自分のハードウェア) |
主なメリット: ランナーが永続的であるため、DerivedData、SPM キャッシュ、CocoaPods がビルド間で保持されます。これだけでも、毎回ゼロから始まる使い捨ての GitHub ホスト型ランナーと比べて、ビルド時間を 50〜70% 短縮できます。
2. 前提条件
始める前に、次のものが揃っていることを確認してください。
- MyRemoteMac の Mac Mini M4 サーバー(月額$85から)
- リポジトリまたは組織への管理者アクセス権を持つ GitHub アカウント
- Mac Mini への SSH アクセス(MyRemoteMac のサブスクリプションに付属します)
- Apple Developer アカウント(コード署名とプロビジョニングプロファイル用)
- YAML と ターミナルコマンドの基本的な知識
3. ステップ 1: Mac Mini に SSH 接続して Xcode をインストールする
まず、Mac Mini M4 に SSH で接続します。MyRemoteMac サーバーをセットアップした際に認証情報を受け取っているはずです。
SSH で接続する
# Connect to your Mac Mini M4
ssh admin@your-server-ip
# Verify you're on Apple Silicon
uname -m
# Expected output: arm64
# Check macOS version
sw_vers
# ProductName: macOS
# ProductVersion: 15.2
# BuildVersion: 24C101
Xcode Command Line Tools をインストールする
# Install Command Line Tools
xcode-select --install
# Accept the license agreement
sudo xcodebuild -license accept
# Verify installation
xcode-select -p
# /Library/Developer/CommandLineTools
Xcode(フルバージョン)をインストールする
iOS ビルドには Xcode アプリケーションの完全版が必要です。ヘッドレスサーバーにインストールする最も速い方法は xcodes を使うことです。
# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Add Homebrew to PATH
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
# Install xcodes CLI tool
brew install xcodes
# List available Xcode versions
xcodes list
# Install the latest stable Xcode
xcodes install 16.2
# Set it as the active Xcode
sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
# Verify
xcodebuild -version
# Xcode 16.2
# Build version 16C5032a
iOS シミュレーターをインストールする
# Install the iOS 18 simulator runtime
xcodebuild -downloadPlatform iOS
# Verify simulator availability
xcrun simctl list runtimes
# == Runtimes ==
# iOS 18.2 (18.2 - 22C150) - com.apple.CoreSimulator.SimRuntime.iOS-18-2
4. ステップ 2: GitHub Actions ランナーをインストールする
次に、GitHub Actions ランナーエージェントをダウンロードして設定します。GitHub 上でリポジトリに移動し、Settings > Actions > Runners > New self-hosted runner に進んで、macOS + ARM64 を選択します。
ダウンロードして設定する
# Create a directory for the runner
mkdir -p ~/actions-runner && cd ~/actions-runner
# Download the latest runner package (ARM64)
curl -o actions-runner-osx-arm64-2.321.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.321.0/actions-runner-osx-arm64-2.321.0.tar.gz
# Extract the package
tar xzf actions-runner-osx-arm64-2.321.0.tar.gz
# Configure the runner
# Replace YOUR_TOKEN with the token from GitHub Settings
./config.sh --url https://github.com/YOUR_ORG/YOUR_REPO \
--token YOUR_TOKEN \
--name "mac-mini-m4-runner" \
--labels "self-hosted,macOS,ARM64,M4" \
--work "_work"
# Test the runner interactively first
./run.sh
永続的な launchd サービスとしてインストールする
エージェントを対話的に実行するのはテストには問題ありませんが、本番では起動時に自動的に開始し、クラッシュしても再起動する必要があります。GitHub は macOS 向けの組み込みサービスインストールスクリプトを提供しています。
# Install as a launchd service
cd ~/actions-runner
sudo ./svc.sh install
# Start the service
sudo ./svc.sh start
# Check the service status
sudo ./svc.sh status
# Expected: "active (running)"
# View the launchd plist (for reference)
cat /Library/LaunchDaemons/actions.runner.*.plist
これでサービスは起動時に自動的に開始し、プロセスが停止しても再起動するようになります。ランナーがリポジトリの Settings > Actions > Runners ページに「Idle」として表示されることを確認できます。
複数のリポジトリ向けにランナーを設定する(組織レベル)
# For an organization-level runner, use the organization URL:
./config.sh --url https://github.com/YOUR_ORG \
--token YOUR_ORG_TOKEN \
--name "mac-mini-m4-org-runner" \
--labels "self-hosted,macOS,ARM64,M4" \
--runnergroup "Default" \
--work "_work"
# This allows ALL repositories in your organization to use this runner
5. ステップ 3: iOS ビルドワークフローを作成する
リポジトリ内の .github/workflows/ios-build.yml にワークフローファイルを作成します。このワークフローは、セルフホストの Mac Mini M4 ランナー上で実行されます。
name: iOS Build & Test
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: [self-hosted, macOS, ARM64, M4]
env:
SCHEME: "MyApp"
DESTINATION: "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Select Xcode version
run: |
sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
xcodebuild -version
- name: Resolve Swift Package Dependencies
run: |
xcodebuild -resolvePackageDependencies \
-scheme "$SCHEME" \
-clonedSourcePackagesDirPath .spm-cache
- name: Build the app
run: |
xcodebuild build \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-clonedSourcePackagesDirPath .spm-cache \
-derivedDataPath DerivedData \
| xcbeautify
- name: Run unit tests
run: |
xcodebuild test \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-clonedSourcePackagesDirPath .spm-cache \
-derivedDataPath DerivedData \
-resultBundlePath TestResults.xcresult \
| xcbeautify
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: TestResults.xcresult
リリースビルドのためのコード署名を追加する
TestFlight や App Store へのデプロイには、コード署名のステップを追加します。証明書とプロビジョニングプロファイルは GitHub Secrets として保存してください。
deploy:
needs: build
runs-on: [self-hosted, macOS, ARM64, M4]
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# Create a temporary keychain
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Import certificate
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" \
-A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# Install provisioning profile
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Build for distribution
run: |
xcodebuild archive \
-scheme "MyApp" \
-archivePath DerivedData/MyApp.xcarchive \
-destination "generic/platform=iOS" \
CODE_SIGN_STYLE=Manual
- name: Export IPA
run: |
xcodebuild -exportArchive \
-archivePath DerivedData/MyApp.xcarchive \
-exportOptionsPlist ExportOptions.plist \
-exportPath DerivedData/Export
- name: Upload to TestFlight
env:
APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
run: |
xcrun altool --upload-app \
-f DerivedData/Export/MyApp.ipa \
-t ios \
--apiKey $APP_STORE_CONNECT_API_KEY
6. ステップ 4: パフォーマンスを最適化する
セルフホストランナーの最大の利点の 1 つは、永続的なキャッシュです。ここでは、Mac Mini M4 を最大限に活用するための主要な最適化を紹介します。
DerivedData のキャッシュを有効にする
ランナーが永続的であるため、DerivedData はビルド間で保持されます。一貫した DerivedData のパスを使用してください。
# In your workflow, always use:
-derivedDataPath DerivedData
# On the runner, periodically clean old DerivedData to save space:
# Add a cron job to clean builds older than 7 days
echo "0 3 * * 0 find ~/actions-runner/_work/*/DerivedData -maxdepth 0 -mtime +7 -exec rm -rf {} +" \
| crontab -
SPM パッケージをキャッシュする
# Use clonedSourcePackagesDirPath to keep SPM packages on disk
xcodebuild build \
-scheme "MyApp" \
-clonedSourcePackagesDirPath ~/spm-cache \
-derivedDataPath DerivedData
# This avoids re-downloading packages on every build
テストの並列実行
# Run tests in parallel across multiple simulators
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-destination "platform=iOS Simulator,name=iPhone 15,OS=17.5" \
-parallel-testing-enabled YES \
-maximum-parallel-testing-workers 4 \
-derivedDataPath DerivedData \
| xcbeautify
より見やすいログのために xcbeautify をインストールする
# xcbeautify formats Xcode output for CI environments
brew install xcbeautify
# Use it by piping xcodebuild output:
xcodebuild build -scheme "MyApp" | xcbeautify
7. よくある問題のトラブルシューティング
GitHub でランナーが「Offline」と表示される
これは通常、launchd サービスが実行されていないことを意味します。サービスの状態とログを確認してください。
# Check service status
sudo ./svc.sh status
# View logs
cat ~/actions-runner/_diag/Runner_*.log | tail -50
# Restart the service
sudo ./svc.sh stop
sudo ./svc.sh start
コード署名が「No signing certificate」で失敗する
launchd サービスは異なるユーザーコンテキストで実行されます。キーチェーンにアクセスできることを確認してください。
# Ensure the login keychain is unlocked for the runner user
security unlock-keychain -p "YOUR_PASSWORD" ~/Library/Keychains/login.keychain-db
# Or use a dedicated keychain in your workflow (recommended)
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
シミュレーターの起動に失敗する
シミュレーターは時々動かなくなることがあります。ビルド間でリセットしてください。
# Shutdown all running simulators
xcrun simctl shutdown all
# Erase all simulator data (nuclear option)
xcrun simctl erase all
# Boot a specific simulator
xcrun simctl boot "iPhone 16 Pro"
ディスク容量が不足してくる
Xcode のビルドは大量のデータを生成します。自動クリーンアップを設定してください。
# Clean old DerivedData
rm -rf ~/Library/Developer/Xcode/DerivedData/*
# Remove old simulator runtimes
xcrun simctl runtime delete all
# Clean Homebrew cache
brew cleanup --prune=7
# Remove old Xcode archives
rm -rf ~/Library/Developer/Xcode/Archives/*
8. コスト分析
さまざまなチーム規模とビルド量に対する詳細なコスト比較を示します。
| チーム規模 | 月間ビルド数 | GitHub ホスト型の費用 | MyRemoteMac の費用 | 月間節約額 |
|---|---|---|---|---|
| 個人開発者 | 100 ビルド(平均 10 分) | 月額$80 | 月額$85 | 月額$5 |
| 小規模チーム(5 人) | 500 ビルド(平均 10 分) | 月額$400 | 月額$85 | 月額$325 |
| 中規模チーム(15 人) | 1500 ビルド(平均 10 分) | 月額$1,200 | 月額$229(M4 Pro) | 月額$971 |
| エンタープライズ(50 人以上) | 5000 ビルド以上 | 月額$4,000以上 | 月額$458(M4 Pro 2 台) | 月額$3,542以上 |
結論: 月に約 100 ビルドを超えるチームであれば、セルフホストの Mac Mini M4 はすぐに元が取れます。さらに、ウォームキャッシュを備えた永続的なハードウェアではビルドが速くなるため、チームの開発時間も節約できます。