Skip to content

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.

  • 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.

Mosayic creates them for you during the Configure Your Project step, via:

Terminal window
gh repo create <project>-app --private --source=mobile --push
gh repo create <project>-api --private --source=api --push

Both are private by default. You can make them public later if you want.

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:

Terminal window
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.

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 Supabase
  • SUPABASE_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.

GitHub Actions needs some secrets to do its work. The Secrets screen in the Mosayic dashboard sets these for you:

SecretUsed by
EXPO_TOKENEAS workflows
SUPABASE_ACCESS_TOKENMigration workflow
SUPABASE_DB_PASSWORDMigration workflow
DB_CONNECTION_STRINGBackup 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.

Mosayic doesn’t enforce one. The default starter has a single main branch and assumes a trunk-based workflow:

  • Most changes go to main directly
  • 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.

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 main is in sync with origin/main

This avoids common release mistakes (releasing local-only commits, releasing with a forgotten WIP file).

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.