@@ -26,7 +26,7 @@ expose `DomainResult<T>` (success/error), surfaced to ViewModels as a single `ui
2626
2727## Commands
2828
29- Build uses product flavors ` dev ` / ` beta ` / ` prod ` (dimension ` version ` ) and build types ` debug ` / ` release ` .
29+ Build uses product flavors ` dev ` / ` prod ` (dimension ` version ` ) and build types ` debug ` / ` release ` .
3030
3131The toolchain is pinned in ` mise.toml ` : ** Java temurin-21** (Gradle JVM — ` compileOptions ` and
3232` jvmTarget ` stay at 17, that is the bytecode level) and ** Ruby 3.4** (fastlane/bundler).
@@ -40,7 +40,8 @@ The toolchain is pinned in `mise.toml`: **Java temurin-21** (Gradle JVM — `com
4040# fastlane wrappers (bundle exec):
4141bundle exec fastlane unit_test # unit tests
4242bundle exec fastlane ui_test # instrumentation tests (DevDebug)
43- bundle exec fastlane prod_googleplay # build prod AAB + upload to Google Play
43+ bundle exec fastlane release # build the prodRelease AAB (used for every track)
44+ bundle exec fastlane beta_googleplay # upload that AAB to the beta track
4445```
4546
4647## Gotchas
@@ -53,9 +54,17 @@ bundle exec fastlane prod_googleplay # build prod AAB + upload to Google Play
5354 ` signingConfig ` . Fastlane deliberately does not inject ` android.injected.signing.* ` — a second
5455 copy of the keystore path drifts per machine, and ` -P ` properties leak the passwords into the
5556 build log. The only property the build lanes pass is ` uploadMapping ` .
56- - The Crashlytics mapping is uploaded ** only** when ` -PuploadMapping ` is set (the ` beta ` and ` prod `
57- fastlane lanes pass it). Local release builds skip it so they don't overwrite the mapping of the
57+ - The Crashlytics mapping is uploaded ** only** when ` -PuploadMapping ` is set (the ` release `
58+ fastlane lane passes it). Local release builds skip it so they don't overwrite the mapping of the
5859 same ` versionCode ` in Firebase.
60+ - ** Build once, promote.** There is a single release artifact — ` prodRelease ` — and it is what
61+ every Play track gets. Do not reintroduce a per-track flavor or ` versionNameSuffix ` : Play
62+ rejects a second upload with the same ` versionCode ` , so a track-specific binary forces a version
63+ bump between beta and production and the tested bits stop being the shipped bits.
64+ - Side-by-side installs come from the ** ` debug ` build type** (` applicationIdSuffix = ".debug" ` ),
65+ not from the flavor. ` devDebug ` is ` cl.figonzal.lastquakechile.debug ` and both package names are
66+ registered in ` app/google-services.json ` — moving that suffix onto the ` dev ` flavor would leave
67+ ` prodDebug ` holding the production applicationId.
5968
6069## Release process (release-please + fastlane + Google Play)
6170
@@ -100,7 +109,12 @@ Use the `/fastlane-changelog` command (see `.claude/commands/fastlane-changelog.
1001093 . Commit those ` default.txt ` files as the final commit onto the release PR branch.
1011104 . ** Merge the release PR** (` gh pr merge <n> --merge ` or the GitHub UI) → creates the tag,
102111 GitHub Release, and ` versionCode ` bump.
103- 5 . Build and upload: ` fastlane prod_googleplay ` (or ` beta_googleplay ` ) — reads ` default.txt ` .
112+ 5 . Build and upload to beta: ` fastlane release ` then ` fastlane beta_googleplay ` — reads
113+ ` default.txt ` . In Play Console the release can be * named* ` 1.8.0-beta ` ; that label is separate
114+ from the AAB's ` versionName ` and is editable when promoting.
115+ 6 . Test on the beta track, then ** promote in Play Console** (Production → Create release → Add
116+ from library → pick that ` versionCode ` ). No rebuild, no second upload: production ships the
117+ exact bits the testers ran. ` prod_googleplay ` is only for a version that skips beta entirely.
104118
105119## Conventions
106120
0 commit comments