From eb14d6c245d3b8002b2a53f1eb11cb48cb905c4d Mon Sep 17 00:00:00 2001 From: engineer Date: Fri, 14 Aug 2026 11:06:48 -0700 Subject: [PATCH] docs(release): record v0.4.15 and make the versionCode bump non-optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two things the v0.4.15 cut got wrong were things this doc told it to do. - PUBLISHING.md step 1 said not to bother hand-bumping `android.versionCode`. That is true for Play (CI overrides it with run_number+100) and false for the two channels that carry most of the install base: F-Droid and direct APK key upgrades off versionCode, so reusing the previous one means the release is never offered to anyone who already has that code. Step 1 now lists all four places to bump plus the changelog named after the code, and step 5 adds the two channel checks (GitHub release — the source the in-app update check polls — and the F-Droid index) that were previously implied to be unnecessary. - docs/playstore.md release history: v0.4.15 at production versionCode 153, the first release to reach production from a tag push alone (#177), plus the superseded 152 from the pre-#180 tag. Co-Authored-By: Paperclip --- PUBLISHING.md | 8 +++++--- docs/playstore.md | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/PUBLISHING.md b/PUBLISHING.md index 89c059b3..f20e7d0d 100644 --- a/PUBLISHING.md +++ b/PUBLISHING.md @@ -44,11 +44,13 @@ It builds an AAB (Android App Bundle), signs it with the release keystore, and u ## Releasing (proven runbook) -1. Bump `version` in `package.json` **and** `app.json` (`expo.version`). Do **not** bother hand-bumping `android.versionCode` for Play — the publish workflow overrides it with `github.run_number + 100` at build time (so the Play `versionCode` is e.g. `142`, unrelated to the number in `app.json`; that field only matters for local/other builds). -2. Update the **Play** release notes in `distribution/whatsnew/whatsnew-en-US` (single file, applied to the build being uploaded; **max 500 chars**). This — not the `fastlane/metadata/android/en-US/changelogs/*.txt` files — is what the Play publish uses (`whatsNewDirectory` in the workflow). The fastlane `changelogs/*.txt` files feed **F-Droid**, not Play; keep them for F-Droid but don't expect Play to read them. Merge to `main`. +1. Bump the version in **four** places, then run `npm run check:versions` before you push: `package.json` `version`, `app.json` `expo.version`, and `android/app/build.gradle` `versionName` — plus `versionCode` in **both** `app.json` (`expo.android.versionCode`) and `build.gradle`, incremented by one. + - Play does not need the hand-bumped `versionCode` (the publish workflow overrides it with `github.run_number + 100`, so the Play code is e.g. `152`, unrelated to the `app.json` number). **F-Droid and direct-APK installs do.** They key upgrades off `versionCode`, so a release that reuses the previous one is silently never offered to anyone who already has that code installed. v0.4.15 shipped with v0.4.14's `versionCode 41` for exactly this reason (fixed in #180) — the F-Droid publish failed outright and the GitHub release never got created. +2. Add the changelog for the **new versionCode** in both `distribution/changelogs/.txt` and `fastlane/metadata/android/en-US/changelogs/.txt` (F-Droid reads the fastlane copy), and update the **Play** release notes in `distribution/whatsnew/whatsnew-en-US` (single file, applied to the build being uploaded; **max 500 chars**). `whatsnew` — not the fastlane `changelogs/*.txt` — is what the Play publish uses (`whatsNewDirectory` in the workflow). `check:versions` enforces that the changelog named after the versionCode describes the version you are releasing. Merge to `main`. 3. Tag the release: `git tag -a vX.Y.Z -m "..." && git push origin vX.Y.Z`. This triggers the publish workflow → **production** track, `status: completed`. 4. Verify the publish run is green, and read the run summary — it records the event, resolved track/status, and the real Play `versionCode` (run_number+100, not the `app.json` number). -5. Nothing else to do. There is no second promotion step. +5. Check the other two channels, because Play is only one of three and the smaller share of the install base: the **GitHub release** exists with both APKs (`build.yml`'s `release` job — this is what the in-app update check polls via `releases/latest`), and the **F-Droid index** lists the new version (`https://dzianisv.github.io/opencode-mobile/fdroid/repo/index-v1.json`). +6. Nothing else to do. There is no second promotion step. ## Promoting to production diff --git a/docs/playstore.md b/docs/playstore.md index a2e8833d..a252bf7a 100644 --- a/docs/playstore.md +++ b/docs/playstore.md @@ -110,10 +110,11 @@ and it is never equal to `app.json`'s committed `android.versionCode`. ### Release history (production track) -| Version | Internal versionCode (tag push) | Production versionCode (dispatch) | Production rollout (UTC) | Notes | +| Version | Internal versionCode (tag push) | Production versionCode | Production rollout (UTC) | Notes | |---|---|---|---|---| -| v0.4.13 | 148 (run 48, cancelled) | **149** (run 49) | 2026-08-14 09:20 | waitlist retry queue (#166) | -| v0.4.14 | 150 (run 50) | **151** (run 51) | 2026-08-14 14:22 | Sentry client-side noise gate (#169) — post-deploy Sentry measurement window for AGE-105 starts at this date, not at merge | +| v0.4.13 | 148 (run 48, cancelled) | **149** (run 49, dispatch) | 2026-08-14 09:20 | waitlist retry queue (#166) | +| v0.4.14 | 150 (run 50) | **151** (run 51, dispatch) | 2026-08-14 14:22 | Sentry client-side noise gate (#169) — post-deploy Sentry measurement window for AGE-105 starts at this date, not at merge | +| v0.4.15 | — | **153** (run 53, **tag push**) | 2026-08-14 17:58 | In-app update check for non-Play installs (#179). First release to reach production **without a dispatch** — #177 verified in the wild: run [31824702844](https://github.com/dzianisv/opencode-mobile/actions/runs/31824702844) logged `event=push -> track=production status=completed`. Code 152 (run 52, 17:04) was the same version from the pre-#180 tag, superseded by 153 | ---