From the Blog

← All posts

← Back to Blog Dark minimal desk setup with glowing monitor showing a mobile CI/CD pipeline config file

CI/CD for Mobile Apps: The 3-Stage Pipeline Solo Devs Actually Need

CI/CD for Mobile Apps: The 3-Stage Pipeline Solo Devs Actually Need

Manual builds are costing you 2–4 hours every release cycle — hours you could spend shipping features instead of babysitting Xcode and Gradle.

TL;DR

  • Enterprise CI/CD configs are overbuilt for solo mobile devs — three stages and two managed services is all you need.
  • GitHub Actions handles your build triggers and test runs; Fastlane handles signing and store delivery.
  • You can have a working pipeline that pushes to both the App Store and Google Play in under an hour of config.

---

Why Enterprise CI/CD Breaks for Mobile Apps

Most tutorials for CI/CD for mobile apps start with a Jenkins cluster, a dedicated macOS build farm, a secrets manager, a Slack bot, and a Kubernetes deployment manifest. That's a configuration written for a 12-person platform team managing five apps. It's not written for you.

The core problem: enterprise pipelines assume horizontal scale. They're designed so that ten developers can push simultaneously without stepping on each other. A solo dev or two-person team ships maybe two to four releases a week. That constraint changes everything.

Here's what actually breaks when you copy an enterprise pipeline:

  • Build minutes balloon. Enterprise configs run a full test matrix across five device tiers. A targeted single-device smoke test suite catches 90% of regressions in a fraction of the time.
  • Secrets sprawl. HashiCorp Vault is genuinely useful — at scale. For one app, a 15-minute GitHub Actions secrets setup does the same job without the ops overhead.
  • Config debt stacks up fast. A 400-line YAML pipeline you don't fully understand will break in a place you can't debug at midnight before launch.

The 2026 reality: managed CI services have closed the gap. GitHub Actions now has macOS M-series runners available at roughly $0.16 per minute, and a typical iOS build finishes in 6–8 minutes. That's under $1.50 per build. There's no longer a cost argument for self-hosting a Mac mini build server when you're pre-revenue.

Start from the minimum. Add complexity only when you hit a real constraint.

---

The Three-Stage Pipeline That Ships to Both Stores

Three stages. Nothing more until you need it.

Stage 1 — Test

Trigger on every pull request. Run your unit tests and a single targeted UI smoke test. Fail fast. This stage should finish in under 5 minutes. If it takes longer, you have too many tests running on CI — move integration tests to a nightly schedule.

Stage 2 — Build and Sign

Trigger on merge to main. Build the release artifact. Sign it. This is where Fastlane earns its place (more on that below). Output: a signed .ipa for iOS and a signed .aab for Android.

Stage 3 — Deploy

Trigger automatically after Stage 2 passes. Push the .ipa to TestFlight using fastlane pilot. Push the .aab to the Google Play internal track using fastlane supply. Both commands are idempotent — running them twice won't duplicate your submission.

That's the whole pipeline. Here's what it looks like in a single GitHub Actions workflow file (simplified):

name: Mobile Release

on:

push:

branches: [main]

jobs:

test:

runs-on: macos-latest

steps:

- uses: actions/checkout@v4

- name: Run unit tests

run: bundle exec fastlane test

build-and-deploy:

needs: test

runs-on: macos-latest

steps:

- uses: actions/checkout@v4

- name: Build, sign, and deploy

env:

APP_STORE_CONNECT_API_KEY: ${{ secrets.ASC_API_KEY }}

GOOGLE_PLAY_JSON_KEY: ${{ secrets.PLAY_JSON_KEY }}

MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}

run: bundle exec fastlane release

The fastlane release lane calls match for signing, then gym to build, then pilot for iOS and supply for Android. One command. Both stores.

---

CI/CD for Mobile Apps: Two Services, Zero Overhead

You need exactly two managed services: GitHub Actions and Fastlane. That's it.

GitHub Actions is the orchestrator. It listens to your git events, spins up an ephemeral macOS runner, runs your lanes, and reports back. You pay per build minute — no standing infrastructure, no idle cost. The free tier (2,000 minutes/month on private repos) covers roughly 200–300 iOS builds a month, which is more than enough pre-launch volume.

