How it works

What Codemany does on your Mac while jobs run, and what it does when something goes wrong.

What actually happens on your Mac

  • One runner per job. For each runner, Codemany asks GitHub for a just-in-time registration. The runner takes exactly one job and exits. Its directory is wiped and re-cloned from a clean copy of GitHub's runner (an instant APFS clone of a checksummed download), then a new runner registers. One credential mints runners forever: no registration tokens to juggle.
  • Sized to your Mac. By default each runner budgets 4 GB of memory, 15 GB of disk and 2 performance cores, and 4 GB of memory plus 20 GB of disk stay reserved for macOS. That is 1 runner on an 8 GB Mac and 3 on a 16 GB one, never fewer than 1 or more than 32.
  • Several repos share the runners. Each repo keeps a warm runner while there are runners to spare, and idle runners move to the repo whose jobs are waiting. Busy runners are never touched.
  • It runs in the background. Jobs run in Codemany's background service, which keeps running when the app is closed, quits or updates. A headless Mac mini whose app is not running keeps working.
  • It keeps your Mac awake while jobs run (or while runners are online, or never: your choice), and lets it sleep again 2 minutes after the last job.
  • Jobs use your tools. Jobs get what is installed on your Mac: Xcode, Homebrew packages, Docker and so on. Codemany checks each tool every 30 minutes, adds an xcode-… label for the selected Xcode and a docker label while Docker is running, and caches actions/setup-* downloads between jobs.

When things go wrong

  • The Mac sleeps or the lid closes. Codemany holds macOS's keep-awake assertion while jobs run. It cannot stop a laptop on battery from sleeping when the lid closes without an external display, Low Power Mode, or someone choosing Sleep, so it warns about those ("On battery: closing the lid stops jobs"). After a sleep it records which jobs were lost and says so once.
  • All runners are busy. New jobs wait on GitHub. Codemany lists them oldest first and highlights waits over 15 minutes. GitHub, not Codemany, picks which waiting job a free runner takes.
  • A runner crashes. Its registration is deleted and it backs off (5 seconds, growing to 5 minutes), then a fresh one starts. A dead runner is a counter on the dashboard, not an incident.
  • A runner goes offline. When GitHub reports an idle runner offline for longer than a grace period (2 minutes by default), Codemany kills it, along with any leftover child processes such as simulators, and starts a fresh one.
  • The disk runs low. Free disk is checked before every runner starts. Below the reserve plus one runner's share, the runner waits with a "low disk space" error instead of starting a job that could fill the disk.
  • Docker or Xcode changes. Labels are fixed when a runner registers, so the next runners pick up the change: the docker label appears while Docker answers and goes away when it stops. With "Keep Docker running" on, Codemany restarts Docker when it stops.
  • An update arrives while jobs run. Installing the update never stops a running job. The background service restarts onto the new version only after running jobs finish.
  • GitHub rate-limits or denies access. Polling pauses until the limit lifts. If the token is revoked, running jobs keep running and new runners retry every 5 minutes; reconnect GitHub and the next retry picks up the new token.
  • The network drops. Errors are recorded and shown, and Codemany keeps retrying. Errors from GitHub never stop a running job. The license keeps working for 7 days offline.
  • The trial or subscription ends. New runners stop with "Codemany Pro license required". Jobs already running are never stopped.
  • A repo turns public. Codemany re-checks every repo every 30 minutes. A public repo is refused unless you opted in for it (see the security model).