CI/CD
Run each CI job in a fresh copy of a prepared VM, then throw the copy away.
Prepare a VM once
vmpal create download:ubuntu --name "CI Ubuntu" --wait
vmpal exec "CI Ubuntu" --admin -- apt-get update
vmpal exec "CI Ubuntu" --admin -- apt-get install -y build-essential git
vmpal stop "CI Ubuntu"
Keep it shut down. To change it later, start it, change it, and stop it again.
Run a job
vmpal run "CI Ubuntu" --copy-in .:src --copy-out src/out:./out -- /bin/sh -lc 'cd src && make test'
run copies the VM, starts the copy, copies your files in, runs the command, copies the results out, and deletes the copy, also when the job fails or is cancelled. It exits with the command's status, so the job passes or fails with it.
GitHub Actions
On a self-hosted runner on the Mac:
jobs:
test:
runs-on: [self-hosted, macOS, ARM64]
steps:
- uses: actions/checkout@v7
- run: vmpal run "CI Ubuntu" --copy-in .:src --copy-out src/out:./out -- /bin/sh -lc 'cd src && make test'
GitLab CI works the same: a shell runner on the Mac, and the same vmpal run line in the job's script.
Good to know
- Run the CI runner as the user logged in at the Mac, and keep the Mac from sleeping.
- Windows starts at its sign-in screen.
runsigns in with the password VMPal keeps for the VM. If that password stops working, update it in the VM's Settings › General › Account › Update Password…. Windows commands needcmd.exeorpowershell.exe. - macOS allows two macOS VMs at a time on one Mac, so run at most two macOS jobs at once.
vmpal help ci has more, or ask your AI agent.