A minimal, opinionated starter for shipping iOS + Android apps with:
- Dev: TestFlight + Google Play Internal
- Prod: App Store + Google Play Production
This repo is intentionally lightweight. You plug in your own ios/ and android/ projects (React Native, native, etc.) and set the variables/secrets.
- GitHub Actions workflows for dev and prod releases
- Fastlane lanes for iOS and Android
- Clear separation of dev vs prod tracks
-
Add your mobile projects
- Put your iOS project in
ios/ - Put your Android project in
android/
- Put your iOS project in
-
Create the app entries in the stores
- iOS: create the app in App Store Connect and ensure the bundle id matches
IOS_APP_IDENTIFIER - Android: create the app in Google Play Console and ensure the package name matches
ANDROID_PACKAGE_NAME
- iOS: create the app in App Store Connect and ensure the bundle id matches
-
Make sure your iOS scheme is shared
- In Xcode:
Product > Scheme > Manage Schemes…and check Shared for the scheme you’ll build in CI
- In Xcode:
-
Set repo variables (non‑secret) in GitHub
IOS_WORKSPACE(e.g.,ios/MyApp.xcworkspace) orIOS_PROJECT(e.g.,ios/MyApp.xcodeproj)IOS_SCHEME(e.g.,MyApp)IOS_APP_IDENTIFIER(e.g.,com.example.app)APPLE_TEAM_IDANDROID_PACKAGE_NAME(e.g.,com.example.app)ANDROID_PROJECT_DIR(optional; default:android)ANDROID_GRADLE_TASK(optional; default:bundle)ANDROID_BUILD_TYPE(optional; default:Release)ANDROID_AAB_PATH(optional; default:android/app/build/outputs/bundle/release/app-release.aab)MATCH_GCS_BUCKET(optional; GCS match backend)MATCH_GCS_PROJECT_ID(optional; GCS match backend)MATCH_S3_BUCKET(optional; S3 match backend)MATCH_S3_REGION(optional; S3 match backend)MATCH_S3_PREFIX(optional; S3 match backend)
-
Set repo secrets in GitHub
APP_STORE_CONNECT_API_KEY_IDAPP_STORE_CONNECT_API_ISSUER_IDAPP_STORE_CONNECT_API_KEY_CONTENT(base64-encoded.p8)MATCH_GIT_URL(URL to your match repo)MATCH_PASSWORDMATCH_KEYCHAIN_PASSWORD(for CI temporary keychain)PLAY_STORE_JSON_KEY(base64-encoded service account JSON)MATCH_GCS_JSON_KEY(optional; raw GCS service account JSON)AWS_ACCESS_KEY_ID(optional; S3)AWS_SECRET_ACCESS_KEY(optional; S3)
-
Run a workflow
- Dev:
.github/workflows/dev.yml - Prod:
.github/workflows/prod.yml
- Dev:
If you’re new to Fastlane, the two store credentials below are the only “non‑code” blockers:
- App Store Connect API key: Create an API key in App Store Connect. Store the
.p8content as base64 inAPP_STORE_CONNECT_API_KEY_CONTENT, and the key/issuer IDs inAPP_STORE_CONNECT_API_KEY_ID/APP_STORE_CONNECT_API_ISSUER_ID. - Google Play service account: Create a service account in Google Cloud and grant it access in Play Console. Base64‑encode the JSON key into
PLAY_STORE_JSON_KEY.
Common encoding examples (macOS):
base64 -i AuthKey_XXXX.p8
base64 -i play-service-account.json- Add
ios/andandroid/projects and confirm paths in repo variables. - Create the app entries in App Store Connect and Google Play Console.
- Share the iOS scheme in Xcode.
- Configure Android release signing in your project.
- Add all required repo variables and secrets.
- Run
.github/workflows/setup-signing.ymlonce (choose backend). - Trigger
.github/workflows/dev.ymlto validate TestFlight + Play Internal.
- Dev (
.github/workflows/dev.yml)- Manual:
workflow_dispatch - Auto: pushes to
developordev
- Manual:
- Prod (
.github/workflows/prod.yml)- Manual:
workflow_dispatch - Auto: tag push matching
v*(e.g.,v1.2.3)
- Manual:
Use the optional workflow below to bootstrap iOS signing on a fresh app. It runs fastlane match to create certificates and profiles, then stores them in your configured backend.
- Workflow:
.github/workflows/setup-signing.yml - Choose backend via the
backendinput when triggering (git, gcs, s3) - Run once per app (or when rotating signing assets)
- After this, CI lanes use
matchin read‑only mode to fetch the assets
match supports multiple storage backends. Git is the default in this boilerplate, but you can use cloud storage too (e.g., Amazon S3 or Google Cloud Storage).
- Git (default): configure
MATCH_GIT_URLandMATCH_PASSWORD - Google Cloud Storage:
- Set
MATCH_GCS_BUCKETandMATCH_GCS_PROJECT_IDas repo variables - Add
MATCH_GCS_JSON_KEYas a repo secret (service account JSON) - The workflow writes
fastlane/gc_keys.jsonand usesfastlane/Matchfile.gcs
- Set
- Amazon S3:
- Set
MATCH_S3_BUCKET,MATCH_S3_REGION, and optionalMATCH_S3_PREFIXas repo variables - Add
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYas repo secrets - The workflow uses
fastlane/Matchfile.s3
- Set
If you previously stored signing assets in Google Cloud Storage, keep that setup and wire the GCS service account key + bucket config into the workflow env. Fastlane supports alternate storage options; pick whichever fits your org.
When using GCS or S3, mirror the same storage config in your dev/prod workflows so match can fetch signing assets (copy the key-writing + Matchfile steps from the setup workflow).
This boilerplate assumes your Android project is already configured to sign Release builds (keystore + Gradle config). If your app isn’t signed yet, set up a keystore in your Android project before running the workflows.
bundle install
bundle exec fastlane ios dev
bundle exec fastlane android devCreate a local .env based on fastlane/.env.sample if you want to run locally.
- iOS signing is handled via match. Update
fastlane/Fastfileif you prefer manual signing. - One-time signing setup: if your repo includes a
setup-signing.ymlworkflow, run it once to bootstrap certificates/profiles before the first CI release. - App Store Connect auth expects a
.p8key atfastlane/AuthKey.p8(CI creates it from the secret). For local runs, setAPP_STORE_CONNECT_API_KEY_PATH. - This repo assumes Release builds for Android.
fastlane/Fastfile– all lanes for dev/prod.github/workflows/dev.yml– dev pipeline.github/workflows/prod.yml– prod pipeline.github/workflows/setup-signing.yml– one-time iOS signing (choose backend)fastlane/.env.sample– local env templatefastlane/Matchfile.gcs– match config template for GCSfastlane/Matchfile.s3– match config template for S3
If you want me to tailor this for a specific app structure (e.g., monorepo, Expo, Flavors, multiple schemes), tell me your layout.