From 0018edff26eb9e10bbfc7a3070412d2fd236f673 Mon Sep 17 00:00:00 2001 From: fy59 Date: Thu, 17 Sep 2026 15:56:47 +0200 Subject: [PATCH] fix(android): preserve rollout update chain --- CHANGELOG.md | 4 ++++ android/app/build.gradle.kts | 12 +++++++++++- docs/sync_rollout_readiness.md | 5 ++++- docs/tests.md | 5 +++++ tools/build_android_backup_bridge.py | 4 ++-- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a81ce12..b852084 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ candidate so user services cannot mix a versioned install with live-checkout helpers during rollout. +- Added a bounded Android package-version override and made the schema-v17 + backup bridge produce a signed release APK, allowing a strictly increasing + private update chain without changing Trainlog schemas or protocols. + - Closed the native candidate warning gate with checked path and HTTP response bounds, strict GCC and Clang builds, full Clang ASan/UBSan validation, and a stable concurrent object-I/O MTP double. Rebuilt the desktop, current Android diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index e58cdc9..67858cd 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -35,6 +35,16 @@ val releaseSigningComplete = listOf( releaseKeyPassword, ).all { !it.isNullOrBlank() } +/* CONTRACT: a private rollout may need an update-only version code above the + * repository default while preserving versionName, schemas and protocols. + * INVARIANT: the override remains a positive Android package version code and + * never changes the source default used by ordinary builds. */ +val trainlogVersionCode = + providers.environmentVariable("TRAINLOG_ANDROID_VERSION_CODE").orNull?.let { raw -> + raw.toIntOrNull()?.takeIf { it in 1..Int.MAX_VALUE } + ?: throw GradleException("TRAINLOG_ANDROID_VERSION_CODE must be a positive integer") + } ?: 3 + android { namespace = "com.labfytools.trainlog" compileSdk = 37 @@ -44,7 +54,7 @@ android { minSdk = 26 targetSdk = 36 - versionCode = 3 + versionCode = trainlogVersionCode versionName = "0.1.2" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/docs/sync_rollout_readiness.md b/docs/sync_rollout_readiness.md index eb1bc6b..3651dba 100644 --- a/docs/sync_rollout_readiness.md +++ b/docs/sync_rollout_readiness.md @@ -28,7 +28,10 @@ the separately authorized rollout are complete. must not combine a packaged binary with helpers from a live checkout. 2. `assembleDebug` is development evidence only. Rollout requires the existing release signing identity, verification of its public certificate and a valid - increasing `versionCode`; this mission reads no signing secret. + increasing `versionCode`. A bounded `TRAINLOG_ANDROID_VERSION_CODE` build + override may establish an update-only private rollout chain without changing + the product version, schema or protocol. The bridge recipe also produces a + signed release variant for installation; debug APKs remain test evidence. 3. Quiesce old writers only during an authorized rollout. Desktop backup uses `backup_trainlog_sqlite.py` and SQLite's backup API, then integrity and foreign-key checks. diff --git a/docs/tests.md b/docs/tests.md index 691605b..8dea9f5 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -523,6 +523,11 @@ canonical stable Android artifact. Release assets must come from the exact tagged source state, and the tag, Android `versionName`, Meson project version, TUI product version, asset names, and release title must agree. +Private update rollout may set `TRAINLOG_ANDROID_VERSION_CODE` to a positive +integer while keeping `versionName=0.1.2`. This build-only override is used only +to maintain a strictly increasing installed → backup bridge → current APK +chain; it does not change any schema or exchange-format version. + ```bash meson setup --reconfigure build meson compile -C build diff --git a/tools/build_android_backup_bridge.py b/tools/build_android_backup_bridge.py index 27ec2b6..c7481e6 100644 --- a/tools/build_android_backup_bridge.py +++ b/tools/build_android_backup_bridge.py @@ -79,7 +79,7 @@ def main(): ":app:testDebugUnitTest", "--tests", "com.labfytools.trainlog.data.BackupBridgeServiceTest", - ":app:assembleDebug", + ":app:assembleRelease", ], cwd=android, env=env, @@ -105,7 +105,7 @@ def main(): print( f"BRIDGE_RECIPE={subprocess.check_output(['git','rev-parse','HEAD'],cwd=ROOT,text=True).strip()}" ) - print(f"BRIDGE_APK={android/'app/build/outputs/apk/debug/app-debug.apk'}") + print(f"BRIDGE_APK={android/'app/build/outputs/apk/release/app-release.apk'}") if __name__ == "__main__":