1. Mengapa Menggunakan Self-Hosted Mac Runner?
Runner macOS yang di-host GitHub praktis tetapi mahal. Dengan $0.08 per menit, tim yang menjalankan 75 jam build per bulan membayar sekitar $360. Mac Mini M4 dedikasi dari MyRemoteMac berbiaya $85/bulan dengan menit build tanpa batas, memberi Anda hardware yang sama (atau lebih baik) dengan biaya jauh lebih murah.
| Fitur | Runner yang Di-host GitHub | MyRemoteMac Self-Hosted |
|---|---|---|
| Biaya | $0.08/menit (~$350/bln untuk 75 jam) | $85/bln (menit tanpa batas) |
| Arsitektur | Intel x86 (sebagian M1) | Apple M4 (terbaru) |
| Kecepatan Build | ~12 mnt (proyek menengah) | ~4 mnt (proyek yang sama) |
| Cache Persisten | Tidak (ephemeral) | Ya (disk persisten) |
| Perangkat Lunak Kustom | Terbatas | Akses root penuh |
| Job Bersamaan | 5 (gratis) / 20 (berbayar) | Tanpa batas (hardware Anda) |
Manfaat Utama: Karena runner bersifat persisten, DerivedData, cache SPM, dan CocoaPods dipertahankan di antara build. Ini saja dapat memangkas waktu build sebesar 50-70% dibanding runner ephemeral yang di-host GitHub yang selalu mulai dari nol setiap kali.
2. Prasyarat
Sebelum memulai, pastikan Anda memiliki hal-hal berikut:
- Server Mac Mini M4 dari MyRemoteMac (mulai $85/bln)
- Akun GitHub dengan akses admin ke repositori atau organisasi Anda
- Akses SSH ke Mac Mini Anda (disediakan dengan langganan MyRemoteMac Anda)
- Akun Apple Developer (untuk code signing dan provisioning profile)
- Pemahaman dasar tentang YAML dan perintah terminal
3. Langkah 1: SSH ke Mac Mini Anda dan Instal Xcode
Pertama, hubungkan ke Mac Mini M4 Anda melalui SSH. Anda telah menerima kredensial saat menyiapkan server MyRemoteMac Anda.
Hubungkan melalui 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
Instal 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
Instal Xcode (Versi Lengkap)
Untuk build iOS, Anda memerlukan aplikasi Xcode lengkap. Cara tercepat menginstalnya di server headless adalah menggunakan 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
Instal Simulator 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. Langkah 2: Instal GitHub Actions Runner
Sekarang mari unduh dan konfigurasikan agen GitHub Actions runner. Navigasikan ke repositori Anda di GitHub, buka Settings > Actions > Runners > New self-hosted runner, dan pilih macOS + ARM64.
Unduh dan Konfigurasikan
# 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
Instal sebagai Layanan launchd Persisten
Menjalankan agen secara interaktif tidak masalah untuk pengujian, tetapi untuk produksi Anda memerlukannya agar mulai otomatis saat boot dan restart jika crash. GitHub menyediakan skrip instalasi layanan bawaan untuk 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
Layanan sekarang akan mulai otomatis saat boot dan restart jika proses mati. Anda dapat memverifikasi runner muncul sebagai "Idle" di halaman Settings > Actions > Runners repositori GitHub Anda.
Konfigurasikan Runner untuk Beberapa Repositori (Tingkat Organisasi)
# 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. Langkah 3: Buat Workflow Build iOS Anda
Buat file workflow di repositori Anda pada .github/workflows/ios-build.yml. Workflow ini akan berjalan di self-hosted runner Mac Mini M4 Anda.
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
Tambahkan Code Signing untuk Build Rilis
Untuk deployment TestFlight atau App Store, tambahkan langkah code signing. Simpan sertifikat dan provisioning profile Anda sebagai 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. Langkah 4: Optimalkan Performa
Salah satu keunggulan terbesar dari self-hosted runner adalah caching persisten. Berikut optimasi utama untuk memaksimalkan Mac Mini M4 Anda.
Aktifkan Caching DerivedData
Karena runner bersifat persisten, DerivedData dipertahankan di antara build. Gunakan path DerivedData yang konsisten:
# 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 -
Cache Paket 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
Eksekusi Pengujian Paralel
# 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
Instal xcbeautify untuk Log yang Lebih Baik
# xcbeautify formats Xcode output for CI environments
brew install xcbeautify
# Use it by piping xcodebuild output:
xcodebuild build -scheme "MyApp" | xcbeautify
7. Pemecahan Masalah Umum
Runner muncul sebagai "Offline" di GitHub
Ini biasanya berarti layanan launchd tidak berjalan. Periksa status dan log layanan:
# 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
Code signing gagal dengan "No signing certificate"
Layanan launchd berjalan di bawah konteks pengguna yang berbeda. Pastikan keychain dapat diakses:
# 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
Simulator gagal boot
Simulator terkadang macet. Reset di antara build:
# 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"
Ruang disk menipis
Build Xcode menghasilkan banyak data. Siapkan pembersihan otomatis:
# 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. Analisis Biaya
Berikut perbandingan biaya yang detail untuk berbagai ukuran tim dan volume build:
| Ukuran Tim | Build/Bulan | Biaya yang Di-host GitHub | Biaya MyRemoteMac | Penghematan Bulanan |
|---|---|---|---|---|
| Dev Solo | 100 build (rata-rata 10 mnt) | $80/bln | $85/bln | $5/bln |
| Tim Kecil (5) | 500 build (rata-rata 10 mnt) | $400/bln | $85/bln | $325/bln |
| Tim Menengah (15) | 1500 build (rata-rata 10 mnt) | $1,200/bln | $229/bln (M4 Pro) | $971/bln |
| Enterprise (50+) | 5000+ build | $4,000+/bln | $458/bln (2x M4 Pro) | $3,542+/bln |
Kesimpulan: Untuk tim yang menjalankan lebih dari ~100 build per bulan, Mac Mini M4 self-hosted langsung membayar dirinya sendiri. Dan karena build lebih cepat pada hardware persisten dengan cache yang sudah terisi, tim Anda juga menghemat waktu pengembang.
Panduan Terkait
Jenkins Mac Build Agent
Konfigurasikan build agent Jenkins di Mac Mini dedikasi untuk CI/CD iOS.
Fastlane + Server Mac Dedikasi
Otomatiskan build iOS, tangkapan layar, dan deployment TestFlight dengan Fastlane.
GitLab CI Mac Runner
Daftarkan GitLab Runner di Mac Mini dedikasi untuk pipeline CI iOS/macOS.