From 34d27f4f10644f06a40f6cc728b016a95a684162 Mon Sep 17 00:00:00 2001 From: Ryan Westfall Date: Sun, 26 Jul 2026 18:28:41 -0500 Subject: [PATCH] Add android/ README with build and Play deploy steps Document sync, debug/release Gradle builds, signing, and internal-testing upload so the native project folder is self-contained for release work. --- llm-fe/ANDROID.md | 2 + llm-fe/android/README.md | 131 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 llm-fe/android/README.md diff --git a/llm-fe/ANDROID.md b/llm-fe/ANDROID.md index 8dfd175..00b15ed 100644 --- a/llm-fe/ANDROID.md +++ b/llm-fe/ANDROID.md @@ -3,6 +3,8 @@ Ship the CRA web build as an Android app via [Capacitor](https://capacitorjs.com/). One codebase: `llm-fe/` → web + Android WebView. +**Build & Play deploy steps:** [`android/README.md`](android/README.md). + Prerequisites for blockers already merged: JWT-only auth (#22), WebSocket lifecycle (#23), HashRouter (#24). ## Prerequisites diff --git a/llm-fe/android/README.md b/llm-fe/android/README.md new file mode 100644 index 0000000..9dc671a --- /dev/null +++ b/llm-fe/android/README.md @@ -0,0 +1,131 @@ +# AI ML Chat — Android + +Native Capacitor project for `com.aimloperations.chat`. Web UI comes from the CRA +`build/` output in the parent `llm-fe/` package (synced with `npx cap sync`). + +Broader Capacitor notes (env files, icons, QA): [`../ANDROID.md`](../ANDROID.md). + +## Prerequisites + +- Node.js **20** +- JDK **17+** +- [Android Studio](https://developer.android.com/studio) with SDK Platform **35** +- `ANDROID_HOME` set, or open this folder once in Android Studio (writes `local.properties`) + +## Build the web bundle and sync + +From the **npm root** (`llm-fe/`, one level up): + +```bash +cd .. +npm ci +npm run build:mobile # .env.mobile → react-scripts build → cap sync android +``` + +Open this project in Android Studio: + +```bash +npm run android:open +# or: npx cap open android +``` + +Re-sync after changing web code (with an existing `build/`): + +```bash +npm run android:sync +``` + +Backend URLs are baked in at web-build time via `../.env.mobile` (prod by default). + +## Run on a device / emulator + +### Android Studio + +1. Sync Gradle when prompted. +2. Pick an emulator or USB device (enable USB debugging). +3. Run **app**. + +### CLI (debug APK) + +```bash +./gradlew assembleDebug +adb install -r app/build/outputs/apk/debug/app-debug.apk +``` + +## Version before a store release + +Edit `app/build.gradle` → `defaultConfig`: + +| Field | Rule | +|-------|------| +| `versionName` | User-visible string; keep in sync with `../package.json` `version` | +| `versionCode` | Integer; **must increase** for every Play upload | + +## Sign a release build + +**Do not commit keystores or passwords.** + +1. Create an upload keystore (once), outside the repo: + +```bash +keytool -genkey -v -keystore ~/Documents/secrets/aiml-chat-upload.jks \ + -keyalg RSA -keysize 2048 -validity 10000 \ + -alias aiml-chat-upload +``` + +2. Create `keystore.properties` in **this** directory (`android/`, gitignored): + +```properties +storeFile=/absolute/path/to/aiml-chat-upload.jks +storePassword=REPLACE_ME +keyAlias=aiml-chat-upload +keyPassword=REPLACE_ME +``` + +3. Build a signed App Bundle: + +```bash +./gradlew bundleRelease +``` + +Output: + +```text +app/build/outputs/bundle/release/app-release.aab +``` + +Signed APK (if needed): + +```bash +./gradlew assembleRelease +# → app/build/outputs/apk/release/app-release.apk +``` + +Without `keystore.properties`, release builds are unsigned; debug builds do not need it. + +## Deploy to Google Play + +1. [Play Console](https://play.google.com/console) → app **AI ML Chat** (`com.aimloperations.chat`). +2. Complete store listing: privacy policy URL, data-safety form, screenshots. +3. **Testing → Internal testing** → create release → upload `app-release.aab`. +4. Add testers, roll out internal track, verify on devices. +5. Promote to closed / open / production only after internal QA passes. + +Each new upload needs a higher `versionCode`. + +## Useful Gradle tasks + +| Task | Purpose | +|------|---------| +| `./gradlew assembleDebug` | Debug APK | +| `./gradlew assembleRelease` | Release APK (signed if props present) | +| `./gradlew bundleRelease` | Play Store `.aab` | +| `./gradlew clean` | Clean build outputs | + +## App identity + +| | | +|--|--| +| Application ID | `com.aimloperations.chat` | +| Display name | AI ML Chat | +| Min / target SDK | 23 / 35 (see `variables.gradle`) |