skip to content

In fastlane, which upload_to_app_store and upload_to_play_store options name an iOS or Android release version?

level: middleimportance: nice to knowfreq 46%

answer

  1. each store counts differently
  2. one string plus one number
  3. Apple edits an app_version record
  4. Play orders by integer version_code

basics

~20 s

On Apple's side upload_to_app_store uses app_version and build_number to choose the App Store Connect version and the build attached to it. On Google's side upload_to_play_store uses version_name and the integer version_code that Play orders releases by.

solid answer

~40 s

The two stores count differently, so the option names differ. `upload_to_app_store` takes `app_version` — the version string on the App Store Connect record being edited — and `build_number`, which selects the uploaded build attached to it; `skip_app_version_update` leaves the version untouched, and `edit_live` / `use_live_version` act on the live version rather than the editable one. `upload_to_play_store` takes `version_name`, a human-facing string, and `version_code`, the integer inside the APK or AAB that Google Play orders releases by; `version_codes_to_retain` says which existing codes stay active. Both actions can read these values out of the artifact you hand them, so you normally pass them only when no artifact is uploaded — a metadata-only run, or promoting a build already on the store.

go deeper

for a junior

Recall which pair belongs to which store: app_version and build_number for the App Store upload, version_name and version_code for the Google Play upload. Do not mix the option names.

for a middle

Explain what each option selects rather than just naming it, and why a lane that uploads an artifact rarely needs to set any of them at all.

for a senior

Show judgment about the source of truth: the artifact carries the numbers, so explicit options belong only to calls with no binary, such as a metadata fix or a promotion of an existing release.

for a principal

Own the versioning scheme end to end, including how build identifiers are generated in CI, so one number is authoritative per platform and never drifts between the build and the store call.

## Two numbering models, not one Both stores show users a friendly version string and both track an internal build identifier, but they name and use them differently, and the fastlane options follow the store rather than inventing a common vocabulary. On Apple's side the pair is a **marketing version** plus a **build number**, and both belong to a version record in App Store Connect that the upload edits. On Google's side the pair is a **version name** plus a **version code**, both baked into the Android artifact, where the integer code is the value Google Play uses to order releases. ## Apple: app_version plus build_number `upload_to_app_store` (`deliver`) exposes: - `app_version` — the version string of the App Store Connect record to work on. It decides which page the upload edits. - `build_number` — which already-processed build is attached to that version. - `skip_app_version_update` — do not change the version, just do the rest of the work. - `edit_live` and `use_live_version` — operate against the version currently live rather than the editable one, for a correction to something already released. - `app_identifier` — which app, when the credential can see several. When you upload an `.ipa`, the action can take the version and build values from the binary itself, so most release lanes never set them. You set them when there is no binary in the call. ## Google: version_name plus version_code `upload_to_play_store` (`supply`) exposes: - `version_name` — the human-facing string for the release. - `version_code` — the integer build identifier that lives inside the `.apk` or `.aab`. Google Play treats it as the ordering key for releases. - `version_codes_to_retain` — which previously uploaded codes remain active alongside the new one, which matters when several artifacts serve one release. - `package_name` — the Android application id being released. Again the artifact usually supplies the numbers; you name them explicitly when you are not uploading one. ## The mapping at a glance | Concept | iOS — `upload_to_app_store` | Android — `upload_to_play_store` | |---|---|---| | User-facing version | `app_version` | `version_name` | | Internal build identifier | `build_number` | `version_code`, an integer | | Where it normally comes from | the uploaded `ipa` | the uploaded `apk` or `aab` | | Leave it alone | `skip_app_version_update` | not applicable; the artifact carries it | | Multi-artifact concern | none | `version_codes_to_retain` | | Act on what is already public | `edit_live`, `use_live_version` | `track_promote_to` for an existing release | The rows are not synonyms. `build_number` selects a build that Apple has already received and processed; `version_code` is a number compiled into the Android artifact before it ever left the build machine. ## When you must pass the versions explicitly 1. **A metadata-only App Store run.** With `skip_binary_upload` there is no `.ipa` to read from, so `app_version` is how the action knows which version's page to edit. 2. **A changelog or listing fix on Google Play.** With no `apk` or `aab` in the call, `version_code` identifies the release being touched. 3. **Attaching a build uploaded earlier.** `build_number` points at a specific processed build rather than the newest one. 4. **Promoting an Android release that is already on the store.** `track_promote_to` moves an existing release onward without a new artifact, so the code identifies it. 5. **Keeping older Android artifacts alive.** `version_codes_to_retain` lists the codes that must stay active when the new one lands. ## Mistakes that come up in review - Passing `version_name` or `version_code` to `upload_to_app_store`, or `app_version` or `build_number` to `upload_to_play_store`. Neither action knows the other's option names. - Treating the Android `version_code` as something users see. It is an integer for ordering; `version_name` is the string on the listing. - Assuming `app_version` alone decides which binary ships. It selects the version record; `build_number` selects the build attached to it. - Hardcoding a version in the Fastfile for the llama-trekking booking app and letting it drift from the value inside the artifact, so a metadata-only run edits last month's release. - Forgetting that a Google Play release is ordered by the integer, so the number that matters is not the friendly string in the release name. ## The habit worth forming Let the artifact be the source of truth wherever a binary is uploaded, and reserve the explicit options for calls that carry no artifact. That keeps one number — the one compiled into the build — authoritative on each platform, and it stops a Fastfile constant from quietly disagreeing with what was actually shipped.

  • Why does an Android metadata-only lane need version_code while a normal release lane does not?
    Because a normal lane uploads the `.aab` or `.apk`, and the artifact carries the code. With `skip_upload_apk` and `skip_upload_aab` set, or with no artifact option at all, nothing tells `upload_to_play_store` which release it is editing, so `version_code` has to name it explicitly.
  • What is the difference between app_version and build_number on an App Store upload?
    `app_version` selects the App Store Connect version record the upload edits — effectively which release page. `build_number` selects which already-processed build is attached to that record. One picks the page, the other picks the binary on it, and `skip_app_version_update` leaves the version alone entirely.

saying these in an interview costs you the question

  • Passing version_name and version_code to the App Store upload
  • Treating the Android version_code as a display string
  • Assuming build_number and version_code mean the same thing
  • Believing app_version alone picks which build ships
  • Hardcoding versions in the Fastfile instead of reading the artifact