As explained before, I have a M1 Mini that I use as a server at home to self-serve diverse applications. Today, I'll try to run my CI/CD on it!

Why?

The project is conceptually simple: a react app talking to Supabase with a few Supabase functions. The E2E are written in Playwright and mimic a significant part of all the combinations that can happen in this software (as a user would do).

My GitHub bill was the trigger. I was looking at the invoice for this small project and saw the Actions minutes spiking. The culprit was a 70-line monster of a YAML file. It was a flaky, brittle beast held together with sleep commands and curl loops, all designed to fight the stateless, ephemeral nature of an ubuntu-latest runner (you get a new instance on every run).
Every run would re-download the multi-gigabyte Supabase Docker stack, wasting time and my money.

I looked at the bill, then at my M1 Mac Mini - always on, always humming, the best hardware on the planet (ok, I'm biased). The fix was obvious: move to a self-hosted runner.

How?

Github developer experience is really good: they support the self-runners and they offer the same experience as the hosted ones!

Just download a bunch of stuff (https://github.com/<your org>/<your project>/settings/actions/runners/new) and make a designated folder to run the actions on a given machine.

Tada! ready to use!

Does it work?

YES, once you run the ./run.sh in the background on the Mac Mini, it will pull the jobs from Github Actions and execute them. I had not a single miss in 2 weeks.

Is it better?

YES. For many reasons:

  1. Stateful vs Stateless: if you know what you are doing, you would prefer having a stateful environment to not re-configure all the dependencies on every test-run (worst case for me was Supabase + Playwright browser to be re-downloaded on every PR (cache works per branch)). I tried creating an image which would have all the dependencies but I run into so many diverse issues that my lazyness told me "there must be a simpler way".
    On my Mac Mini, Supabase is installed runs in my Docker machine, the test reset the db at the beginning of the run (supabase db reset) and start.
  2. Hosted MacOS minutes are expensive. The Mac minutes are 10x more expensive than the Linux, it does make sense (because Macs are generally not server grade hardware -  so more expensive to maintain, it is not Github specific) but it makes the self-hosting even more relevant.
  3. Because it runs on a Mac, I can have Safari's Playwright and make sure that I delight Apple users as well
  4. It has a real display, so browsers (including Playwright) tend to be more realistic and less flaky.
  5. My home connection (a 5G connection) is worse than a datacenter: I get more realistic test results. I have a similar internet connection as my users.
  6. More power: a Mac Mini has 8 CPU and a 8 GPUs (which can be used by the browser for rendering the pages - no idea if it's the case). The default runner on Linux has only 2, the default on Mac 3.
  7. Better for privacy, if you are in a secure environment and you are able to separate the code from the data, having the test data on the Mac Mini will always be more secure by design that having them in Github (yes, your test data should be meaningless and not sensitive, but they are probably not 😉).

Conclusion

I finally found a successor to my Jenkins setup that I deployed in every company I joined. Well done Github!