Fastlane is the mobile automation layer. It handles the two tasks that take solo devs the most time: code signing and store delivery. The fastlane match command syncs your certificates and provisioning profiles from a private Git repo (or S3 bucket) so that any runner can sign your app without you touching Keychain Access. The fastlane deliver and fastlane supply commands handle App Store Connect and Google Play Console API calls, including screenshots, metadata, and phased rollout flags.

No CircleCI. No Bitrise. No App Center. Those services add monthly SaaS cost and a separate config surface. GitHub Actions + Fastlane keeps everything in the repo you already have, and both tools have extensive documentation that's actively maintained heading into 2026.

Once your CI/CD for mobile apps is running, pairing it with the right mobile analytics tools for indie builders closes the feedback loop — you'll know within hours whether a release moved your key metrics. And if you want your release pipeline to automatically trigger acquisition, the 3-tool marketing stack for indie devs shows how to wire that in.

---

Code Signing and Secrets Without the Pain

Code signing is where most indie devs lose an afternoon. It doesn't have to be.

Use Fastlane Match

fastlane match centralizes your certificates and provisioning profiles in a single encrypted Git repo. Every runner that checks out your code can also check out your signing credentials — one environment variable (MATCH_PASSWORD) unlocks everything. Setup takes about 20 minutes the first time.

Run this once locally:

fastlane match init

fastlane match appstore

fastlane match development

After that, match runs in your CI pipeline and handles certificate renewal automatically. Apple's 1-year certificate expiry stops being your problem.

Store Secrets in GitHub Actions, Not in Files

Never commit .p12 files, .json keyfiles, or API keys to your repo. Use GitHub Actions secrets for:

  • ASC_API_KEY — App Store Connect API key (JSON format)
  • PLAY_JSON_KEY — Google Play service account JSON
  • MATCH_PASSWORD — Fastlane Match encryption passphrase
  • MATCH_GIT_BASIC_AUTHORIZATION — base64-encoded Git credentials for your match repo

All four secrets take under 10 minutes to configure in your repo settings. Each one maps to an environment variable in your workflow YAML. No secrets manager. No Vault. No KMS.

Two-Store Signing in One Lane

Your Fastfile release lane should call match(type: "appstore") before calling gym for iOS. For Android, Fastlane reads your keystore path and credentials from environment variables directly. A complete dual-platform Fastfile release lane runs end-to-end in 8–12 minutes on an M-series GitHub runner.

---

CI/CD for Mobile Apps: What to Skip Until You Hit 10K Users

Not everything belongs in a pipeline on day one. Here's what to defer:

  • Automated screenshot generation. Fastlane's snapshot tool is useful but adds 15–20 minutes to every build. Run it manually when you update your store listing, not on every release.
  • Staged rollouts via pipeline. Google Play's rollout percentage can be set in fastlane supply, but managing rollout progression from CI adds state that's easy to break. Use the Play Console UI until you have enough users for rollout data to be meaningful.
  • Custom notification systems. A GitHub Actions Slack notification takes 30 minutes to wire up and saves you zero time. You'll see the build status in your email. Skip it.
  • Separate staging and production pipelines. One pipeline, one main branch, one deployment to TestFlight internal testing first. Promote to full release manually. That manual gate costs you 2 minutes and saves you from accidentally shipping a broken build to all users.
  • Self-hosted runners. macOS GitHub-hosted runners are fast enough for pre-10K scale. The cost of a dedicated Mac mini (hardware + colocation + maintenance) isn't justified until build queue time is consistently over 15 minutes.

The pattern is always the same: add a pipeline feature when you feel the pain of not having it, not before. A solo dev who ships the right game engine setup with a clean CI/CD pipeline behind it is faster than a team that spent three weeks configuring the perfect DevOps stack before writing a line of game logic.

Keep the pipeline boring. Ship the app.

---

If you're staring down a manual build process and want to skip the trial-and-error, message Boyd Tiffin directly at /contact — describe where your pipeline is breaking and he'll tell you exactly what to change.

<<>>

Like what you read?

Get in touch — we’d love to hear from you.

Get in Touch