Skip to content

feat(release): publish fastlane changelogs and screenshots to Play - #59

Merged
mikebarkmin merged 1 commit into
mainfrom
claude/fastlane-google-play-changelog-screenshots-sf7ja4
Aug 29, 2026
Merged

mikebarkmin merged 1 commit into
mainfrom
claude/fastlane-google-play-changelog-screenshots-sf7ja4

Conversation

@mikebarkmin

Copy link
Copy Markdown
Member

Why

fastforge publish --targets playstore uploads the bundle and names the track release — and nothing else. Reading crates/app_publisher/src/playstore/mod.rs, perform_publish does insert_edit → upload_bundle → update_track (body is just {track, releases:[{name, versionCodes, status}]}) → commit_edit. It never sets releaseNotes and never calls edits.images or edits.listings.

So fastlane/metadata/android/ has only ever been read by F-Droid. The "What's new" section in Play was empty because nothing was ever sending it.

What changed

publish-playstore now runs fastlane supply instead of fastforge publish. Supply uploads the AAB and the whole metadata tree in a single Play edit, so the listing can't drift from the binary it ships. It reads the layout that already exists and picks changelogs/<version code>.txt matching the uploaded bundle — exactly what version_code.txt + changelog.yml already produce. Java, Flutter and Fastforge are dropped from the job (supply reads the version code from the upload response); Ruby and Pillow are added.

The committed tree can't go to Play as-is, which is what tool/prepare_play_metadata.py is for:

Play limit This repo
Release notes ≤ 500 chars 26.txt 571, 33.txt 728, 37.txt 668
Screenshot longest side ≤ 2× shortest 1080×2424 = 1:2.24 — rejected
No alpha channel on screenshots not currently guaranteed

Degrading the committed assets to Play's lowest common denominator would also hit tool/build_site.sh, which copies those same screenshots onto classi.openpatch.org. So the script writes a normalised copy that only supply --metadata_path consumes:

  • release notes trimmed on a bullet boundary, then any dangling section header dropped (33.txt: 728 → 476, whole bullets intact)
  • screenshots flattened to RGB and letterboxed — never cropped — to 1212×2424 by repeating the edge pixels outward, so the app bar continues into the padding instead of sitting next to black bars
  • oversized screenshots scaled under the 3840 px ceiling

Anything hand-written that Play would reject — title over 30 chars, more than 8 screenshots per form factor, a wrong-sized icon — is a hard error rather than a silent fix, because that should be a human decision.

de-DE/changelogs/default.txt is added because the generated changelog is English-only, and supply would otherwise push an empty "What's new" to the German listing.

Before merging

  • This overwrites the Play Console listing. Title, short and full description for both locales now come from the repo on every release. If they've been edited in the Console, reconcile first — the README documents a --validate_only dry run that shows what would be sent without committing to Play.
  • The service account needs wider scope. It previously only uploaded bundles; it now writes listings and images. If it's restricted in the Console, the job will 403.
  • de-DE/changelogs/default.txt is placeholder German. Every German release gets the same "Fehlerbehebungen und Verbesserungen" text until per-release de-DE/changelogs/<code>.txt files exist or changelog.yml emits both locales.

Testing

tool/prepare_play_metadata.py runs clean against the real tree (exit 0), plus synthetic edge cases: landscape padding, a 5000 px oversize, an undersized image, an over-length title, and 9 screenshots in one form factor. The letterbox output was rendered and inspected — the padding is not visible.

The Play API round-trip is unverified; it can't be exercised outside a tagged release. The first release after this merge is the real test.

`fastforge publish --targets playstore` only uploads the bundle and names the
track release — it never calls the Play API for release notes or the store
listing, so the changelogs `changelog.yml` has been generating into
`fastlane/metadata/android/en-US/changelogs/` only ever reached F-Droid, and
the screenshots never left the repository.

Replace it with `fastlane supply`, which uploads the bundle and the whole
metadata tree in a single Play edit, so the listing cannot drift from the
binary it ships with. It reads the same fastlane layout that is already here,
and picks the changelog matching the uploaded version code, which is the
scheme `version_code.txt` already produces.

The tree cannot be handed to Play unchanged: release notes are capped at 500
characters (three committed ones are over), screenshots may not carry an alpha
channel, and their longest side may be at most twice the shortest — the phone
screenshots are 1080x2424, or 1:2.24. Rather than degrade the F-Droid assets,
`tool/prepare_play_metadata.py` writes a normalised copy that only Play sees:
notes trimmed on a bullet boundary, screenshots flattened to RGB and
letterboxed by repeating their edge pixels, so the padding continues the app
bar instead of adding black bars. Anything hand-written that Play would reject,
such as a title over 30 characters, fails the job instead of being silently
fixed. Keeping the committed screenshots untouched also leaves
`tool/build_site.sh`, which copies them onto the landing page, unaffected.

Add `de-DE/changelogs/default.txt` so the German listing gets release notes
rather than an empty "What's new"; the generated changelog is English only.
@mikebarkmin
mikebarkmin merged commit 07efd32 into main Aug 29, 2026
1 check passed
@mikebarkmin
mikebarkmin deleted the claude/fastlane-google-play-changelog-screenshots-sf7ja4 branch August 29, 2026 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants