Migrate from Fastlane supply to gplay in an afternoon
If you’ve been shipping Android with Fastlane for years, you have a directory tree that looks something like:
fastlane/├── Fastfile└── metadata/ └── android/ ├── en-US/ │ ├── title.txt │ ├── short_description.txt │ ├── full_description.txt │ ├── images/ │ │ ├── icon.png │ │ ├── featureGraphic.png │ │ └── phoneScreenshots/ │ └── changelogs/ │ └── default.txt └── fr-FR/ └── ...Good news: gplay reads this format directly. You don’t have to rewrite your metadata, re-download screenshots, or manually re-enter listings. This post walks through the full migration in an afternoon.
Step 1 — install gplay
Section titled “Step 1 — install gplay”brew install tamtom/tap/gplaygplay setup --autogplay apps listsetup --auto reuses your existing service account if you already have one, or creates a new one. apps list confirms the connection.
Step 2 — dry-run your existing metadata
Section titled “Step 2 — dry-run your existing metadata”gplay migrate fastlane reads fastlane/metadata/android/ and shows you exactly what will be uploaded, without touching anything:
gplay migrate fastlane \ --package com.example.app \ --metadata-dir fastlane/metadata/android \ --dry-runOutput (formatted for readability):
Locale: en-US title: "MyApp" short_description: 80 chars full_description: 3120 chars screenshots (phone): 6 images featureGraphic: 1024x500 changelog: 240 chars
Locale: fr-FR ...
Total: 12 locales, 68 screenshots, 12 changelogsTotal upload size: 41 MBRead the diff. If anything looks wrong (missing locale, oversized screenshot, empty changelog), fix the source files first. gplay does not truncate — it fails loudly on Google’s validation.
Step 3 — run the migration
Section titled “Step 3 — run the migration”Drop the --dry-run:
gplay migrate fastlane \ --package com.example.app \ --metadata-dir fastlane/metadata/androidThis creates an edit session, uploads every listing, screenshot, and changelog, then commits atomically. If anything fails mid-way, the edit is discarded — Play Console goes back to exactly its previous state.
Step 4 — replace your supply lane
Section titled “Step 4 — replace your supply lane”Your Fastfile probably has something like:
lane :deploy do gradle(task: "bundleRelease") supply( track: "internal", aab: "app/build/outputs/bundle/release/app-release.aab", metadata_path: "./fastlane/metadata/android", skip_upload_apk: true )endThe gplay equivalent:
./gradlew bundleReleasegplay release \ --package com.example.app \ --track internal \ --bundle app/build/outputs/bundle/release/app-release.aab \ --listings-dir fastlane/metadata/android--listings-dir reuses your existing Fastlane metadata directory on every release. No migration needed for future runs — the source of truth stays where it is.
Or point it at a different directory if you want to move it out of the fastlane/ folder later:
gplay release \ --package com.example.app \ --track internal \ --bundle app-release.aab \ --listings-dir play-metadataStep 5 — port your other supply lanes
Section titled “Step 5 — port your other supply lanes”Every Fastlane action has a gplay equivalent. The ones you probably use most:
| Fastlane | gplay |
|---|---|
supply(track: "internal", aab: "...") |
gplay release --track internal --bundle ... |
supply(track: "production", rollout: "0.1") |
gplay tracks promote --to production --rollout 0.1 |
supply(skip_upload_screenshots: false, ...) |
gplay release --listings-dir ... |
download_screenshots(...) |
gplay listings pull --output-dir ... |
upload_to_play_store_internal_app_sharing |
gplay internal-app-sharing upload --bundle ... |
| Manual: change track from internal to alpha | gplay tracks promote --from internal --to alpha |
| Manual: check listing status | gplay listings get --package ... --locale en-US |
Step 6 — bonus, do things you couldn’t before
Section titled “Step 6 — bonus, do things you couldn’t before”Once you’ve migrated, you have 250+ commands available that Fastlane supply doesn’t cover. A few worth trying immediately:
Check crashes from CI:
gplay vitals crashes query --package com.example.app --time-range LAST_7_DAYSReply to reviews:
gplay reviews list --filter "rating<=2"gplay reviews reply --review-id <id> --message "Thanks for the feedback..."Manage subscriptions:
gplay subscriptions listgplay baseplans list --subscription-id monthly_proDownload this month’s earnings:
gplay reports financial listgplay reports financial download --report-id earnings_202607Fastlane can’t do any of this. It’s not a bug — supply was designed for a narrower job. gplay wasn’t.
What you can leave in place
Section titled “What you can leave in place”You don’t have to rip Fastlane out. Common hybrid:
- Keep Fastlane for the parts of iOS release you already have working.
- Keep
fastlane/metadata/android/as the source of truth for listings (gplay reads it natively). - Use gplay for Android release, staged rollout, monitoring, subscriptions, purchase verification, and everything post-publish.
Rollback plan
Section titled “Rollback plan”If you decide the migration didn’t work out (it will, but hypothetically):
- Your Fastlane metadata directory is unchanged. gplay reads it; it doesn’t rewrite it.
- Your service account and Play Console access are unchanged. Fastlane still authenticates fine.
- Your CI can call both. Nothing is exclusive.
Reverting is git revert on the workflow change. Zero data loss.
Getting started
Section titled “Getting started”brew install tamtom/tap/gplaygplay setup --autogplay migrate fastlane --package com.example.app --metadata-dir fastlane/metadata/android --dry-runFull migration reference at /reference/migrate/. If you want to fully automate the migration and CI rewrite in one shot, install the Fastlane migration skill and ask your AI agent to walk your repo end-to-end.