Ansible-first automation for provisioning macOS CI agents, with Tart VM support for local iteration.
This repository provisions macOS hosts (VMs or physical machines) using Ansible roles and playbooks.
The current active stack is:
- Root-level Ansible project (
ansible.cfg,inventory/,playbooks/,roles/) - Dynamic Tart inventory (
inventory/tart_inventory.py) for VM IP discovery at runtime - Role-scoped reference scripts in
scripts/used as implementation references and helpers - Toolchain and workflow orchestration via
mise
.
├── ansible.cfg
├── requirements.yml
├── inventory/
│ ├── tart_inventory.py
│ └── group_vars/
│ ├── macos_agents.yml
│ ├── macos_15_agents.yml
│ ├── macos_26_agents.yml
│ ├── tart_agents.yml
│ └── orka_agents.yml
├── playbooks/
│ └── provision.yml
├── roles/
│ ├── xcode_clt/
│ ├── macos_updates/
│ ├── rosetta/
│ ├── ssh_config/
│ ├── system_config/
│ ├── auth_config/
│ ├── homebrew/
│ └── xcode/
├── scripts/
│ ├── xcode/
│ ├── xcode_clt/
│ ├── homebrew/
│ ├── system_config/
│ ├── auth_config/
│ ├── ssh_config/
│ ├── rosetta/
│ └── macos_updates/
├── mise.toml
└── pyproject.toml
- macOS host for Tart-based workflows
- mise
- Tart VMs prepared locally (if using dynamic Tart inventory)
- Pre-staged Xcode
.xipand Simulator Runtime.dmgassets for the target OS version(s)
Run commands from the repository root.
-
Install toolchain from
mise.toml:mise install
-
Bootstrap Python/Ansible dependencies and Galaxy content:
mise run bootstrap
This installs:
- Python dependencies from
pyproject.toml(ansible-core,ansible-lint,paramiko) - Roles and collections from
requirements.yml
- Python dependencies from
ansible.cfg points to inventory/tart_inventory.py as the default inventory.
inventory/tart_inventory.pydiscovers VM IPs viatart ip <vm_name>- Hosts are grouped into:
macos_agents(parent)tart_agents(runtime Tart VM group)- version-specific groups like
macos_15_agentsandmacos_26_agents
Primary variable files:
inventory/group_vars/macos_agents.yml: shared settings (admin credentials, Homebrew base packages, Dock config)inventory/group_vars/tart_agents.yml: Tart-specific packages (tart-guest-agent)inventory/group_vars/macos_15_agents.ymlandinventory/group_vars/macos_26_agents.yml: Xcode/runtime/simulator presets
The xcode role expects cached installers on the control node:
.cache/xcode/*.xip.cache/simruntime/*.dmg
Group vars must reference exact filenames in these cache directories.
If cache files are missing, install tasks for those assets are skipped.
Run a preflight cache check explicitly:
mise run verify-xcode-cacheThis runs the local Ansible playbook playbooks/preflight-xcode-cache.yml.
Run the full playbook:
ansible-playbook playbooks/provision.ymlOr run common role slices with tags:
ansible-playbook playbooks/provision.yml --tags xcode
ansible-playbook playbooks/provision.yml --tags homebrew
ansible-playbook playbooks/provision.yml --tags system_configPlaybook role order in playbooks/provision.yml is intentional:
xcode_cltmacos_updatesrosettassh_configsystem_configauth_confighomebrewgeerlingguy.mac.dockxcode- Spotlight re-index task
- Reboot task
mise includes helper tasks for local Tart loops:
mise run run-tart-vms: starts configured VMs and waits for SSH readinessmise run provision: verifies Xcode/simruntime cache inputs, starts VMs, then runsansible-playbook playbooks/provision.ymlmise run shutdown-tart-vms: shuts down hosts intart_agentsmise run refresh-tart-vms: recreates local Tart VM clones from frozen images
Adjust VM names in:
inventory/tart_inventory.py(VMSlist)mise.toml(tasks.run-tart-vmsandtasks.refresh-tart-vms)
This repo uses hk and mise task aliases:
mise run chk # lint/check
mise run fmt # auto-fix formatting and supported lint issueschk includes ansible-lint, shellcheck, shfmt, ruff, yamlfmt, and additional utility checks defined in hk.pkl.
Xcode utility script tests can be run directly on macOS:
bash scripts/xcode/tests/test_xcode-utils.bash- https://github.com/timsutton/osx-vm-templates
- https://github.com/boxcutter/macos
- https://github.com/cirruslabs/macos-image-templates
- https://github.com/actions/runner-images
- https://github.com/torarnv/tart-image-bakery
- https://gist.github.com/aessam/aa9c32af6900123277c36d4d0ac7f73d#9d-skip-setup-assistant--6-layers