We used to dread pressing the deploy button. Not because something might break, but because every build cost us money.
For the longest time, we relied on Codemagic to build and deploy our iOS and Android apps. It made sense at the time because neither of us had a Mac capable of building iOS apps and Codemagic handled everything in the cloud. We liked it overall, but the pricing for non-personal use was steep. We're talking hundreds of dollars over time, and it made us passive about releases.
Instead of shipping fast and iterating quickly, we found ourselves batching updates together to minimize build costs. "Let's wait until we have three more features ready." "Let's combine these bug fixes into one release." This approach backfired spectacularly when updates failed which meant that rollbacks and debugging became a nightmare because we had no idea which of the ten changes we'd bundled together was the culprit.
The Comfort Zone Trap
Even after both of us got Macs, we stuck with Codemagic. It was comfortable. It worked. The thought of building on our own machines had crossed our minds, but the pain of keeping environments aligned, managing certificates, and dealing with provisioning profiles kept us at bay. Neither of us had any real DevOps experience, and the work of reading through .yaml config files felt like deciphering ancient scrolls.
So we kept paying. Month after month.
The Breaking Point
Then one day, I got frustrated. I wanted to push a quick patch using Shorebird which is a fantastic tool that lets you push over-the-air updates to Flutter apps without going through the app stores. But instead of waiting for Codemagic, I decided to try patching locally.
As I worked through various certificate issues and provisioning headaches, a thought struck me: If I'm going to deal with this anyway, let's do it properly.
That's when I stumbled across GitHub self-hosted runners.
It finally clicked. I could use my Mac in the exact same way as Codemagic's build agents but running on my own hardware. No per-minute charges. No artificial limits on build time. Just my machine, doing what it was always capable of doing.
What Are GitHub Self-Hosted Runners?
For those unfamiliar, GitHub Actions normally runs your workflows on GitHub's cloud infrastructure. But with self-hosted runners, you can register your own machine as a build agent. When a workflow triggers, GitHub sends the job to your machine instead of their servers.
The setup is surprisingly simple:
- Go to your repository settings
- Navigate to Actions > Runners
- Click "New self-hosted runner"
- Follow the installation steps for your OS
Once configured, your Mac sits ready to pick up any workflow that specifies runs-on: self-hosted. It's like having your own personal Codemagic agent, except it's free and you control everything.
The Missing Piece: Fastlane
The refactoring began. I started talking to Claude about what I wanted to achieve, and pretty rapidly I had a working GitHub Actions workflow. But there was a problem: the workflow used my locally installed certificates and keys to sign the apps. This would be annoying to manage across our team, even though it's just two of us, dealing with certificate syncing sounded like a recipe for "it works on my machine" disasters.
Then we discovered Fastlane.
Fastlane is an open-source platform that automates building and releasing mobile apps. But what really sold us was Fastlane Match which is a tool that syncs your certificates and provisioning profiles across machines using a private Git repository or cloud storage.
Here's how it works:
- All signing certificates are encrypted and stored in a Git repo
- When any team member (or CI runner) needs to build, Match pulls and installs the right certificates automatically
- No more manually exporting
.p12files or sharing provisioning profiles over Slack
Our Fastlane setup handles everything from incrementing build numbers to uploading to TestFlight and the Play Store. What used to be a scary manual process is now a single command.
The Result
Now our deployment costs are exactly $0. We run builds on our own Macs, certificates are synced automatically through Match, and we can patch and release whenever we want. No more batching updates because "builds are expensive." No more hesitating to push a quick fix because it'll eat into our monthly budget.
The psychological shift has been massive. We went from dreading deployments to embracing them. Found a typo? Ship it. Want to test a small feature with beta users? Ship it. The friction is gone.
If you're a small team paying for cloud CI/CD and you have Macs gathering dust, consider this approach. The initial setup takes a weekend, but the freedom it gives you is worth every minute.

