Automating App Store and Play screenshots with fastlane
Uploading store screenshots by hand is manageable once. It becomes fragile when you have multiple device classes, several locales, regular releases, and more than one person touching the listing. fastlane makes the files part of the release process, so the same reviewed assets move from your repository or build artifact to both stores.
The two relevant fastlane tools are deliver for App Store Connect and supply, also exposed as upload_to_play_store, for Google Play. Both can upload metadata and screenshots without requiring a new binary in the same run.
Start by pinning fastlane
The official fastlane setup guide recommends managing fastlane with Bundler. Put the gem in a Gemfile, commit the resulting lockfile, and run commands through bundle exec fastlane. That keeps a CI runner and a developer laptop on the same fastlane version.
source "https://rubygems.org"
gem "fastlane"iOS: organize screenshots by locale
After fastlane deliver init, deliver uses fastlane/metadata for listing text and fastlane/screenshotsfor screenshots. Inside the screenshot directory, create one subdirectory per App Store locale. deliver determines the device type from each image's resolution. The official deliver reference documents the paths, supported locale codes, and configuration options.
fastlane/
screenshots/
en-US/
01-home.png
02-plan.png
03-result.png
de-DE/
01-home.png
02-plan.png
03-result.png
metadata/
en-US/
description.txt
keywords.txt
name.txt
subtitle.txtKeep the same numbered story order across locales. Resolution is not a substitute for a clear filename, especially during review. If the screenshots came from automated UI tests, fastlane's snapshot tool can capture multiple devices and languages and store the output in fastlane/screenshots. The screenshot automation guide covers that workflow.
Android: use Play's fixed image directories
Run fastlane supply init after the app exists in Play Console. The command creates or downloads the metadata structure under fastlane/metadata/android. Each locale contains text files and an images directory with fixed names for each screenshot slot.
fastlane/
metadata/
android/
en-US/
title.txt
short_description.txt
full_description.txt
images/
featureGraphic.png
phoneScreenshots/
01-home.png
02-plan.png
sevenInchScreenshots/
01-home.png
tenInchScreenshots/
01-home.pngThe directory names are case-sensitive conventions. Screenshots are ordered by filename, so zero-pad the numbers. The current supply documentation also warns that uploaded screenshots replace the current images in that listing instead of being appended. Treat the local directory as the complete intended set.
Create a screenshots-only lane
Separate asset publication from binary deployment. A narrow lane is easier to review and less likely to advance a build or overwrite unrelated listing text.
lane :store_screenshots do
deliver(
skip_binary_upload: true,
skip_metadata: true,
screenshots_path: "./fastlane/screenshots"
)
upload_to_play_store(
skip_upload_apk: true,
skip_upload_aab: true,
skip_upload_metadata: true,
skip_upload_images: true,
metadata_path: "./fastlane/metadata/android"
)
endIn the Play action, ordinary images and screenshots have separate skip controls. Settingskip_upload_images keeps the feature graphic and other single-image assets unchanged while still allowing the screenshot directories to upload. Remove that option when the feature graphic is intentionally part of the release.
Make CI boring and reversible
- Store App Store Connect API credentials and the Google service-account credential in the CI secret manager, never beside the screenshots.
- Generate and visually review assets in an earlier job. Make upload a separate approved job that consumes an immutable artifact.
- Check file count, dimensions, locale names, and numbered order before authentication. Fail locally before a store API can change anything.
- Let deliver produce its HTML metadata preview. Do not set
force: trueuntil the pipeline has another deliberate review gate. - Use supply's
validate_onlyoption for a validation job when it fits your release process, then run the actual upload only from a protected branch or tag. - Save the exact uploaded artifact and fastlane log for rollback diagnosis. A later run should be able to reproduce the same folder tree byte for byte.
Common failures
- The gallery order changed. Check alphanumeric filenames. Use
01,02, and10, not1,2, and10. - A locale is missing. Confirm that the directory name is a locale supported by the target tool, and that every expected device folder exists inside it.
- Old Play screenshots disappeared. supply replaces the set. Restore the missing files to the local directory and upload the complete intended set again.
- deliver chose the wrong device slot. Verify the exported pixel size. deliver infers device type from resolution, so a visually correct but incorrectly sized file can land in the wrong place or fail.
Storeboard generates the exact files before this process begins. Keep one exported folder per locale, map it into the fastlane structure, review the gallery once, and let the release pipeline handle the repetitive upload work.
Put this into practice
Generate screenshots ready for your release pipeline →Skip the artboards entirely.
A description, a screenshot, or your URL in; the full store-ready set out. Start free with a draft project.
Build my listing →