Self-hosted service
traderepublic/Cilicon avatar
traderepublic/Cilicon

Cilicon: ephemeral macOS CI VMs on Apple Silicon

🛠️ Self-Hosted ephemeral macOS CI on Apple Silicon

1,193 stars44 forksSwiftMIT

At a glance

What is it?
Cilicon is a macOS app that uses Apple's Virtualization Framework to spin up disposable macOS VMs for self-hosted CI runners. It is built for teams that need Xcode builds without renting cloud Macs, and it comes with real constraints around image sources and host macOS versions.
Who is it for?
Cilicon fits teams that already own Apple Silicon hardware, need Xcode in CI, and are willing to manage a cilicon.yml file plus a GitHub App or runner token. It is the wrong tool if you need Intel macOS builds, if you cannot keep the host on macOS 15.4 or later, or if you expect the project to manage image lifecycle for you.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Cilicon addresses for Apple Silicon CI

Hosting a macOS CI runner usually means keeping a Mac mini or Mac Studio online, installing Xcode, and hoping that one job does not leave state behind for the next one. Cilicon targets that second problem directly. The README describes it as a macOS app that leverages Apple's Virtualization Framework to create, provision and run ephemeral CI VMs with near-native performance. Ephemeral is the operative word: each job starts from a known image rather than from whatever the previous job left on disk.

The audience is narrow and specific. You need Apple Silicon hardware, because the app is built on the Virtualization Framework and the repository topics list m1, m2 and silicon. You need a CI system that can talk to a self-hosted runner: the README names GitHub Actions, Buildkite Agent, GitLab Runner and arbitrary scripts. And you need Xcode builds, since the recommended images are Xcode images. If your CI is Linux-only, nothing here applies to you.

How the Cilicon cycle actually works

Cilicon does not run jobs itself. It prepares a VM and hands it to a runner process. According to the README, the app follows a simple cycle, illustrated by a diagram in the repository. The app downloads an image from an OCI registry, boots a VM from it, waits for SSH to become available, starts the configured provisioner inside the guest, and then tears the VM down when the job finishes.

The 2.0 release notes describe a meaningful shift in how that provisioning happens. Cilicon 1.0 relied on a user-defined Login Item script inside the VM. Version 2.0 includes an SSH client and executes commands on the VM directly. That removes a moving part from the guest image, but it also means the guest must have SSH enabled and credentials set, which the migration notes call out explicitly: when converting a 1.0 image you must enable SSH and set the credentials in the config, or use the default admin:admin.

Image handling is the other half of the mechanism. Cilicon uses the tart container format and ships an integrated OCI client. The release notes say Cilicon has partially adopted the tart image format and can automatically convert 1.0 images to it. Downloaded images land in ~/.tart, and the README warns that this folder should be cleared of unused images periodically. That is a manual garbage collection step, not an automatic one.

Installing Cilicon and running a first GitHub Actions job

Cilicon is distributed as a macOS app, not through a package manager. The README says to download the latest release from the GitHub releases page. There is no Homebrew formula or install script documented, so the release download is the documented path.

Configuration lives in a single file. Cilicon expects a cilicon.yml file in the host OS's home directory. For GitHub Actions you first create and install a GitHub App with Self-hosted runners Read & Write permissions at the organization level, then download the private key file and point the config at it. The README gives this example:

yaml
source: oci://ghcr.io/cirruslabs/macos-runner:sequoia
provisioner:
  type: github
  config:
    appId: <APP_ID>
    organization: <ORGANIZATION_SLUG>
    privateKeyPath: ~/github.pem

The source line is the part people get wrong. When choosing an OCI hosted image you must prepend the oci:// scheme to the URL, because Cilicon otherwise assumes a local filesystem path. After starting the app, the README's sample job video shows a GitHub Actions job running through the VM.

If you prefer GitLab, the minimal provisioner config is shorter. You create a runner with an authentication token and set two values:

yaml
source: oci://ghcr.io/cirruslabs/macos-runner:sequoia
provisioner:
  type: gitlab
  config:
    gitlabURL: <GITLAB_INSTANCE_URL>
    runnerToken: <RUNNER_TOKEN>

For anything else, the script provisioner runs a shell fragment in the guest, which is how you would start a runner type Cilicon does not support natively. The README's example prints a greeting and sleeps. Note that the script block is the only place in the documented configuration where you supply your own commands.

Where Cilicon's design puts work back on you

The most concrete limitation is stated as a warning at the top of the README: there seems to be an issue with swift-nio based SSH on macOS 15.0 through 15.3.X, and macOS 15.4 or later is recommended for a more reliable experience. That is a hard floor on the host OS version. If your fleet is pinned to an earlier 15.x release, the SSH path that Cilicon 2.0 depends on is the part with known trouble.

