Compare commits
1 Commits
8322e8318c
...
docs/andro
| Author | SHA1 | Date | |
|---|---|---|---|
| cbaa18ea0b |
@@ -1,6 +1,6 @@
|
||||
# Android App — Plan
|
||||
|
||||
Status: **M0–M6 landed; the functional build, design pass, and release mechanics are complete (cut the v1 tag, then M7 push notifications).** This document is the
|
||||
Status: **M0–M6 landed; the functional build, design pass, and release mechanics are complete (the auto-release engine cuts a tagged, signed APK on merge to `main`; M7 push notifications next).** This document is the
|
||||
design contract for the `RunicGateway/Android-app` repo. It was written before implementation so the
|
||||
API changes it depends on could be landed in `website/` and `docs/` first. The authoritative API
|
||||
reference is the committed OpenAPI spec at `website/server/swagger/swagger-output.json` (regenerated
|
||||
@@ -128,15 +128,22 @@ probe refuses a backend whose API version this build can't speak (a future `v2`)
|
||||
signed release) with keep-rules for the kotlinx.serialization serializers, the wire DTOs, and the
|
||||
Retrofit interfaces; a release `signingConfig` that reads keystore material from a **gitignored**
|
||||
`keystore.properties` or env vars (absent → unsigned; the keystore is never committed); and
|
||||
`versionName`/`versionCode` overridable via `-P` so a release tag + CI run number drive them (§10).
|
||||
**CI `release.yml`** — on a `v*` tag, builds a **signed** APK (keystore decoded from a base64 Gitea
|
||||
secret) and attaches it + `SHA256SUMS` to a Gitea release; `workflow_dispatch` is a signing dry run.
|
||||
`versionName` is the committed source of truth (bumped by the release engine); `versionCode` is derived
|
||||
from it (`major*10000+minor*100+patch`, monotonic); both stay `-P`-overridable for local builds (§10).
|
||||
**CI `release.yml`** — mirrors `link/`'s language-agnostic release engine, adapted for Android: on every
|
||||
push to `main` it derives the next version from conventional-commit subjects since the last `v*` tag
|
||||
(`feat!`/BREAKING → major, `feat` → minor, `fix`/`perf` → patch; nothing releasable → no release),
|
||||
generates a grouped changelog, bumps `build.gradle.kts`, builds the **signed** APK (keystore decoded from
|
||||
a base64 Gitea secret), then commits the bump `[skip ci]`, tags `vX.Y.Z`, and creates the Gitea release
|
||||
with notes + APK + `SHA256SUMS`. Uses `REGISTRY_USER`/`REGISTRY_TOKEN` (as `link/` does) to push the bump
|
||||
and create the release, so `main` must allow that account to push.
|
||||
HTTPS-only in release (M1), no token logging (logging is debug-gated, M3), and the Settings → Server
|
||||
hard reset (M3) were already in place. Biometric app-lock is **descoped from v1** (see the note below).
|
||||
|
||||
**The functional build (M0–M4), design pass (M5), and release mechanics (M6) are complete. Cutting
|
||||
the first `v*` release tag (once the signing secrets are set + the on-device QA pass is done) and M7
|
||||
push notifications are what remain.**
|
||||
**The functional build (M0–M4), design pass (M5), and release mechanics (M6) are complete. The first
|
||||
signed release now cuts automatically on the next release-worthy merge to `main` — once the signing +
|
||||
`REGISTRY_*` secrets are set, `main` allows the CI account to push, and the on-device QA pass is done.
|
||||
M7 push notifications are what remain.**
|
||||
|
||||
**Prerequisite progress (§8):** all v1 prerequisites are **done** (2026-07-19) — ✅ password reset
|
||||
(item 2; website#75 + docs#8), ✅ role-agnostic `/auth/me/*` self surface (item 1; website#76 + docs#10),
|
||||
@@ -506,7 +513,8 @@ push, and Play (M6–M8) follow the designed app.
|
||||
7. **M6 — Polish & release mechanics**: settings (server switch = hard reset, done M3),
|
||||
version-mismatch guard, release build hardening (HTTPS-only, no token logging, R8 minify + resource
|
||||
shrink, release signing). No offline cache in v1 (§7). **Ships v1 as a signed APK attached to a Gitea
|
||||
release** via `release.yml` on a `v*` tag (see §10). Biometric app-lock **descoped** (below).
|
||||
release** via `release.yml`'s conventional-commit engine on merge to `main` (see §10, §12).
|
||||
Biometric app-lock **descoped** (below).
|
||||
**Landed** 2026-07-20 (`RunicGateway/Android-app#11`).
|
||||
8. **M7 — Push notifications** (post-v1): add the self-hosted `ntfy` service to
|
||||
`website/docker-compose.yml` (declarative, zero-interaction config), UnifiedPush integration in the
|
||||
@@ -607,11 +615,16 @@ repos use), on a bare `ubuntu:latest` container.
|
||||
frequent: run the job under a prebuilt Android-SDK `container:` image so nothing installs per-run.)
|
||||
- **PR gate** (`.gitea/workflows/pr-checks.yml`, on PR → `main`): `./gradlew lint test assembleDebug`.
|
||||
Debug builds are auto-signed, so the gate needs no secrets. Mirrors `website/`'s pre-merge gate.
|
||||
- **Release** (`.gitea/workflows/release.yml`, M6+): build a **signed release APK** and attach it to a
|
||||
Gitea release (mirrors `link/`'s release job). The **keystore is a base64 Gitea Actions secret**
|
||||
decoded in CI; store/key passwords are secrets. The keystore never lives in the repo. Keep the
|
||||
signing identity stable from the first release (Play later requires consistency).
|
||||
- Semantic `versionName` + monotonic `versionCode`; tag releases.
|
||||
- **Release** (`.gitea/workflows/release.yml`, M6): mirrors `link/`'s release engine — on every push to
|
||||
`main` it computes the next version from conventional commits since the last `v*` tag, generates a
|
||||
changelog, bumps `build.gradle.kts`, builds a **signed release APK**, commits the bump `[skip ci]`,
|
||||
tags `vX.Y.Z`, and creates the Gitea release with the notes + APK + `SHA256SUMS`. The **keystore is a
|
||||
base64 Gitea Actions secret** decoded in CI (`ANDROID_KEYSTORE_BASE64`); store/key passwords + alias
|
||||
are secrets too. The keystore never lives in the repo. `REGISTRY_USER`/`REGISTRY_TOKEN`
|
||||
(`write:repository`) push the bump + create the release, so `main` must allow that account to push.
|
||||
Keep the signing identity stable from the first release (Play later requires consistency).
|
||||
- Semantic `versionName` (bumped by the engine) + derived monotonic `versionCode`
|
||||
(`major*10000+minor*100+patch`); the engine tags each release.
|
||||
|
||||
## 13. Open questions (revisit as we go)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user