1. Mengapa Menggunakan Self-Hosted Runner CircleCI di Mac?
CircleCI menawarkan lingkungan eksekusi macOS berbasis cloud, tetapi disertai biaya dan keterbatasan yang signifikan. Sumber daya macOS di CircleCI menggunakan sistem berbasis kredit di mana setiap menit pada eksekutor macOS mengonsumsi 50-100 kredit tergantung resource class-nya. Untuk tim yang sering menjalankan build iOS, ini dapat dengan cepat mencapai $300-$500 per bulan atau lebih.
Self-hosted runner di Mac Mini M4 dedikasi dari MyRemoteMac menghilangkan penagihan per menit sepenuhnya. Anda mendapatkan mesin Apple Silicon dedikasi dengan penyimpanan persisten, cache yang sudah terisi, dan akses root penuh dengan biaya bulanan tetap mulai dari $85/bulan. Berikut perbandingan detailnya:
| Fitur | CircleCI Cloud macOS | MyRemoteMac Self-Hosted |
|---|---|---|
| Model Biaya | 50-100 kredit/mnt (~$0.06-$0.12/menit) | $85/bln tetap (menit tanpa batas) |
| Arsitektur | Intel x86 atau M1 (bersama) | Apple M4 (dedikasi, terbaru) |
| Kecepatan Build | ~14 mnt (proyek iOS menengah) | ~5 mnt (proyek yang sama) |
| Persistensi Cache | Ephemeral (harus dipulihkan tiap job) | Persisten di disk (instan) |
| Waktu Tunggu Antrean | 30 dtk - 5 mnt (bervariasi per paket) | 0 dtk (hardware dedikasi) |
| Privasi / Kontrol Data | Infrastruktur bersama | Mesin dedikasi, kontrol penuh |
| Perangkat Lunak Kustom | Hanya image prainstal | Akses root penuh, perangkat lunak apa pun |
Manfaat Utama: Dengan self-hosted runner yang persisten, cache DerivedData, Swift Package Manager, dan CocoaPods dipertahankan di antara build. Ini saja dapat memangkas waktu build sebesar 50-70% dibanding lingkungan macOS cloud ephemeral CircleCI yang selalu mulai dari nol setiap kali. Dikombinasikan dengan performa single-thread chip M4 yang unggul, build iOS Anda akan jauh lebih cepat.
2. Prasyarat
Sebelum memulai, pastikan Anda memiliki hal-hal berikut:
- Server Mac Mini M4 dari MyRemoteMac (mulai $85/bln)
- Akun CircleCI dengan paket Performance, Scale, atau Server (self-hosted runner memerlukan paket berbayar)
- Akses SSH ke Mac Mini Anda (disediakan dengan langganan MyRemoteMac Anda)
- Akun Apple Developer (untuk code signing dan provisioning profile)
- Pemahaman dasar tentang YAML, konfigurasi CircleCI, dan perintah terminal
3. Langkah 1: SSH ke Mac Mini Anda dan Instal Dependensi
Pertama, hubungkan ke Mac Mini M4 Anda melalui SSH. Anda telah menerima kredensial saat menyiapkan server MyRemoteMac Anda. Kita perlu menginstal Xcode dan alat yang diperlukan untuk build iOS sebelum menyiapkan runner CircleCI.
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 Homebrew dan Xcode Command Line Tools
# 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 Xcode Command Line Tools
xcode-select --install
# Accept the license agreement
sudo xcodebuild -license accept
Instal Xcode (Versi Lengkap)
Untuk build iOS, Anda memerlukan aplikasi Xcode lengkap. Cara tercepat menginstalnya di server headless adalah menggunakan xcodes:
# 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 installation
xcodebuild -version
# Xcode 16.2
# Build version 16C5032a
Instal Simulator iOS dan Build Tools
# 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
# Install additional build tools
brew install xcbeautify fastlane swiftlint
4. Langkah 2: Instal Agen Runner CircleCI
CircleCI menggunakan agen machine runner untuk menghubungkan Mac Mini Anda ke platform CircleCI. Machine runner menerima job dari CircleCI dan menjalankannya langsung di host macOS Anda. Ini berbeda dari container runner (yang hanya bekerja di Linux).
Buat Pengguna Khusus untuk Runner
Disarankan untuk membuat pengguna khusus untuk menjalankan agen CircleCI demi isolasi keamanan:
# Create a circleci user (optional but recommended)
sudo dscl . -create /Users/circleci
sudo dscl . -create /Users/circleci UserShell /bin/zsh
sudo dscl . -create /Users/circleci RealName "CircleCI Runner"
sudo dscl . -create /Users/circleci UniqueID 550
sudo dscl . -create /Users/circleci PrimaryGroupID 20
sudo dscl . -create /Users/circleci NFSHomeDirectory /Users/circleci
sudo mkdir -p /Users/circleci
sudo chown circleci:staff /Users/circleci
# Or simply use your existing admin user (simpler setup)
Unduh dan Instal Agen Runner
# Create a directory for the runner
sudo mkdir -p /opt/circleci
# Download the latest CircleCI machine runner for macOS ARM64
# Check https://circleci.com/docs/runner-installation-mac/ for latest version
curl -o /tmp/circleci-runner.pkg \
https://circleci-binary-releases.s3.amazonaws.com/circleci-runner/1.0/circleci-runner_darwin_arm64.pkg
# Install the runner package
sudo installer -pkg /tmp/circleci-runner.pkg -target /
# Verify the installation
circleci-runner --version
Konfigurasikan Agen Runner
Buat file konfigurasi runner. Anda memerlukan token autentikasi runner dari dasbor CircleCI (dibahas di Langkah 3). Untuk saat ini, buat struktur file konfigurasinya:
# Create the configuration directory
sudo mkdir -p /opt/circleci/config
# Create the runner configuration file
sudo tee /opt/circleci/config/runner-agent-config.yaml << 'EOF'
api:
auth_token: YOUR_RUNNER_TOKEN_HERE
runner:
name: mac-mini-m4-runner
working_directory: /opt/circleci/workdir
cleanup_working_directory: true
max_run_time: 5h
# Optional: limit concurrent tasks
# command_prefix: ["nice", "-n", "10"]
logging:
file: /opt/circleci/logs/runner.log
EOF
# Create required directories
sudo mkdir -p /opt/circleci/workdir
sudo mkdir -p /opt/circleci/logs
# Set permissions (adjust user if using dedicated circleci user)
sudo chown -R admin:staff /opt/circleci
Buat Launch Agent macOS untuk Persistensi
Untuk memastikan runner mulai otomatis saat boot dan restart jika crash, buat LaunchDaemon macOS:
# Create the LaunchDaemon plist
sudo tee /Library/LaunchDaemons/com.circleci.runner.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.circleci.runner</string>
<key>ProgramArguments</key>
<array>
<string>/opt/circleci/circleci-runner</string>
<string>machine</string>
<string>--config</string>
<string>/opt/circleci/config/runner-agent-config.yaml</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/opt/circleci/logs/runner-stdout.log</string>
<key>StandardErrorPath</key>
<string>/opt/circleci/logs/runner-stderr.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
</dict>
</plist>
EOF
# Load and start the service
sudo launchctl load /Library/LaunchDaemons/com.circleci.runner.plist
# Verify the service is running
sudo launchctl list | grep circleci
# Expected: PID listed with com.circleci.runner
# Check the logs
tail -f /opt/circleci/logs/runner.log
Penting: Agen runner tidak akan terhubung sampai Anda menambahkan token autentikasi yang valid. Selesaikan Langkah 3 terlebih dahulu untuk menghasilkan token, lalu perbarui file runner-agent-config.yaml dengan token sebenarnya dan restart layanannya.
5. Langkah 3: Konfigurasikan Runner di Dasbor CircleCI
Sekarang Anda perlu mendaftarkan runner Anda di antarmuka web CircleCI dan menghasilkan token autentikasi. Ini menghubungkan Mac Mini Anda ke organisasi CircleCI Anda.
Buat Resource Class
Di CircleCI, self-hosted runner diorganisasikan berdasarkan resource class. Resource class adalah label yang memetakan .circleci/config.yml Anda ke sekumpulan runner tertentu.
- Buka Dasbor CircleCI → Organization Settings → Self-Hosted Runners
- Klik "Create Resource Class"
- Atur Namespace ke nama organisasi Anda (mis.,
your-org) - Atur nama Resource Class ke sesuatu yang deskriptif (mis.,
mac-runner) - Ini membuat identifier resource class:
your-org/mac-runner
Hasilkan Token Autentikasi Runner
- Setelah membuat resource class, klik "Create New Token"
- Beri token nama yang deskriptif (mis.,
mac-mini-m4-token) - Salin token yang dihasilkan segera — token hanya akan ditampilkan sekali
Perbarui Konfigurasi Runner dengan Token Anda
# SSH back into your Mac Mini
ssh admin@your-server-ip
# Update the runner configuration with your real token
sudo nano /opt/circleci/config/runner-agent-config.yaml
# Replace YOUR_RUNNER_TOKEN_HERE with the actual token:
# api:
# auth_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
# Restart the runner service to apply the new token
sudo launchctl unload /Library/LaunchDaemons/com.circleci.runner.plist
sudo launchctl load /Library/LaunchDaemons/com.circleci.runner.plist
# Verify the runner connects successfully
tail -20 /opt/circleci/logs/runner.log
# Look for: "Runner is ready to receive jobs"
Setelah terhubung, runner akan muncul sebagai "Online" di dasbor CircleCI pada bagian Self-Hosted Runners. Jika tidak muncul dalam 60 detik, periksa file log untuk pesan kesalahan.
Menggunakan CircleCI CLI (Alternatif)
Anda juga dapat mengelola runner melalui CircleCI CLI:
# Install the CircleCI CLI
brew install circleci
# Authenticate with CircleCI
circleci setup
# Create a resource class via CLI
circleci runner resource-class create your-org/mac-runner \
"Mac Mini M4 Runner" --generate-token
# List your runners
circleci runner instance list your-org/mac-runner
6. Langkah 4: Buat .circleci/config.yml Anda untuk Build iOS
Buat file .circleci/config.yml di root repositori Anda. Perbedaan utama dari konfigurasi CircleCI standar adalah penggunaan machine: true dengan resource_class kustom Anda untuk menargetkan self-hosted runner Anda.
version: 2.1
jobs:
build-and-test:
machine: true
resource_class: your-org/mac-runner
environment:
SCHEME: "MyApp"
DESTINATION: "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2"
DERIVED_DATA_PATH: "DerivedData"
SPM_CACHE_PATH: ".spm-cache"
steps:
- checkout
- run:
name: Select Xcode version
command: |
sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
xcodebuild -version
- run:
name: Resolve Swift Package Dependencies
command: |
xcodebuild -resolvePackageDependencies \
-scheme "$SCHEME" \
-clonedSourcePackagesDirPath "$SPM_CACHE_PATH"
- run:
name: Build the app
command: |
xcodebuild build \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-clonedSourcePackagesDirPath "$SPM_CACHE_PATH" \
-derivedDataPath "$DERIVED_DATA_PATH" \
| xcbeautify
- run:
name: Run unit tests
command: |
xcodebuild test \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-clonedSourcePackagesDirPath "$SPM_CACHE_PATH" \
-derivedDataPath "$DERIVED_DATA_PATH" \
-resultBundlePath TestResults.xcresult \
| xcbeautify
- store_test_results:
path: TestResults.xcresult
- store_artifacts:
path: TestResults.xcresult
destination: test-results
workflows:
ios-pipeline:
jobs:
- build-and-test:
filters:
branches:
only:
- main
- develop
Catatan: Nilai resource_class: your-org/mac-runner harus sama persis dengan resource class yang Anda buat di dasbor CircleCI. Jika tidak cocok, job akan tetap dalam antrean tanpa batas waktu.
7. Langkah 5: Optimalkan dengan Caching dan Paralelisme
Salah satu keunggulan terbesar dari self-hosted runner adalah caching persisten. Karena filesystem runner bersifat persisten, Anda tidak perlu mengunggah dan mengunduh cache seperti pada sumber daya cloud CircleCI. Namun, ada optimasi tambahan untuk memaksimalkan kecepatan build Anda.
Manfaatkan DerivedData Persisten
Karena disk runner bertahan di antara build, DerivedData sudah otomatis di-cache. Gunakan path yang konsisten:
# In your config.yml steps, always use a consistent DerivedData path:
- run:
name: Build with persistent cache
command: |
xcodebuild build \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-derivedDataPath ~/DerivedData/"$SCHEME" \
-clonedSourcePackagesDirPath ~/spm-cache \
| xcbeautify
# Periodically clean old DerivedData on the runner (cron job):
# 0 3 * * 0 find ~/DerivedData -maxdepth 1 -mtime +7 -exec rm -rf {} +
Persistensi Workspace di Antara Job
Gunakan workspace CircleCI untuk meneruskan artifact di antara job dalam workflow yang sama:
jobs:
build:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Build
command: |
xcodebuild build \
-scheme "MyApp" \
-destination "generic/platform=iOS" \
-derivedDataPath DerivedData
- persist_to_workspace:
root: .
paths:
- DerivedData
test:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Run tests
command: |
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-derivedDataPath DerivedData \
| xcbeautify
workflows:
build-test:
jobs:
- build
- test:
requires:
- build
Eksekusi Pengujian Paralel
- run:
name: Run tests in parallel
command: |
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
Test Splitting CircleCI
Untuk suite pengujian besar, gunakan test splitting bawaan CircleCI untuk mendistribusikan pengujian ke beberapa runner paralel:
jobs:
test:
machine: true
resource_class: your-org/mac-runner
parallelism: 3
steps:
- checkout
- run:
name: Split and run tests
command: |
# Generate test plan
TESTS=$(circleci tests glob "**/*Tests.swift" | \
circleci tests split --split-by=timings)
# Run only this container's portion of tests
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-only-testing:$TESTS \
| xcbeautify
8. Contoh Workflow
Berikut contoh workflow lengkap yang siap produksi untuk skenario CI/CD iOS yang umum.
Pipeline Build, Test, dan Deploy iOS Lengkap
version: 2.1
jobs:
lint:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Run SwiftLint
command: swiftlint lint --reporter json > swiftlint-results.json || true
- store_artifacts:
path: swiftlint-results.json
build-and-test:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Select Xcode
command: sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
- run:
name: Resolve dependencies
command: |
xcodebuild -resolvePackageDependencies \
-scheme "MyApp" \
-clonedSourcePackagesDirPath ~/spm-cache
- run:
name: Build and test
command: |
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-clonedSourcePackagesDirPath ~/spm-cache \
-derivedDataPath ~/DerivedData/MyApp \
-resultBundlePath TestResults.xcresult \
-parallel-testing-enabled YES \
| xcbeautify
- store_test_results:
path: TestResults.xcresult
- store_artifacts:
path: TestResults.xcresult
deploy-testflight:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Select Xcode
command: sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
- run:
name: Install certificates with Fastlane Match
command: |
fastlane match appstore --readonly
- run:
name: Build and upload to TestFlight
command: |
fastlane beta
environment:
FASTLANE_USER: ${APPLE_ID}
MATCH_PASSWORD: ${MATCH_PASSWORD}
workflows:
ios-pipeline:
jobs:
- lint
- build-and-test:
requires:
- lint
- deploy-testflight:
requires:
- build-and-test
filters:
branches:
only: main
Contoh Integrasi Fastlane
Jika Anda menggunakan Fastlane untuk otomatisasi build, berikut cara mengintegrasikannya dengan self-hosted runner CircleCI Anda:
# Fastfile (fastlane/Fastfile)
default_platform(:ios)
platform :ios do
desc "Run tests"
lane :test do
scan(
scheme: "MyApp",
device: "iPhone 16 Pro",
derived_data_path: "~/DerivedData/MyApp",
result_bundle: true,
output_directory: "./test_output"
)
end
desc "Build and push to TestFlight"
lane :beta do
match(type: "appstore", readonly: true)
increment_build_number(
build_number: ENV["CIRCLE_BUILD_NUM"]
)
gym(
scheme: "MyApp",
export_method: "app-store",
derived_data_path: "~/DerivedData/MyApp"
)
pilot(skip_waiting_for_build_processing: true)
end
end
# .circleci/config.yml using Fastlane
version: 2.1
jobs:
fastlane-test:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Install dependencies
command: bundle install
- run:
name: Run Fastlane tests
command: bundle exec fastlane test
- store_test_results:
path: ./test_output
- store_artifacts:
path: ./test_output
fastlane-deploy:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Install dependencies
command: bundle install
- run:
name: Deploy to TestFlight
command: bundle exec fastlane beta
workflows:
ios-workflow:
jobs:
- fastlane-test
- fastlane-deploy:
requires:
- fastlane-test
filters:
branches:
only: main
9. Perbandingan Performa
Berikut perbandingan performa dan biaya yang detail antara sumber daya macOS cloud CircleCI dan Mac Mini M4 self-hosted dari MyRemoteMac:
Benchmark Waktu Build
| Skenario | CircleCI Cloud macOS | Mac Mini M4 Self-Hosted | Peningkatan |
|---|---|---|---|
| Clean build (aplikasi menengah) | 14 mnt | 5 mnt | 2.8x lebih cepat |
| Build inkremental | 14 mnt (tanpa cache) | 1.5 mnt | 9.3x lebih cepat |
| Resolusi dependensi SPM | 3-5 mnt (unduh setiap kali) | 5 dtk (di-cache di disk) | ~60x lebih cepat |
| Suite unit test (500 pengujian) | 8 mnt | 2.5 mnt | 3.2x lebih cepat |
| Waktu tunggu antrean | 30 dtk - 5 mnt | 0 dtk | Instan |
Analisis Biaya Bulanan
| Ukuran Tim | Build/Bulan | Biaya CircleCI Cloud | Biaya MyRemoteMac | Penghematan Bulanan |
|---|---|---|---|---|
| Dev Solo | 100 build (rata-rata 10 mnt) | $100/bln | $85/bln | $25/bln |
| Tim Kecil (5) | 500 build (rata-rata 10 mnt) | $500/bln | $85/bln | $425/bln |
| Tim Menengah (15) | 1500 build (rata-rata 10 mnt) | $1,500/bln | $229/bln (M4 Pro) | $1,271/bln |
| Enterprise (50+) | 5000+ build | $5,000+/bln | $458/bln (2x M4 Pro) | $4,542+/bln |
Kesimpulan: Untuk tim mana pun yang menjalankan lebih dari ~75 build per bulan, Mac Mini M4 self-hosted langsung membayar dirinya sendiri. Penghematan biaya semakin bertambah karena build lebih cepat pada hardware dedikasi dengan cache yang sudah terisi, artinya setiap build mengonsumsi lebih sedikit menit sejak awal.
10. Pemecahan Masalah Umum
Runner terputus atau muncul sebagai "Offline"
Agen runner mungkin kehilangan koneksi karena masalah jaringan atau proses yang crash. LaunchDaemon seharusnya restart otomatis, tetapi jika tidak:
# Check if the process is running
ps aux | grep circleci-runner
# Check the LaunchDaemon status
sudo launchctl list | grep circleci
# View the error logs
tail -50 /opt/circleci/logs/runner-stderr.log
tail -50 /opt/circleci/logs/runner.log
# Restart the service
sudo launchctl unload /Library/LaunchDaemons/com.circleci.runner.plist
sudo launchctl load /Library/LaunchDaemons/com.circleci.runner.plist
# If the token expired, generate a new one in CircleCI dashboard
# and update /opt/circleci/config/runner-agent-config.yaml
resource_class tidak ditemukan atau job macet dalam antrean
Jika job tetap dalam antrean dengan "No matching runner found", resource class di konfigurasi Anda tidak cocok dengan dasbor:
# Verify the exact resource class name in CircleCI dashboard:
# Organization Settings > Self-Hosted Runners > Resource Classes
# The resource_class in .circleci/config.yml must match exactly:
# resource_class: your-org/mac-runner (case-sensitive!)
# Check your runner is online:
circleci runner instance list your-org/mac-runner
# Common mistakes:
# - Wrong namespace (org name vs personal namespace)
# - Typo in resource class name
# - Runner is offline or token is invalid
# - Using 'docker' executor instead of 'machine: true'
Kesalahan code signing Xcode
Code signing di mesin CI memerlukan pengelolaan keychain yang cermat. Proses runner mungkin tidak memiliki akses ke login keychain:
# Option 1: Use Fastlane Match (recommended)
# In your Fastfile:
match(type: "appstore", readonly: true)
# Option 2: Manual keychain management in your job steps
- run:
name: Setup code signing
command: |
# Decode and import the certificate
echo "$BUILD_CERTIFICATE_BASE64" | base64 --decode > /tmp/cert.p12
# Create a temporary keychain
security create-keychain -p "ci" /tmp/ci.keychain
security set-keychain-settings -lut 21600 /tmp/ci.keychain
security unlock-keychain -p "ci" /tmp/ci.keychain
# Import the certificate
security import /tmp/cert.p12 -P "$P12_PASSWORD" \
-A -t cert -f pkcs12 -k /tmp/ci.keychain
security list-keychain -d user -s /tmp/ci.keychain
# Install provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
echo "$PROVISIONING_PROFILE_BASE64" | base64 --decode \
> ~/Library/MobileDevice/Provisioning\ Profiles/profile.mobileprovision
Simulator gagal boot atau time out
Simulator dapat mengalami kondisi buruk pada mesin CI yang berjalan lama. Reset di antara build:
# Add a pre-build step to clean simulators
- run:
name: Reset simulators
command: |
xcrun simctl shutdown all 2>/dev/null || true
xcrun simctl erase all 2>/dev/null || true
# If a specific runtime is missing, reinstall it:
xcodebuild -downloadPlatform iOS
# List available simulators
xcrun simctl list devices available
Ruang disk menipis
Build Xcode menghasilkan data dalam jumlah besar. Siapkan pembersihan otomatis pada runner Anda:
# Check available disk space
df -h /
# 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 CircleCI working directories
find /opt/circleci/workdir -maxdepth 1 -mtime +3 -exec rm -rf {} +
# Set up a weekly cron job for automatic cleanup
(crontab -l 2>/dev/null; echo "0 4 * * 0 rm -rf ~/Library/Developer/Xcode/DerivedData/* && brew cleanup --prune=7") | crontab -
11. Pertanyaan yang Sering Diajukan
Berapa biaya CircleCI self-hosted runner di Mac Mini M4?
Mac Mini M4 dedikasi dari MyRemoteMac mulai dari $85/bulan dengan menit build tanpa batas. Ini jauh lebih murah dibanding runner macOS cloud CircleCI yang berbiaya sekitar $0.06-$0.12 per menit (kira-kira $300-500/bulan untuk tim aktif). Self-hosted runner tidak memiliki biaya per menit, sehingga biaya Anda dapat diprediksi terlepas dari volume build.
Bisakah saya menggunakan CircleCI self-hosted runner untuk build iOS dan macOS?
Ya. Self-hosted runner di Mac Mini M4 dapat menjalankan beban kerja macOS apa pun, termasuk build iOS, build aplikasi macOS, pengujian paket Swift, pengujian UI Xcode, dan otomatisasi Fastlane. Karena berjalan secara native di Apple Silicon, build lebih cepat dibanding runner cloud berbasis emulasi atau Intel.
Apa perbedaan antara machine runner dan container runner CircleCI?
Machine runner CircleCI menjalankan job langsung di sistem operasi mesin host, yang diperlukan untuk build macOS/iOS yang membutuhkan Xcode, simulator, dan framework Apple. Container runner menjalankan job di dalam kontainer Docker dan hanya tersedia di Linux. Untuk build Mac, Anda harus menggunakan machine runner.
Bagaimana cara menjaga CircleCI self-hosted runner saya tetap diperbarui?
Agen machine runner CircleCI mendukung pembaruan otomatis secara default. Anda juga dapat memperbarui secara manual dengan mengunduh rilis terbaru dari CircleCI dan mengganti binernya. Disarankan untuk memeriksa pembaruan setiap bulan dan menjaga Xcode serta macOS tetap diperbarui.
Apakah self-hosted runner lebih cepat dibanding macOS cloud CircleCI?
Ya, biasanya 2-3x lebih cepat untuk clean build dan hingga 9x lebih cepat untuk build inkremental. Runner macOS cloud CircleCI menggunakan hardware Intel atau M1 bersama dengan lingkungan ephemeral, artinya setiap build dimulai dengan cache dingin. Mac Mini M4 self-hosted memiliki performa Apple Silicon dedikasi, cache DerivedData dan SPM persisten, serta tanpa waktu tunggu antrean.
Bisakah saya menjalankan beberapa job CircleCI secara bersamaan di satu Mac Mini?
Ya. Mac Mini M4 memiliki CPU 10-core dan RAM 16GB atau lebih, yang dapat dengan nyaman menangani 2-3 job build bersamaan. Untuk beban kerja lebih berat, Mac Mini M4 Pro dengan 14 core dan RAM 24GB dapat menangani 4-6 job bersamaan. Anda dapat mengonfigurasi jumlah tugas bersamaan maksimum runner di file konfigurasi runner.