chore(screenshots): Commit only English Play Store screenshots
Only en-US screenshots are tracked from now on. The other 67 locales are generated on demand and gitignored, which drops 35 PNGs and roughly 5 MB from the repository and stops every screenshot refresh from churning binaries in five languages nobody reviews. Play Store still gets the full 68 locales. supply only uploads what is present under fastlane/metadata/android/<locale>/images/phoneScreenshots/ and retains whatever was last pushed for locales absent from an upload, so localization is maintained by an occasional manual regen plus screenshots_only rather than by every PR. PlayStoreLocales.kt had been committed since February holding a truncated four-locale batch slice, left behind when a run was killed before its EXIT trap restored the file. The next run then copied that slice over its own backup and faithfully restored the corruption, which is why the remnant survived six months. It is replaced with a documented en-US placeholder, the generator no longer emits an annotation nothing references, and the script now refuses to start when a stale .bak is present instead of clobbering the only good copy. The refresh runbook is corrected as well: it ended with a checkout that restores tracked files from the index, which would have reverted the freshly rendered English screenshots while the store received them, and its upload step is now gated so a failed upload leaves them staged for a retry rather than committed as though deployed.
@@ -32,13 +32,15 @@ ScreenshotContent.kt (mock data + composables)
|
||||
|------|---------|
|
||||
| `app/src/debug/java/.../screenshots/ScreenshotContent.kt` | Mock data composables (7 exist; `HomescreenWidgetContent` has an IDE preview only and is **not** in the Play Store pipeline) |
|
||||
| `app/src/screenshotTest/kotlin/.../screenshots/PlayStoreScreenshots.kt` | `@PreviewTest` functions (currently: `DashboardLight`, `DashboardDark`, `CasePopUp`, `DeviceProfiles`, `AddProfile`, `DeviceSettingsReactions`, `WidgetConfiguration`) |
|
||||
| `app/src/screenshotTest/kotlin/.../screenshots/PlayStoreLocales.kt` | Multi-preview annotations (auto-generated by batch script) |
|
||||
| `app/src/screenshotTest/kotlin/.../screenshots/PlayStoreLocales.kt` | Multi-preview annotations. The committed content is an en-US placeholder, not meaningful data — `generate_screenshots.sh` rewrites it per batch and restores it from a `.bak` on exit. A run killed hard leaves that `.bak` behind, so the script now refuses to start until it is restored by hand |
|
||||
| `fastlane/generate_screenshots.sh` | Batched generation; locale list (`ALL_LOCALES`) and `BATCH_SIZE` are defined inside the script |
|
||||
| `fastlane/copy_screenshots.sh` | Copies rendered PNGs into fastlane structure |
|
||||
|
||||
## Commit policy
|
||||
|
||||
Only the 6 smoke locales (en-US, de-DE, ja-JP, ar, zh-CN, pt-BR) have `phoneScreenshots/*.png` checked into the repo. Non-smoke locales are excluded by `.gitignore`. This mirrors permission-pilot and keeps repo size small (~7 MB vs ~67 MB for the full 68 locales).
|
||||
Only `en-US` has `phoneScreenshots/*.png` checked into the repo — 7 PNGs, ~1 MB tracked. Every other locale is excluded by `.gitignore`.
|
||||
|
||||
`--smoke` still *renders* 6 locales (en-US, de-DE, ja-JP, ar, zh-CN, pt-BR), but only en-US is committed. The other five cover LTR, RTL and CJK layout so a render that breaks on non-Latin script fails during generation, and the resulting PNGs sit in the working tree for manual inspection. Nothing compares them against a baseline, so this is render coverage plus eyeballing, not regression checking.
|
||||
|
||||
Play Store's `supply` only uploads what's present in `fastlane/metadata/android/<locale>/images/phoneScreenshots/`. For locales not in the upload, Play Store retains whatever was last pushed. So full localization on Play Store is maintained by an **occasional manual** full regen + `:screenshots_only` upload — not by every PR.
|
||||
|
||||
@@ -90,11 +92,20 @@ Periodic, manual operation — not per-PR:
|
||||
```bash
|
||||
./fastlane/generate_screenshots.sh # full, ~30 min, 476 PNGs (68 locales x 7)
|
||||
./fastlane/copy_screenshots.sh --clean
|
||||
bundle exec fastlane screenshots_only # uploads all 68 locales to Play Store
|
||||
git checkout -- fastlane/metadata/android/ # discard non-smoke changes (gitignored anyway)
|
||||
git add fastlane/metadata/android/en-US/images/phoneScreenshots/
|
||||
if bundle exec fastlane screenshots_only; then
|
||||
git checkout -- fastlane/metadata/android/ &&
|
||||
git commit --only -m "chore(screenshots): Refresh Play Store screenshots" -- \
|
||||
fastlane/metadata/android/en-US/images/phoneScreenshots/
|
||||
else
|
||||
git checkout -- fastlane/metadata/android/
|
||||
echo "Upload failed; the refreshed en-US screenshots remain staged for retry."
|
||||
fi
|
||||
```
|
||||
|
||||
The `.gitignore` rule keeps non-smoke output unstaged automatically, so only the smoke locales' refreshed PNGs would show up as modifications and can be committed.
|
||||
The `git add` has to happen before the upload. The final `git checkout` restores every tracked file under that path **from the index**, so staging the refreshed English set is precisely what makes it survive the checkout — skip the `git add` and the checkout silently reverts the refresh while the store still receives the new images.
|
||||
|
||||
Restoring is the checkout's job otherwise: `screenshots_only` runs `remove_unsupported_languages.sh`, which deletes 9 tracked locale directories (es-AR, sc-IT, sq-AL, uz, kmr-TR, ur-IN, zu, si-LK, nb) from the working tree before uploading — 35 tracked files, a subset of the 309 tracked non-screenshot metadata files under that path, all of them put back by the checkout. It does **not** touch the regenerated non-English PNGs: those are untracked and ignored, so they stay on disk and never show up in `git status`. Because the checkout discards any uncommitted metadata text edits too, run this refresh only with an otherwise-clean metadata tree. The final commit is path-limited on purpose, so an unrelated staged change can't ride along, and it is gated on `screenshots_only` succeeding rather than merely sequenced after it: if the upload fails, the refreshed English files stay staged for a retry instead of being committed as though they were deployed. The deleted locale directories are restored on either path.
|
||||
|
||||
## Technical Notes
|
||||
|
||||
|
||||
@@ -17,16 +17,11 @@
|
||||
.kotlin
|
||||
# Screenshot test reference images (ephemeral, regenerated on demand)
|
||||
app/src/screenshotTest*/reference/
|
||||
# Play Store phone screenshots: commit only the 6 smoke locales (mirrors permission-pilot).
|
||||
# Play Store phone screenshots: commit only en-US.
|
||||
# Full localization is uploaded by occasional manual regen + screenshots_only;
|
||||
# Play Store retains previously-uploaded screenshots for locales not pushed.
|
||||
fastlane/metadata/android/*/images/phoneScreenshots/*.png
|
||||
!fastlane/metadata/android/en-US/images/phoneScreenshots/*.png
|
||||
!fastlane/metadata/android/de-DE/images/phoneScreenshots/*.png
|
||||
!fastlane/metadata/android/ja-JP/images/phoneScreenshots/*.png
|
||||
!fastlane/metadata/android/ar/images/phoneScreenshots/*.png
|
||||
!fastlane/metadata/android/zh-CN/images/phoneScreenshots/*.png
|
||||
!fastlane/metadata/android/pt-BR/images/phoneScreenshots/*.png
|
||||
.codex
|
||||
protocol-research/
|
||||
_site/
|
||||
|
||||
@@ -4,26 +4,17 @@ import android.content.res.Configuration
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
||||
/**
|
||||
* Multi-preview annotation generating one preview per Play Store-supported locale (light mode).
|
||||
* Each [name] is the fastlane metadata directory name for direct use in the copy script.
|
||||
* Placeholder locale set. `fastlane/generate_screenshots.sh` rewrites this file per batch and
|
||||
* restores it afterwards, so the committed content only decides what a bare
|
||||
* `./gradlew updateGplayDebugScreenshotTest` renders.
|
||||
*
|
||||
* [name] is the fastlane metadata directory the copy script sorts the output into.
|
||||
*/
|
||||
@Preview(locale = "en", name = "en-US", device = DS)
|
||||
@Preview(locale = "af", name = "af", device = DS)
|
||||
@Preview(locale = "am", name = "am", device = DS)
|
||||
@Preview(locale = "ar", name = "ar", device = DS)
|
||||
annotation class PlayStoreLocales
|
||||
|
||||
/**
|
||||
* Same locales but with night mode enabled for dark theme screenshots.
|
||||
*/
|
||||
@Preview(locale = "en", name = "en-US", device = DS, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Preview(locale = "af", name = "af", device = DS, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Preview(locale = "am", name = "am", device = DS, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Preview(locale = "ar", name = "ar", device = DS, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
annotation class PlayStoreLocalesDark
|
||||
|
||||
/**
|
||||
* Smoke test subset for fast iteration (6 locales covering LTR, RTL, CJK).
|
||||
*/
|
||||
@Preview(locale = "en", name = "en-US", device = DS)
|
||||
annotation class PlayStoreLocalesSmoke
|
||||
|
||||
@@ -122,6 +122,15 @@ echo "=== Localized Screenshot Generation ==="
|
||||
echo "Locales: $TOTAL | Batch size: $BATCH_SIZE | Batches: $NUM_BATCHES"
|
||||
echo ""
|
||||
|
||||
# A leftover .bak means a previous run died before its trap restored the file: the real source is
|
||||
# in the .bak and copying over it here would destroy the only good copy.
|
||||
if [[ -e "$LOCALES_FILE.bak" ]]; then
|
||||
echo "ERROR: Stale backup found: $LOCALES_FILE.bak"
|
||||
echo "A previous run was interrupted. Restore it first:"
|
||||
echo " mv \"$LOCALES_FILE.bak\" \"$LOCALES_FILE\""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Back up the original file
|
||||
cp "$LOCALES_FILE" "$LOCALES_FILE.bak"
|
||||
trap 'mv "$LOCALES_FILE.bak" "$LOCALES_FILE"; echo "Restored original PlayStoreLocales.kt"' EXIT
|
||||
@@ -166,13 +175,6 @@ HEADER
|
||||
done
|
||||
echo "annotation class PlayStoreLocalesDark" >> "$file"
|
||||
echo "" >> "$file"
|
||||
|
||||
# Smoke annotation (single entry placeholder)
|
||||
echo "/**" >> "$file"
|
||||
echo " * Smoke test subset for fast iteration (6 locales covering LTR, RTL, CJK)." >> "$file"
|
||||
echo " */" >> "$file"
|
||||
echo "@Preview(locale = \"en\", name = \"en-US\", device = DS)" >> "$file"
|
||||
echo "annotation class PlayStoreLocalesSmoke" >> "$file"
|
||||
}
|
||||
|
||||
for (( batch=0; batch < NUM_BATCHES; batch++ )); do
|
||||
|
||||
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 209 KiB |
|
Before Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 206 KiB |