Files
web-terminal/android/keystore.properties.example
Yaojia Wang c1612d0145 build(android): make release buildable and instrumented testing possible
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.
2026-07-30 12:14:53 +02:00

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