Ship
Take your Expo app from code-complete to live on the App Store and Google Play with one config and one command — build, submit, store listing, and release, with every manual store gate detected and surfaced.
amba ship takes a code-complete Expo app all the way to live on the App
Store and Google Play. One config file (amba.ship.json), one command,
six idempotent phases. Re-runs skip work that's already done, so the real loop
is clear a gate → re-run until you're live.
It's honest about what no API can do. Several launch steps — creating the store
app record, accepting the Apple Paid Apps agreement, screenshots, store review —
are not automatable. amba ship detects each one and stops with the exact
console action and URL, instead of pretending it's done.
amba ship runs where your app and its build toolchain live (your machine or CI). It drives the
Expo build/submit toolchain and your store credentials — Amba never sees your signing keys.
Quickstart
amba ship init writes a starter config you edit in place. --dry-run prints
the full plan and makes no changes or network calls. --force re-runs
phases already recorded as done. --phase <name> runs a single phase;
--platform ios|android narrows to one store.
The phases
amba ship runs these in order, recording per-app progress under
.amba/ship-state/ so a re-run resumes where it stopped:
| Phase | What it does |
|---|---|
preflight | Read-only checks: build toolchain installed + authenticated, config valid, store-record gates surfaced. Never mutates. |
monetization | Verifies your in-app purchase catalog is in sync with Amba's monetization control plane and stops if it has drifted. Skipped unless monetization.enabled is set. |
build | Builds the production binary for each platform. Idempotent — reuses a recorded build for the same version unless --force. |
submit | Uploads to TestFlight (iOS) and your Play track (Android). Won't re-submit a build that's already been submitted. |
metadata | Pushes the App Store listing and surfaces the store-side checklist (screenshots, privacy, data safety). |
release | Promotes the Android build to production; for iOS, stops at the manual Submit for Review gate (Apple review isn't automatable). |
Config
amba.ship.json carries non-secret identifiers and the name of the
environment variable holding your build token — never secret values. Your store
credentials stay in your build config, where the build runs.
ios.ascAppId stays null until your App Store Connect app record exists —
ship treats a missing one as a gate on the submit phase. android.track is
the Play track the submit phase lands on; release promotes it to production.
Bump app.version and the binary phases (build → release) re-run automatically.
Manual gates
These are not bugs — they're steps the stores require a human to do. amba ship
detects each and prints the exact action and console URL, then exits cleanly so
you can clear it and re-run:
- Create the App Store Connect and Google Play app records (no create API).
- Apple Paid Apps agreement + tax/banking, and the Play payments profile.
- Screenshots, App Privacy / Data safety, and content rating questionnaires.
- The first Play upload, published once manually (a Google Play limitation).
- Submit for Review and the final release on both stores.
Monetization
If your app sells anything, set monetization.enabled to true and ship
verifies your in-app purchase catalog against Amba's monetization control
plane before building — gating if it has drifted so you apply
the catalog with amba monetization apply first. Configure the catalog once;
amba ship keeps the store in step with it.
Related
amba monetization— the in-app purchase catalogshipverifies.- Sites — host your privacy/support pages at a public URL the stores require.
- CLI overview — install, auth, and project setup.