Four gaps that made "ship it" and "test it on hardware" impossible. RELEASE SIGNING. assembleRelease was silently producing app-release-unsigned.apk because there was no signingConfigs block at all — the failure mode where you only notice at install time. Credentials now resolve from keystore.properties, then local.properties, then WEBTERM_RELEASE_* env; nothing is created or committed, and keystore.properties.example is the template. The degradation is ENFORCED, not documented. The signingConfig is only created when credentials actually resolve — an empty config is precisely what makes AGP emit an unsigned artifact quietly — and a guard on packageRelease throws with an actionable message, distinguishing "not configured" from "credentials found but the keystore file is missing: <path>". It hooks the PACKAGE task on purpose: R8 has already run and reported by then, so a developer without a keystore still gets the full shrink result rather than an early abort. Verified: minifyReleaseWithR8 completes, packageRelease fails loudly, and no unsigned APK is written. VERSIONING. Was still the scaffold 1 / "0.1.0". Now 1 / "0.1.0-alpha01", where the suffix is a factual claim about device verification rather than decoration: alpha means device QA is essentially unstarted, beta means the A34/A35 checklist blocks pass on hardware, and plain 0.1.0 means the whole checklist is ticked. versionCode stays 1 because no artifact has ever left the build machine. MINIFICATION. release had isMinifyEnabled = false and an empty rules file — so nothing had ever exercised R8 on this app, and the first release build would have been the experiment. Now minify + resource shrinking, with a deliberately short rules file: the actual artifacts were checked, and kotlinx.serialization, Tink, Hilt, FCM, OkHttp, Compose and CameraX all ship their own consumer rules, so none are re-declared. The termux packages are kept whole because the JitPack artifacts ship no rules and :terminal-view binds to non-API internals — it writes the public TerminalView.mEmulator field and calls TerminalRenderer.getFontWidth()/getFontLineSpacing(). Getting that wrong yields a build that crashes only in production. lintVitalRelease also passes now, the two pre-existing lint ERRORS having been fixed earlier this session. ANDROID TEST ENABLEMENT. :app had no androidTest source set and no instrumentation runner, which is the mechanical reason A34/A35 have no code at all. The runner (Hilt-aware) and dependencies are wired, and a :macrobenchmark module exists. The tests themselves are a separate change. Verified: ./gradlew test :app:assembleDebug :app:assembleDebugAndroidTest :app:assembleBenchmark :macrobenchmark:assembleBenchmark :app:lintVitalRelease koverVerify -> BUILD SUCCESSFUL; 901 JVM tests, 0 failures on a forced re-execution with test-results deleted and --no-build-cache.
32 lines
1.5 KiB
Plaintext
32 lines
1.5 KiB
Plaintext
# TEMPLATE ONLY — copy to `keystore.properties` and fill in. NEVER commit the copy.
|
|
#
|
|
# cp keystore.properties.example keystore.properties
|
|
#
|
|
# BEFORE you create the real file, make sure `keystore.properties` is listed in
|
|
# android/.gitignore. If it is not there yet, use `local.properties` instead — that
|
|
# path is ALREADY gitignored and :app reads the same four keys from it.
|
|
#
|
|
# Resolution order in app/build.gradle.kts (first non-blank wins):
|
|
# 1. android/keystore.properties
|
|
# 2. android/local.properties
|
|
# 3. WEBTERM_RELEASE_STORE_FILE / _STORE_PASSWORD / _KEY_ALIAS / _KEY_PASSWORD (CI)
|
|
#
|
|
# With none of them set, debug + benchmark builds work normally and
|
|
# `:app:assembleRelease` FAILS at packaging with instructions — it never emits an
|
|
# unsigned APK.
|
|
#
|
|
# Generate a keystore OUTSIDE the repository:
|
|
# keytool -genkeypair -v -keystore ~/.webterm/webterm-release.jks \
|
|
# -alias webterm -keyalg RSA -keysize 4096 -validity 10000
|
|
#
|
|
# Then read its SHA-256 (needed for the App Links assetlinks.json — plan §8):
|
|
# keytool -list -v -keystore ~/.webterm/webterm-release.jks -alias webterm | grep SHA256
|
|
|
|
# Path to the keystore. Absolute, or relative to the `android/` directory.
|
|
# Keep the keystore itself out of the repo (android/.gitignore blocks *.jks / *.keystore,
|
|
# but out-of-tree is the safer habit — a lost signing key cannot be recovered).
|
|
webterm.release.storeFile=/absolute/path/to/webterm-release.jks
|
|
webterm.release.storePassword=CHANGE_ME
|
|
webterm.release.keyAlias=webterm
|
|
webterm.release.keyPassword=CHANGE_ME
|