Merge pull request 'android: ANDROID_PLAN refresh + pin build-tools 36 (unblocks the release build)' (#269) from feature/android-plan-refresh into development
CI / changes (push) Successful in 2s
CI / unit (push) Has been skipped
CI / integration (push) Has been skipped
CI / ui (push) Successful in 1m15s
CI / conformance (push) Successful in 10s
CI / gate (push) Successful in 0s
CI / deploy (push) Successful in 1m57s

This commit was merged in pull request #269.
This commit is contained in:
2026-07-14 19:38:13 +00:00
2 changed files with 39 additions and 17 deletions
+28 -17
View File
@@ -62,19 +62,20 @@ client-only (no server change).
Kept current as parts land so a fresh session resumes without re-deriving. Verify against code.
> ### ▶ RESUME HERE — 2026-07-13 (documents track + release-prep)
> ### ▶ RESUME HERE — 2026-07-14 (keystore secrets set; payments landed; gate = RuStore account + merge/tag)
>
> **Where we are.** The legal-documents track, the release-prep hygiene, **and the icon rebrand** are
> DONE. The RuStore release is now gated on **owner-side** items only (keystore, RuStore account) plus
> the merge/tag chain. Do not re-do or re-litigate the finished work; do not re-ask the locked decisions.
> **Where we are.** The legal-documents track, the release-prep hygiene, the icon rebrand **and the
> release keystore** are DONE (the keystore + its Gitea secrets set by the owner — see below). The
> RuStore MVP is now gated on **one owner-side item** — the **RuStore developer account** (owner going
> ИП; RuStore updated its requirements) — plus the agent's **promote/tag → signed-build** chain. Also
> landed on `development` since: the payments **E10 multi-shop split** (#266) + **E11 kill switch**
> (#267), both dormant / fail-open (no bearing on the Android build), and the signing-secret rename
> `ANDROID_*` → **`ANDROID_RUSTORE_*`** (#268). Do not re-do the finished work or re-ask the locked
> decisions.
>
> **Branches / PRs (current working branch: `feature/android-release-prep`).**
> - `development` — has the **legal-documents track**, merged via **PR #253** (green, deployed to the
> test contour). `/privacy/`, `/eula/`, `/offer/` are live there, bilingual RU/EN.
> - `feature/android-release-prep` — the **release-prep hygiene**, **PR #254 OPEN, green, NOT merged**
> (the owner chose to hold the merge). It is branched off `development`, so it also contains the
> legal-documents track. Merge #254 into `development` when ready — needs **owner approval** (the
> agent cannot self-approve).
> **Branches / PRs.** All merged to `development` (contour-green): legal documents (#253); release-prep
> hygiene + the re-enabled `android-build` workflow (#254); the payments E10/E11 (#266/#267); the
> signing-secret rename (#268). No open Android branch.
>
> **Done this session.**
> - **Legal documents** (satisfies the RuStore *hosted privacy-policy URL* prerequisite): authored
@@ -113,12 +114,12 @@ Kept current as parts land so a fresh session resumes without re-deriving. Verif
> 2. **Merge PR #254** → `development` (owner approval), then **promote `development` → `master`** and
> **tag `vX.Y.Z`** for the release (the version stamps the APK `versionName`/`versionCode` and the
> `X-Client-Version` header).
> 3. **Release keystore.** OWNER generates it (`keytool -genkeypair -v -keystore erudit-release.jks
> -alias erudit -keyalg RSA -keysize 4096 -validity 10000`), base64-encodes it, sets the four Gitea
> **secrets** `ANDROID_KEYSTORE_BASE64` / `ANDROID_KEYSTORE_PASSWORD` / `ANDROID_KEY_ALIAS` /
> `ANDROID_KEY_PASSWORD`, and backs the `.jks` up **off-host** (loss ⇒ the app can never be updated).
> The AGENT provides the exact commands on request. Without the secrets the workflow builds an
> UNSIGNED APK (a dry run still proves the pipeline).
> 3. **Release keystore — DONE (owner, 2026-07-14).** `erudit-release.jks` (RSA 4096, alias `erudit`,
> PKCS12) generated + backed up off-host; the four Gitea secrets are set under the RuStore-specific
> names `ANDROID_RUSTORE_KEYSTORE_BASE64` / `ANDROID_RUSTORE_KEYSTORE_PASSWORD` /
> `ANDROID_RUSTORE_KEY_ALIAS` / `ANDROID_RUSTORE_KEY_PASSWORD` (loss ⇒ the app can never be updated
> the cert is pinned at the first RuStore upload). Google Play, later, would use its own
> `ANDROID_PLAY_*` upload key (Play App Signing) — a separate key.
> 4. **RuStore developer account.** OWNER (verified legal entity or self-employed / самозанятый). Gates
> publication, not the build.
> 5. **Dispatch the signed build.** AGENT: on `master`, dispatch `android-build` (`confirm=build`) via
@@ -132,6 +133,16 @@ Kept current as parts land so a fresh session resumes without re-deriving. Verif
> 8. **Upload to RuStore.** OWNER. After publication, set the `ANDROID_RUSTORE_URL` Gitea variable to
> the store deep-link so the update button works on future gated releases (empty until then — the
> gate is dormant in the MVP).
>
> **Next tracks (design in a future session — interview the owner first).**
> - **Native notifications (push).** Promote FCM/push from "Out of scope" to a real track: a Capacitor
> push plugin, the Android send path (FCM — but **check RuStore's own push service vs FCM on RuStore
> devices**, since Google Play Services may be absent), token registration, and reusing the existing
> server notification dispatcher. Owner will bring specifics.
> - **A test APK for the emulator** (owner asked): the signed APK comes from `android-build` (needs the
> promote/tag chain, step 2). A quick **debug** APK is buildable without the release chain if the host
> has the Android SDK + JDK 21 (`pnpm build` → `cap sync` → `assembleDebug`).
> - Possibly other native polish (owner to flag).
- **A. Capacitor scaffolding — ✅ DONE & verified (2026-07-12).** Capacitor 8 native project generated
under `ui/android/` (tracked), `@capacitor/*` deps + `capacitor.config.ts`, hardware Back in
+11
View File
@@ -24,6 +24,17 @@ allprojects {
}
}
// Pin build-tools to the compileSdk-matching version for every Android module (the app + the
// Capacitor modules regenerated by `cap sync`), so AGP does not fall back to its default (35.0.0),
// which the provisioned / read-only CI SDK does not have installed.
subprojects {
afterEvaluate {
if (project.hasProperty('android')) {
android.buildToolsVersion = "36.0.0"
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}