Unit Tests / test (pull_request) Successful in 14s
Closes #121. Supersedes the separate Deploy Android workflow in #58 by attaching hesychia-<version>-<code>.aab to an android-v* Gitea release after the prod web deploy.
143 lines
4.3 KiB
Markdown
143 lines
4.3 KiB
Markdown
# Hesychia — Android
|
||
|
||
Native Capacitor project for `ai.hesychia.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:android:store # Play binary: .env.mobile → build → cap sync android
|
||
# npm run build:mobile # same web env, also syncs iOS
|
||
```
|
||
|
||
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
|
||
|
||
`app/build.gradle` stores the floor (`hesychiaVersionNameFloor` / `hesychiaVersionCodeFloor`). A local `bundleRelease` uses that floor. **Deploy Prod** passes the next pair with `-PhesychiaVersionName` and `-PhesychiaVersionCode` after reading `android-v*` Gitea releases, so a prod run does not need a version commit.
|
||
|
||
| Field | Rule |
|
||
|-------|------|
|
||
| `versionName` | User-visible `major.minor.patch` |
|
||
| `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 /home/westfarn/.android/hesychia-upload.jks \
|
||
-keyalg RSA -keysize 2048 -validity 10000 \
|
||
-alias aiml-chat-upload
|
||
```
|
||
|
||
Reuse an existing Play upload key. Do not generate a second keystore for an app that already has one.
|
||
|
||
2. Create `keystore.properties` in **this** directory (`android/`, gitignored). On the Deploy Prod runner the file is `/home/westfarn/.android/hesychia-keystore.properties` (not RealPath’s `keystore.properties`):
|
||
|
||
```properties
|
||
storeFile=/home/westfarn/.android/hesychia-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
|
||
|
||
**Deploy Prod** builds the signed AAB and attaches it to a Gitea release (`android-v<versionName>-<versionCode>`, asset `hesychia-<versionName>-<versionCode>.aab`). Download that asset and upload it yourself. See [`../ANDROID.md`](../ANDROID.md).
|
||
|
||
1. [Play Console](https://play.google.com/console) → app **Hesychia** (`ai.hesychia.chat`).
|
||
2. Complete store listing: privacy policy URL, data-safety form, screenshots.
|
||
3. Set **Account deletion URL** to the public instructions page (no sign-in required):
|
||
- `https://hesychia.ai/account-deletion/` (preferred product host)
|
||
- or `https://chat.aimloperations.com/account-deletion/` until hesychia.ai cutover
|
||
4. **Testing → Internal testing** → create release → upload `app-release.aab`.
|
||
5. Add testers, roll out internal track, verify on devices.
|
||
6. Promote to closed / open / production only after internal QA passes.
|
||
|
||
See also [`../ANDROID.md`](../ANDROID.md) Play checklist and issue
|
||
[#103](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/103).
|
||
|
||
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 | `ai.hesychia.chat` |
|
||
| Display name | Hesychia |
|
||
| Min / target SDK | 23 / 35 (see `variables.gradle`) |
|