1. Pourquoi utiliser un runner CircleCI auto-hébergé sur Mac ?
CircleCI propose des environnements d'exécution macOS dans le cloud, mais ils sont accompagnés de coûts et de limitations significatifs. Les ressources macOS sur CircleCI utilisent un système basé sur les crédits où chaque minute sur un exécuteur macOS consomme 50 à 100 crédits selon la classe de ressource. Pour les équipes effectuant des builds iOS fréquents, cela peut rapidement atteindre 300 à 500 $ par mois ou plus.
Un runner auto-hébergé sur un Mac Mini M4 dédié de MyRemoteMac élimine entièrement la facturation à la minute. Vous obtenez une machine Apple Silicon dédiée avec un stockage persistant, des caches préchauffés et un accès root complet pour un tarif mensuel fixe à partir de 75 $/mois. Voici une comparaison détaillée :
| Caractéristique | CircleCI Cloud macOS | My Remote Mac auto-hébergé |
|---|---|---|
| Modèle tarifaire | 50-100 crédits/min (~0,06-0,12 $/min) | 75 $/mois forfaitaire (minutes illimitées) |
| Architecture | Intel x86 ou M1 (partagé) | Apple M4 (dédié, dernière génération) |
| Vitesse de build | ~14 min (projet iOS moyen) | ~5 min (même projet) |
| Persistance du cache | Éphémère (à restaurer à chaque job) | Persistant sur disque (instantané) |
| Temps d'attente en file | 30 s - 5 min (variable selon l'offre) | 0 s (matériel dédié) |
| Confidentialité / Contrôle des données | Infrastructure partagée | Machine dédiée, contrôle total |
| Logiciels personnalisés | Image pré-installée uniquement | Accès root complet, tout logiciel |
Avantage clé : Avec un runner auto-hébergé persistant, DerivedData, les caches Swift Package Manager et CocoaPods sont préservés entre les builds. Cela seul peut réduire les temps de build de 50 à 70 % par rapport aux environnements macOS cloud éphémères de CircleCI qui repartent de zéro à chaque fois. Combiné aux performances supérieures du M4 en mono-thread, vos builds iOS seront considérablement plus rapides.
2. Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
- Un serveur Mac Mini M4 chez My Remote Mac (à partir de 75 $/mois)
- Un compte CircleCI avec une offre Performance, Scale ou Server (les runners auto-hébergés nécessitent une offre payante)
- Un accès SSH à votre Mac Mini (fourni avec votre abonnement My Remote Mac)
- Un compte Apple Developer (pour la signature de code et les profils de provisionnement)
- Une connaissance de base de YAML, de la configuration CircleCI et des commandes terminal
3. Étape 1 : Se connecter en SSH à votre Mac Mini et installer les dépendances
Commencez par vous connecter à votre Mac Mini M4 via SSH. Vous aurez reçu vos identifiants lors de la mise en place de votre serveur My Remote Mac. Nous devons installer Xcode et les outils nécessaires aux builds iOS avant de configurer le runner CircleCI.
Connexion via 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
Installer Homebrew et les outils en ligne de commande Xcode
# 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
Installer Xcode (version complète)
Pour les builds iOS, vous avez besoin de l'application Xcode complète. Le moyen le plus rapide de l'installer sur un serveur sans écran est d'utiliser 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
Installer les simulateurs iOS et les outils de build
# 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. Étape 2 : Installer l'agent runner CircleCI
CircleCI utilise un agent machine runner pour connecter votre Mac Mini à la plateforme CircleCI. Le machine runner reçoit les jobs de CircleCI et les exécute directement sur votre hôte macOS. C'est différent du container runner (qui ne fonctionne que sous Linux).
Créer un utilisateur dédié pour le runner
Il est recommandé de créer un utilisateur dédié pour exécuter l'agent CircleCI afin d'assurer l'isolation de sécurité :
# 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)
Télécharger et installer l'agent 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
Configurer l'agent runner
Créez le fichier de configuration du runner. Vous aurez besoin de votre jeton d'authentification du runner depuis le tableau de bord CircleCI (traité à l'étape 3). Pour l'instant, créez la structure du fichier de configuration :
# 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
Créer un Launch Agent macOS pour la persistance
Pour vous assurer que le runner démarre automatiquement au démarrage et redémarre en cas de plantage, créez un 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
Important : L'agent runner ne se connectera pas tant que vous n'aurez pas ajouté un jeton d'authentification valide. Complétez d'abord l'étape 3 pour générer le jeton, puis mettez à jour le fichier runner-agent-config.yaml avec le vrai jeton et redémarrez le service.
5. Étape 3 : Configurer le runner dans le tableau de bord CircleCI
Vous devez maintenant enregistrer votre runner dans l'interface web CircleCI et générer un jeton d'authentification. Cela connecte votre Mac Mini à votre organisation CircleCI.
Créer une classe de ressource
Dans CircleCI, les runners auto-hébergés sont organisés par classes de ressources. Une classe de ressource est un label qui associe votre .circleci/config.yml à un ensemble spécifique de runners.
- Allez dans Tableau de bord CircleCI → Paramètres de l'organisation → Runners auto-hébergés
- Cliquez sur "Créer une classe de ressource"
- Définissez le Namespace avec le nom de votre organisation (ex. :
your-org) - Définissez le nom de la classe de ressource avec un nom descriptif (ex. :
mac-runner) - Cela crée un identifiant de classe de ressource :
your-org/mac-runner
Générer un jeton d'authentification du runner
- Après avoir créé la classe de ressource, cliquez sur "Créer un nouveau jeton"
- Donnez au jeton un nom descriptif (ex. :
mac-mini-m4-token) - Copiez immédiatement le jeton généré — il ne sera affiché qu'une seule fois
Mettre à jour la configuration du runner avec votre jeton
# 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"
Une fois connecté, le runner devrait apparaître comme "En ligne" dans le tableau de bord CircleCI sous Runners auto-hébergés. S'il n'apparaît pas dans les 60 secondes, vérifiez le fichier journal pour les messages d'erreur.
Utiliser le CLI CircleCI (alternative)
Vous pouvez également gérer les runners via le CLI CircleCI :
# 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. Étape 4 : Créer votre .circleci/config.yml pour les builds iOS
Créez un fichier .circleci/config.yml à la racine de votre dépôt. La différence clé avec une configuration CircleCI standard est l'utilisation de machine: true avec votre resource_class personnalisée pour cibler votre runner auto-hébergé.
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
Remarque : La valeur resource_class: your-org/mac-runner doit correspondre exactement à la classe de ressource que vous avez créée dans le tableau de bord CircleCI. Si elle ne correspond pas, les jobs resteront en file d'attente indéfiniment.
7. Étape 5 : Optimiser avec le cache et le parallélisme
L'un des plus grands avantages d'un runner auto-hébergé est le cache persistant. Comme le système de fichiers du runner est persistant, vous n'avez pas besoin de télécharger et restaurer les caches comme avec les ressources cloud CircleCI. Cependant, il existe des optimisations supplémentaires pour maximiser la vitesse de vos builds.
Exploiter le DerivedData persistant
Puisque le disque du runner persiste entre les builds, DerivedData est déjà mis en cache automatiquement. Utilisez un chemin cohérent :
# 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 {} +
Persistance de l'espace de travail entre les jobs
Utilisez les espaces de travail CircleCI pour transmettre des artefacts entre les jobs d'un même workflow :
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
Exécution parallèle des tests
- 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
Répartition des tests CircleCI
Pour les suites de tests volumineuses, utilisez la répartition de tests intégrée de CircleCI pour distribuer les tests sur des runners parallèles :
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. Exemples de workflows
Voici des exemples de workflows complets, prêts pour la production, pour les scénarios CI/CD iOS courants.
Pipeline complet de build, test et déploiement iOS
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
Exemple d'intégration Fastlane
Si vous utilisez Fastlane pour votre automatisation de build, voici comment l'intégrer avec votre runner CircleCI auto-hébergé :
# 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. Comparaison des performances
Voici une comparaison détaillée des performances et des coûts entre les ressources macOS cloud de CircleCI et un Mac Mini M4 auto-hébergé de My Remote Mac :
Benchmarks des temps de build
| Scénario | CircleCI Cloud macOS | Mac Mini M4 auto-hébergé | Amélioration |
|---|---|---|---|
| Build propre (app moyenne) | 14 min | 5 min | 2,8x plus rapide |
| Build incrémental | 14 min (pas de cache) | 1,5 min | 9,3x plus rapide |
| Résolution des dépendances SPM | 3-5 min (téléchargement à chaque fois) | 5 sec (cache sur disque) | ~60x plus rapide |
| Suite de tests unitaires (500 tests) | 8 min | 2,5 min | 3,2x plus rapide |
| Temps d'attente en file | 30 s - 5 min | 0 sec | Instantané |
Analyse des coûts mensuels
| Taille de l'équipe | Builds/mois | Coût CircleCI Cloud | Coût My Remote Mac | Économies mensuelles |
|---|---|---|---|---|
| Développeur solo | 100 builds (10 min moy.) | 100 $/mois | 75 $/mois | 25 $/mois |
| Petite équipe (5) | 500 builds (10 min moy.) | 500 $/mois | 75 $/mois | 425 $/mois |
| Équipe moyenne (15) | 1500 builds (10 min moy.) | 1 500 $/mois | 179 $/mois (M4 Pro) | 1 321 $/mois |
| Entreprise (50+) | 5000+ builds | 5 000+ $/mois | 358 $/mois (2x M4 Pro) | 4 642+ $/mois |
En résumé : Pour toute équipe effectuant plus de ~75 builds par mois, un Mac Mini M4 auto-hébergé est immédiatement rentable. Les économies se cumulent davantage car les builds sont plus rapides sur du matériel dédié avec des caches préchauffés, ce qui signifie que chaque build consomme moins de minutes en premier lieu.
10. Résolution des problèmes courants
Le runner se déconnecte ou apparaît "Hors ligne"
L'agent runner peut perdre la connexion en raison de problèmes réseau ou d'un processus planté. Le LaunchDaemon devrait redémarrer automatiquement, mais si ce n'est pas le cas :
# 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 introuvable ou jobs bloqués en file d'attente
Si les jobs restent en file d'attente avec "Aucun runner correspondant trouvé", la classe de ressource dans votre configuration ne correspond pas au tableau de bord :
# 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'
Erreurs de signature de code Xcode
La signature de code sur une machine CI nécessite une gestion soigneuse du trousseau. Le processus runner peut ne pas avoir accès au trousseau de session :
# 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
Le simulateur ne démarre pas ou expire
Les simulateurs peuvent se retrouver dans un état incorrect sur les machines CI à longue durée de fonctionnement. Réinitialisez-les entre les builds :
# 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
Espace disque insuffisant
Les builds Xcode génèrent des quantités importantes de données. Configurez un nettoyage automatique sur votre runner :
# 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. Questions fréquentes
Combien coûte un runner CircleCI auto-hébergé sur Mac Mini M4 ?
Un Mac Mini M4 dédié chez My Remote Mac commence à 75 $/mois avec des minutes de build illimitées. C'est nettement moins cher que les runners macOS cloud de CircleCI qui coûtent environ 0,06 à 0,12 $ par minute (environ 300 à 500 $/mois pour les équipes actives). Les runners auto-hébergés n'ont aucun frais à la minute, donc vos coûts sont prévisibles quel que soit le volume de builds.
Puis-je utiliser un runner CircleCI auto-hébergé pour les builds iOS et macOS ?
Oui. Un runner auto-hébergé sur un Mac Mini M4 peut exécuter n'importe quelle charge de travail macOS, y compris les builds iOS, les builds d'applications macOS, les tests de paquets Swift, les tests UI Xcode et l'automatisation Fastlane. Comme il s'exécute nativement sur Apple Silicon, les builds sont plus rapides que sur des runners cloud émulés ou basés sur Intel.
Quelle est la différence entre le machine runner et le container runner de CircleCI ?
Le machine runner de CircleCI exécute les jobs directement sur le système d'exploitation de la machine hôte, ce qui est nécessaire pour les builds macOS/iOS qui ont besoin de Xcode, des simulateurs et des frameworks Apple. Le container runner exécute les jobs dans des conteneurs Docker et n'est disponible que sur Linux. Pour les builds Mac, vous devez utiliser le machine runner.
Comment maintenir mon runner CircleCI auto-hébergé à jour ?
L'agent machine runner CircleCI prend en charge les mises à jour automatiques par défaut. Vous pouvez également mettre à jour manuellement en téléchargeant la dernière version depuis CircleCI et en remplaçant le binaire. Il est recommandé de vérifier les mises à jour mensuellement et de maintenir Xcode et macOS à jour également.
Un runner auto-hébergé est-il plus rapide que les runners macOS cloud de CircleCI ?
Oui, généralement 2 à 3 fois plus rapide pour les builds propres et jusqu'à 9 fois plus rapide pour les builds incrémentaux. Les runners macOS cloud de CircleCI utilisent du matériel Intel ou M1 partagé avec des environnements éphémères, ce qui signifie que chaque build démarre avec un cache vide. Un Mac Mini M4 auto-hébergé offre des performances Apple Silicon dédiées, des caches DerivedData et SPM persistants, et aucun temps d'attente en file d'attente.
Puis-je exécuter plusieurs jobs CircleCI simultanément sur un seul Mac Mini ?
Oui. Le Mac Mini M4 dispose d'un CPU 10 cœurs et de 16 Go de RAM ou plus, ce qui permet de gérer confortablement 2 à 3 jobs de build simultanés. Pour des charges de travail plus lourdes, le Mac Mini M4 Pro avec 14 cœurs et 24 Go de RAM peut gérer 4 à 6 jobs simultanés. Vous pouvez configurer le nombre maximum de tâches simultanées du runner dans le fichier de configuration du runner.