feat(android): manual signed-APK CI workflow

Add .gitea/workflows/android-build.yaml (workflow_dispatch + confirm=build,
master-only; mirrors prod-deploy): builds the native SPA, bundles the offline
dicts, assembles a release APK as a run artifact. JDK 21 via setup-java; the
Android SDK is host-provisioned (host-executor runner) with a fail-fast verify
that also checks the runner user's access. Signing degrades gracefully — no
keystore => unsigned release APK, not a failure.

Wire ui/android/app/build.gradle: versionCode/versionName from the release tag
(-P props; '=' assignment, not the command form that binds .toInteger() to the
DSL setter's null return), plus a guarded signingConfigs.release from env.

Rename VITE_STORE_URL -> VITE_RUSTORE_URL (empty until publish).

Bake the E as-built into ANDROID_PLAN.md.
This commit is contained in:
Ilia Denisov
2026-07-12 20:27:07 +02:00
parent e7cb60c996
commit ca2c6487cf
5 changed files with 257 additions and 18 deletions
+3 -2
View File
@@ -7,8 +7,9 @@ interface ImportMetaEnv {
readonly VITE_GATEWAY_URL?: string;
/** "1" hides the in-app-currency purchase actions in the thin native MVP that defers store billing. */
readonly VITE_PAYMENTS_DISABLED?: string;
/** Store listing URL the native update overlay opens for its "update" action (e.g. the RuStore page). */
readonly VITE_STORE_URL?: string;
/** RuStore listing URL the native update overlay opens for its "update" action. Empty until the app
* is published (the button then no-ops); the version gate is dormant in the MVP so it never fires yet. */
readonly VITE_RUSTORE_URL?: string;
/** Bundled-dictionary version the native offline path requests; matches the packaged DAWG files. */
readonly VITE_DICT_VERSION?: string;
}