Image lifecycle is the second gap. The README tells you not to use the latest tag, and to pick the specific version of Xcode you want instead. It also notes that images with newer versions of macOS may be published with the same Xcode version installed, so upgrading may require manually deleting the outdated image and starting Cilicon again. Combined with the advice to clear ~/.tart periodically, this means image housekeeping is your responsibility. Nothing in the documented configuration automates pruning.

There is also a migration cliff for existing users. The config schema changed between 1.0 and 2.0, and in most cases renaming vmBundlePath to source is said to be enough. If you converted images from 1.0, you must enable SSH and set credentials, or fall back to admin:admin. That default credential pair is convenient for a first run and a poor idea for anything reachable beyond the host.

Cilicon compared with a plain self-hosted runner

The obvious alternative is installing the GitHub Actions runner or GitLab Runner directly on the Mac and skipping virtualization entirely. That approach has fewer moving parts and no image downloads, and it works on any macOS version the runner supports. The trade-off is state: the runner shares the host filesystem, caches and Xcode installation with every job, so a job that modifies the environment can affect the next one. Cilicon's answer is a fresh VM per job, at the cost of pulling and booting an image and of maintaining the images themselves.

A second alternative is the tart tool from Cirrus Labs, which Cilicon's format is based on and which the README recommends for creating or customizing your own images. Tart is a virtual machine tool you drive yourself; Cilicon wraps a subset of that workflow with a provisioner loop and a config file. If you want full control over VM lifecycle, scripted with your own tooling, tart is the lower-level choice. If you want the runner registration handled for you, Cilicon is the layer that does it. The two are not mutually exclusive: the README points at tart for custom images and at Cirrus Labs' published macos-sonoma-xcode image for the prebuilt path.

Maintenance, licensing and what to check before committing

The repository is not archived, and the last push was on 2026-09-14, which is recent. Releases are more spaced out: v2.4.2 landed on 2025-12-12, with v2.4.0 and v2.4.1 two days earlier. The 2.x line has been stable for a while, and the README's own Ideas for the Future section signals that the project still has a roadmap, though the README does not document rollback or downgrade procedures for the app itself.

Licensing is MIT, per the repository's LICENSE.md. That is permissive: you can use, modify and redistribute the app, including in commercial settings, provided the licence text and copyright notice are preserved. It says nothing about the images you pull. The README recommends publicly hosted images from Cirrus Labs and the macos-sonoma-xcode container package; those images carry their own terms, and Apple's software licence agreements govern macOS virtual machines separately. That is a question for your legal team, not something the MIT grant resolves.

Upgrade cost is mostly operational. Each Cilicon release may require a config change, as 2.0 did with the vmBundlePath to source rename. Because images live in ~/.tart and are not pruned automatically, disk growth is the recurring maintenance item. Before adopting Cilicon, verify the host is on macOS 15.4 or later, confirm you can create the GitHub App or runner token your provisioner needs, and decide up front which specific Xcode image tag you will standardize on rather than letting latest resolve for you.

Editorial conclusion

Cilicon fits teams that already own Apple Silicon hardware, need Xcode in CI, and are willing to manage a cilicon.yml file plus a GitHub App or runner token. It is the wrong tool if you need Intel macOS builds, if you cannot keep the host on macOS 15.4 or later, or if you expect the project to manage image lifecycle for you. Before adopting it, verify three things on the host: that your macOS version is at least 15.4, that ~/.tart has room for the images you pull, and that your chosen image tag is a specific version rather than latest.

Frequently asked questions

Where does Cilicon store downloaded macOS images?

Images downloaded via OCI reside in the ~/.tart folder, according to the README. The README advises clearing that folder of unused images periodically, since Cilicon does not prune them automatically.

Which macOS version does Cilicon need on the host?

The README carries a warning about swift-nio based SSH on macOS 15.0 through 15.3.X and recommends macOS 15.4 or later for a more reliable experience. That applies to the host running the Cilicon app.

Does Cilicon work with GitLab and Buildkite, or only GitHub Actions?

The README documents provisioner types for GitHub, GitLab and Buildkite, plus a script provisioner for runners that are not natively supported. Each type has its own config block under provisioner in cilicon.yml.

What credentials are used when converting a Cilicon 1.0 image?

The migration notes say you must enable SSH and set the respective credentials in the config when converting a 1.0 image, or use the default admin:admin. The config schema also changed, and renaming vmBundlePath to source is said to suffice in most cases.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. traderepublic/Cilicon on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/traderepublic-cilicon.svg)](https://hysenlabs.com/projects/traderepublic-cilicon)