storebound/skills/migrate-from-fastlane/SKILL.md

5.2 KiB

name description
migrate-from-fastlane Move a mobile app or game from fastlane (deliver, supply, snapshot / screengrab, Appfile, Deliverfile) to storebound with `storebound import fastlane` - store ids, App Store and Google Play listing text in every language, categories, review notes, Play icon and feature graphic, screenshots as frames - without copying keys, team ids or the App Review demo account. Use when a project has a fastlane/ (or ios/fastlane, android/fastlane) folder, when the user says "we use fastlane", "migrate from fastlane", or before running `storebound init` in such a project.

Migrate from fastlane

CLI: storebound import fastlane [--dir fastlane] [--out .] [--profile app|game|subscription-app] [--dry] (MCP: import_fastlane, dry_run defaults to true). It only reads fastlane's files and never runs Ruby. Default --dir: every one of fastlane/, ios/fastlane/, android/fastlane/ that exists; pass several with commas.

Steps

  1. storebound import fastlane --dry. Show the owner the plan and the report. The report has five parts: mapped (source -> target), not mapped (with where each item goes by hand), keys, accounts and personal data (named only), placeholders and warnings (missing fields, store limits, unknown locale codes).
  2. With the owner's yes, run it without --dry. Nothing that exists is overwritten:
    • a text file that exists gets a <name>.imported.<ext> copy next to it. Compare with git diff --no-index store/listing.md store/listing.imported.md and merge what the owner wants;
    • an image that exists is kept.
  3. storebound init --profile <same profile>: it adds the remaining templates (declarations, App Privacy, Data safety CSV, privacy policy, .storebound/credentials.json) and keeps the imported files.
  4. Secrets, done by the owner (never in chat, never in the config; AGENTS.md rules 4 and 9):
    • Play json_key_file: move the key into .storebound/, set PLAY_SERVICE_ACCOUNT to its path. If the key was ever committed, rotate it in Google Cloud.
    • app_store_connect_api_key in the Fastfile: ASC_KEY_ID, ASC_ISSUER_ID, ASC_P8 (the .p8 path).
    • review_information/ contact and demo account: reviewContact and reviewDemoAccount in .storebound/credentials.json. The import sets reviewAccess.signInRequired: true when fastlane had a demo user.
  5. Replace the placeholders the report lists (app.contactEmail always: the App Review contact is personal data and is not used for it).
  6. storebound check, then storebound shots capture --source folder to check the imported frames.

What maps where

fastlane storebound
Appfile app_identifier / package_name apple.bundleId / play.packageName
deliver locale folders + supply language folders languages[], one entry per language with both codes (tr + tr-TR, zh-Hans + zh-CN, he + iw-IL, es-MX + es-419)
metadata/<locale>/name, subtitle, promotional_text, keywords, description, release_notes (+ default/) store/appstore.md (name, subtitle, promotionalText, keywords without spaces after commas, description, whatsNew)
privacy_url, support_url, marketing_url app.privacyPolicyUrl, app.supportUrl, app.marketingUrl + app.website (one for all languages)
copyright.txt, primary_category.txt ... app.copyright, apple.info.categories (GAMES picks the game profile)
review_information/notes.txt apple.info.reviewNotes
metadata/android/<lang>/title, short_description, full_description store/listing.md
newest changelogs/<versionCode>.txt (else default.txt) Play "What's new"
video.txt (YouTube) play.video
images/icon.png, images/featureGraphic.* store/icons/play-512.png (play.icon), store/renders/<lang>/feature/1024x500.*
screenshots/<locale>/ (largest iPhone set, iPad), else phoneScreenshots/, tenInchScreenshots/ store/shots/frames/<lang>/<phone|tablet>/NN.png, scenes shot-01..., shots.capture.source: 'folder', empty copy in store/shots/copy.json

Not imported (on purpose)

  • submit_for_review, automatic_release, reject_if_possible: the owner submits and releases (AGENTS.md rule 1); phased release is release-management.
  • price_tier: products and the prices CSV (store-iap-setup). Age rating config: store-declarations. Export compliance: export-compliance (apple.usesNonExemptEncryption stays commented out).
  • Lanes, match, gym / gradle: building and signing stay where they are; storebound has no lanes.
  • Ruby logic (for_platform, for_lane, ENV[...], interpolation): reported by key and line; set those in storebound.config.ts.
  • Promo graphic, TV banner, TV / Wear screenshots, Apple TV privacy policy, Korean trade representative contact: consoles.

Screenshots

fastlane screenshots are often finished store art (framed, captioned). The import puts them in the frames folder so shots render can rebuild them from one source in every size; full-screen captures usually need the status bar cut (shots capture --source folder reports the aspect ratio per frame). If the owner prefers to keep the finished art, leave the copy empty and upload as before. JPEG screenshots are listed, not copied (frames are PNG).