skip to content

In fastlane, where do upload_to_app_store and upload_to_play_store read iOS and Android release notes from?

level: middleimportance: nice to knowfreq 42%

answer

  1. both read a metadata folder
  2. metadata_path names the tree
  3. Apple keys notes by locale
  4. Play files changelogs per version code

basics

~20 s

Both read a metadata folder set by metadata_path, but the layouts differ. upload_to_app_store reads a per-locale release_notes entry and also accepts the text inline as an option; upload_to_play_store reads per-locale changelog files named after the Android version code.

solid answer

~40 s

Both actions take the folder through `metadata_path`, and that is where the similarity ends. On Apple's side, `upload_to_app_store` reads a tree whose per-locale folders hold one file per localized key, and `release_notes` is one of those keys alongside `description`, `keywords` and `subtitle`; because those keys are also action options, you can pass the text inline instead of writing files. On Google's side, `upload_to_play_store` reads its own tree where each locale folder has a `changelogs` directory holding **one file named for the Android version code** — and no option carries that text, so the file is the only route. That asymmetry explains most missing-changelog incidents: a new version code shipped with no matching file. `skip_upload_changelogs` and `skip_metadata` turn the respective uploads off.

code

ruby · 12 lines
ruby
lane :fix_play_changelog do
  upload_to_play_store(
    package_name: 'com.llamatrek.booking',
    json_key: './play_key.json',
    metadata_path: './fastlane/metadata/android',
    version_code: 412,
    skip_upload_apk: true,
    skip_upload_aab: true,
    skip_upload_images: true,
    skip_upload_screenshots: true
  )
end

go deeper

for a junior

Remember that both upload actions read release notes from files under metadata_path, not from the Fastfile, and that the folder layout differs for the App Store and for Google Play.

for a middle

Explain the two shapes precisely: a localized release_notes key per locale on Apple's side, a changelog file named for the version code on Google's, and which skip switch turns each one off.

for a senior

Show how you keep notes from silently going missing on release night: a check that a changelog exists for the version code being shipped, and a lane that fails loudly rather than uploading blank text.

for a principal

Decide who authors release notes and in which locales, and whether that text is generated in the pipeline or owned by a human writer, because the answer shapes the whole metadata directory and its review path.

## One idea, two directory shapes Release notes are the what-is-new text a store shows next to a new version. Both fastlane upload actions read them from **disk** rather than from the Fastfile, and both take the folder through an option called `metadata_path`. That is where the similarity stops. Apple treats release notes as one **localized field among many** on the app version being edited; Google Play treats them as a **changelog bound to a specific version code**. The layouts are not interchangeable, and pointing one action at the other's tree usually produces an upload with no notes rather than a loud error. ## Apple: release_notes is a localized metadata key `upload_to_app_store` (`deliver`) reads a metadata tree, conventionally `./fastlane/metadata`, whose per-locale folders hold one file per localized key. `release_notes` is one of those keys, sitting alongside `description`, `keywords`, `name`, `subtitle`, `promotional_text`, `support_url`, `marketing_url`, `privacy_url` and `copyright`. For the llama-trekking booking app, the English and German notes live in the `en-US` and `de-DE` folders of that tree. Because those localized keys are also **action options**, the folder is not the only route on this side: you can pass the text straight into the action, which is handy when the notes are generated from commit history earlier in the same lane. Whole categories can be switched off too — `skip_metadata` sends the binary only, `skip_screenshots` leaves the images alone, and `skip_binary_upload` sends the listing without a new build. ## Google Play: a changelog file per version code `upload_to_play_store` (`supply`) reads its own tree, conventionally `./fastlane/metadata/android`, where each locale folder contains a `changelogs` directory. The files inside are named for the **Android version code** — `412.txt` for version code 412 — and a `default.txt` in the same folder acts as the fallback when no file matches. The important fact here is a negative one: the action's options include `skip_upload_changelogs` but **no option that carries the changelog text**. On Android the file is the only route. That single asymmetry explains most missing-changelog incidents — the build produced a new version code, nobody added the matching file, and the release went out with empty notes. ## The two layouts side by side | | iOS — `upload_to_app_store` | Android — `upload_to_play_store` | |---|---|---| | Folder option | `metadata_path`, conventionally `./fastlane/metadata` | `metadata_path`, conventionally `./fastlane/metadata/android` | | Where the notes live | one localized key file per locale folder | `<locale>/changelogs/<version code>.txt` | | Keyed by | the app version being edited | the integer version code | | Inline alternative | the localized keys are action options too | none — the file is the only route | | Fallback | none; a missing locale simply is not sent | `changelogs/default.txt` | | Switch it off | `skip_metadata` | `skip_upload_changelogs` | ## Shipping notes without shipping a binary A very common lane is fix the wording, publish nothing new. Both actions support it, again with different switches: - On Apple's side, `skip_binary_upload` plus `app_version` updates the listing of a version already in App Store Connect. - On Google's side, drop the artifact options (or set `skip_upload_apk` and `skip_upload_aab`) and name the `version_code` whose changelog you are correcting. - Narrow the run further with `skip_upload_images` and `skip_upload_screenshots` on Google's side, or `skip_screenshots` on Apple's, so a wording fix does not re-upload every asset. ## Where release notes silently go missing - The Android version code moved and no changelog file was added for it, so the release ships with whatever `default.txt` says, or with nothing. - `metadata_path` points at the Apple tree while `upload_to_play_store` is running, so no locale folder matches and nothing is found. - A locale folder exists on one store but not the other; the two stores' locale sets are maintained independently. - `skip_upload_changelogs` was set months ago to speed a lane up and nobody removed it. - Notes were generated inline for iOS and everyone assumed the Android lane would pick up the same text, which it cannot. ## How to talk about it in an interview The short version is: **same option name, different shape**. `metadata_path` is common vocabulary; `release_notes` as a localized key with an inline option is Apple's model; a version-code-named changelog file is Google Play's. Naming the canonical actions — `upload_to_app_store` and `upload_to_play_store` rather than only `deliver` and `supply` — signals that you know the two lanes are separate code paths with separate conventions, not one uploader with a platform switch.

  • The Android release notes came out empty even though the lane reported success. What do you check first?
    Whether a changelog file exists for the version code that shipped. `upload_to_play_store` looks for a file named for the version code under the locale's `changelogs` folder and falls back to `default.txt`, so a bumped code with no new file yields empty notes and no error. Then confirm `skip_upload_changelogs` is unset and that `metadata_path` points at the Android tree.
  • Can you generate release notes in the lane instead of committing files?
    On Apple's side yes: the localized metadata keys are also options on `upload_to_app_store`, so text built earlier in the lane can be passed straight in. On Google's side there is no changelog option, so the lane must write the file into the `changelogs` folder for the version code before calling `upload_to_play_store`.

saying these in an interview costs you the question

  • Assuming upload_to_play_store takes changelog text as an option
  • Expecting one release-notes file to cover every locale
  • Thinking Play changelogs are keyed by the version name
  • Believing skip_metadata on the Apple lane also affects Play
  • Assuming missing notes fail the upload rather than shipping empty