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.
This commit is contained in:
1 parent
36341f6e72
commit
0d233b077c
8 files changed
+542
-18
No files matched your search
@@ -19,7 +19,8 @@ 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
|
||||
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:
|
||||
@@ -54,11 +55,11 @@ adb install -r app/build/outputs/apk/debug/app-debug.apk
|
||||
|
||||
## Version before a store release
|
||||
|
||||
Edit `app/build.gradle` → `defaultConfig`:
|
||||
`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 string; keep in sync with `../package.json` `version` |
|
||||
| `versionName` | User-visible `major.minor.patch` |
|
||||
| `versionCode` | Integer; **must increase** for every Play upload |
|
||||
|
||||
## Sign a release build
|
||||
@@ -68,15 +69,17 @@ Edit `app/build.gradle` → `defaultConfig`:
|
||||
1. Create an upload keystore (once), outside the repo:
|
||||
|
||||
```bash
|
||||
keytool -genkey -v -keystore ~/Documents/secrets/aiml-chat-upload.jks \
|
||||
keytool -genkey -v -keystore /home/westfarn/.android/hesychia-upload.jks \
|
||||
-keyalg RSA -keysize 2048 -validity 10000 \
|
||||
-alias aiml-chat-upload
|
||||
```
|
||||
|
||||
2. Create `keystore.properties` in **this** directory (`android/`, gitignored):
|
||||
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=/absolute/path/to/aiml-chat-upload.jks
|
||||
storeFile=/home/westfarn/.android/hesychia-upload.jks
|
||||
storePassword=REPLACE_ME
|
||||
keyAlias=aiml-chat-upload
|
||||
keyPassword=REPLACE_ME
|
||||
@@ -105,6 +108,8 @@ Without `keystore.properties`, release builds are unsigned; debug builds do not
|
||||
|
||||
## 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):
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
// Last bundle recorded in git. Prod deploy passes -PhesychiaVersionCode and
|
||||
// -PhesychiaVersionName; these stay the floor when those properties are absent.
|
||||
def hesychiaVersionCodeFloor = 1
|
||||
def hesychiaVersionNameFloor = "0.1.0"
|
||||
|
||||
// Resolve before the android block. A parenthesized expression on the versionCode
|
||||
// setter is parsed as a cast of the setter result, so AGP throws "Value is null".
|
||||
def hesychiaVersionCodeProp = project.findProperty('hesychiaVersionCode')?.toString()?.trim()
|
||||
def hesychiaVersionNameProp = project.findProperty('hesychiaVersionName')?.toString()?.trim()
|
||||
def resolvedVersionCode = hesychiaVersionCodeProp ? hesychiaVersionCodeProp.toInteger() : hesychiaVersionCodeFloor
|
||||
def resolvedVersionName = hesychiaVersionNameProp ? hesychiaVersionNameProp : hesychiaVersionNameFloor
|
||||
|
||||
def keystorePropertiesFile = rootProject.file('keystore.properties')
|
||||
def keystoreProperties = new Properties()
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
@@ -13,8 +25,8 @@ android {
|
||||
applicationId "ai.hesychia.chat"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "0.1.0"
|
||||
versionCode resolvedVersionCode
|
||||
versionName resolvedVersionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
@@ -27,7 +39,7 @@ android {
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user