Day 55: CI/CD Pipelines for Web & Mobile (Fastlane, GitHub Actions)
Design a CI/CD pipeline that catches problems early (lint/type/test) and safely automates the genuinely painful parts of mobile release (signing, store submission).
Study
Concepts
A pipeline is a series of increasingly expensive, increasingly trust-worthy gates
The standard shape: lint + type-check (seconds, catches typos/obvious mistakes) → unit tests (fast, catches logic regressions) → build (confirms it actually compiles/bundles) → integration/E2E tests (slower, catches cross-component regressions) → deploy to a preview/staging environment → (manual or automatic) promote to production. Ordering matters for feedback speed: fail fast on the cheap checks before spending minutes on a full E2E suite for a PR that has an obvious lint error.
For a monorepo (Day 42), this pipeline should run scoped to affected packages only — re-running the full pipeline for every package on every PR does not scale, and Turborepo/Nx's affected-graph tooling is exactly what makes "only test what changed, plus its dependents" practical in CI.
Mobile release automation: the parts unique to iOS/Android
Web deploys are comparatively simple (push a static build/bundle to a host); mobile release involves CODE SIGNING (certificates and provisioning profiles on iOS, keystores on Android — both must be securely stored as CI secrets, never committed) and STORE SUBMISSION (App Store Connect / Google Play Console APIs, review times measured in hours to days, not seconds). Fastlane is the standard tool that automates this: `fastlane match` synchronizes signing certificates/profiles securely across a team's machines and CI, and lanes like `fastlane ios release` chain together build → sign → upload → submit-for-review as one reproducible, scriptable step instead of a manual, error-prone Xcode/Play Console ritual.
A staged rollout (releasing a new version to 5% of users first, then 25%, then 100%, monitored via the crash/error rates from Day 54 at each stage) is standard practice for mobile specifically, because — unlike a web deploy, which can be instantly rolled back — a bad native build already installed on a user's device cannot be un-installed remotely; the blast radius of a bad release must be limited BEFORE it happens, not fixed quickly after.
See It
Visualizations
Visualization
A staged CI/CD pipeline, cheapest gates first
seconds
fast, scoped to affected packages
slower, cross-component
staged rollout on mobile
Visualization
Mobile staged rollout with monitoring gates
Day 0
Release to 5% of users
watch crash-free rate closely
Day 1-2
If healthy, expand to 25%
Day 3-5
If healthy, expand to 100%
Any stage
If crash rate spikes: halt rollout
no remote uninstall — limiting blast radius is the only lever
Build It
Code Examples
GitHub Actions: scoped, staged pipeline for a monorepo
name: CI
on: [pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx turbo run lint typecheck --filter=...[origin/main]
test:
needs: quality
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx turbo run test --filter=...[origin/main]
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx turbo run build --filter=...[origin/main]A Fastlane lane automating signed build → TestFlight upload
# fastlane/Fastfile
platform :ios do
lane :beta do
match(type: 'appstore', readonly: true) # sync signing certs/profiles securely
increment_build_number(xcodeproj: 'App.xcodeproj')
build_app(scheme: 'App', export_method: 'app-store')
upload_to_testflight(skip_waiting_for_build_processing: true)
slack(message: "New beta build uploaded to TestFlight ✅")
end
end
# Invoked from CI as: bundle exec fastlane ios beta
# Signing secrets (match's encryption passphrase, App Store Connect API key)
# come from CI secrets, NEVER committed to the repo.Remember
Key Takeaways
- Order pipeline stages cheapest-and-fastest first (lint/type-check) so obvious mistakes fail in seconds, not minutes.
- Scope monorepo CI to affected packages (Day 42's tooling) — re-running everything on every PR does not scale.
- Mobile release uniquely requires code signing (certs/keystores as CI secrets) and store submission — Fastlane automates both reproducibly.
- Staged rollouts limit blast radius BEFORE a bad release reaches everyone — mobile builds cannot be remotely un-installed like a web deploy can be rolled back.
- Signing credentials and API keys belong in CI secrets management, never committed to the repository, even in a private one.
Do It
Practice
- 1Set up a GitHub Actions workflow with staged lint → test → build jobs (using needs: to enforce order) on a real or sample repo.
- 2Read the Fastlane match documentation and explain, in your own words, how it keeps signing certificates synchronized across a team without committing them to git.
- 3Design a staged-rollout policy (percentages + time-between-stages + the specific metric that would halt it) for a hypothetical banking app release.