GitHub & CI/CD
Every Mosayic project lives in two GitHub repositories:
<project>-app— the React Native mobile codebase<project>-api— the FastAPI backend codebase
They’re deliberately separate, not a monorepo. Each can be released, versioned, and deployed independently — and most days you’ll only touch one of them.
Why two repos
Section titled “Why two repos”- Independent release cadence. A bug fix in the API doesn’t need a new mobile build. A polish change in the app doesn’t need an API redeploy.
- Independent CI. Mobile builds (EAS) and API deploys (Cloud Run) are different beasts with different test setups. Mixing them slows everything down.
- Smaller blast radius. A broken commit in one repo doesn’t block work in the other.
- Easier permissions. If you ever want to bring in a contractor for a frontend feature, you can give them access to just the mobile repo.
How they’re created
Section titled “How they’re created”Mosayic creates them for you during the Configure Your Project step, via:
gh repo create <project>-app --private --source=mobile --pushgh repo create <project>-api --private --source=api --pushBoth are private by default. You can make them public later if you want.
SSH keys
Section titled “SSH keys”To push without typing a password each time, Mosayic generates a fresh SSH key pair on your machine and registers the public half with your GitHub account:
ssh-keygen -t ed25519 -f ~/.ssh/mosayic_<project>gh ssh-key add ~/.ssh/mosayic_<project>.pub --title "Mosayic <project>"The remote URL for both repos is set to use SSH (git@github.com:...) so all subsequent pushes use the key automatically.
What’s already wired up
Section titled “What’s already wired up”The starter templates ship with several GitHub Actions workflows.
.github/workflows/eas-build-on-tag.yaml (mobile repo)
Section titled “.github/workflows/eas-build-on-tag.yaml (mobile repo)”Triggers when you push a tag matching v*. Runs eas build --profile production --platform all and (optionally) eas submit. This is what makes “cut a release” actually produce store-ready binaries.
.github/workflows/supabase-deploy-migrations.yaml (api repo)
Section titled “.github/workflows/supabase-deploy-migrations.yaml (api repo)”Triggers on push to main. Runs supabase db push against your production Supabase project to apply any new migrations.
Requires two repo secrets:
SUPABASE_ACCESS_TOKEN— set automatically when you connect SupabaseSUPABASE_PROJECT_REF— your production project’s ref
.github/workflows/gcp-deploy.yaml (api repo)
Section titled “.github/workflows/gcp-deploy.yaml (api repo)”Optional, off by default. Deploys your API to Cloud Run on push to main. Mosayic’s Production Release screen runs the equivalent command, so this workflow is for teams that prefer GitOps.
To enable, you’ll need to set up Workload Identity Federation between GitHub and GCP. The Supabase docs have a good walkthrough for the equivalent on their side; the GCP version is similar.
.github/workflows/scheduled-backups.yaml (api repo)
Section titled “.github/workflows/scheduled-backups.yaml (api repo)”Runs on a cron schedule (default: nightly at 3 AM UTC). Dumps your production Supabase to a Cloud Storage bucket. You’ll want to set this up before you have real users.
Repository secrets
Section titled “Repository secrets”GitHub Actions needs some secrets to do its work. The Secrets screen in the Mosayic dashboard sets these for you:
| Secret | Used by |
|---|---|
EXPO_TOKEN | EAS workflows |
SUPABASE_ACCESS_TOKEN | Migration workflow |
SUPABASE_DB_PASSWORD | Migration workflow |
DB_CONNECTION_STRING | Backup workflow |
GCP_SA_KEY | (Optional) Cloud Run deploy workflow |
These live as repository secrets on your <project>-api and <project>-app repos. They’re never visible in the Actions logs and can’t be read by anyone without write access to the repo.
Branch strategy
Section titled “Branch strategy”Mosayic doesn’t enforce one. The default starter has a single main branch and assumes a trunk-based workflow:
- Most changes go to
maindirectly - Release tags (
v1.0.0,v1.0.1, etc.) mark released versions
If you want feature branches, PRs, code review — go for it. The workflows trigger on main regardless of how commits got there.
Pre-flight checks
Section titled “Pre-flight checks”The Production Release screen runs these checks before letting you cut a release:
- ✅ Working tree is clean (no uncommitted changes)
- ✅ You’re on
main - ✅ Local
mainis in sync withorigin/main
This avoids common release mistakes (releasing local-only commits, releasing with a forgotten WIP file).
Tag-driven releases
Section titled “Tag-driven releases”When you click “Cut release” in the dashboard, Mosayic creates a tag like v1.2.3 on both repos. The mobile repo’s eas-build-on-tag.yaml workflow sees this and starts a production build. You can also trigger builds manually via the EAS web UI or CLI.
This means the source of truth for “what’s in production” is the git tag history. You can run git log --tags --oneline on either repo to see every released version.