fix(android): keep the debug applicationId out of Tauri's reach

`bun run android:dev` produced an APK whose applicationId was plain
com.dtourolle.jellytau, so installing it over a real release build failed
with INSTALL_FAILED_UPDATE_INCOMPATIBLE -- the only obvious way out being to
uninstall the release app and lose its data.

`tauri android build` rewrites the getByName("debug") block in the generated
copy of build.gradle.kts to inject its jniLibs.keepDebugSymbols entries. The
damage is visible in the generated file, where `packaging {` ends up with the
first injected line welded onto it. That rewrite drops applicationIdSuffix
and nothing else -- versionNameSuffix and the manifest placeholders beside it
survive -- and it happens after sync-android-sources.sh has copied the
canonical file into place and before Gradle configures, so no amount of
syncing beats it. The sideBySideRelease suffix in the release build type is
untouched by the same rewrite, which is why `build-and-deploy.sh release
--debug` kept working while the plain debug path did not.

The suffix moves to a top-level statement after the android {} block, which
is not inside what the rewriter looks for and survives. build-android.sh then
asserts the applicationId the APK actually carries, read from AGP's
output-metadata.json, so a future CLI that reaches further fails the build
instead of shipping a colliding APK.

Verified: a debug build now reports com.dtourolle.jellytau.debug, and the
statement is still there in gen/ after the CLI has run.
This commit is contained in:
2026-08-25 23:48:24 +02:00
parent bbccc8567c
commit 1ba836928f
2 changed files with 65 additions and 1 deletions
+38
View File
@@ -128,6 +128,44 @@ else
bun run tauri android build --apk --debug "${TARGET_ARGS[@]}"
fi
# The applicationId the APK actually carries — not the one build.gradle.kts asks
# for. `tauri android build` rewrites the debug `buildTypes` block in the
# generated gradle file to inject its keepDebugSymbols entries, and that rewrite
# used to drop `applicationIdSuffix` with it, silently producing a debug APK
# under the release applicationId. Installing that over a real release build
# fails with INSTALL_FAILED_UPDATE_INCOMPATIBLE, whose only obvious remedy is
# uninstalling the release app and losing its data — so this fails the build
# instead. The suffix now lives outside the rewritten block (see
# src-tauri/android/app/build.gradle.kts); this checks that it survived.
assert_application_id() {
local variant="$1" expected="$2"
local metadata="src-tauri/gen/android/app/build/outputs/apk/universal/$variant/output-metadata.json"
[ -f "$metadata" ] || return 0
local actual
actual=$(sed -n 's/.*"applicationId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$metadata" | head -1)
if [ -n "$actual" ] && [ "$actual" != "$expected" ]; then
echo ""
echo "❌ APK applicationId is '$actual', expected '$expected'."
echo " A build meant for the side-by-side slot came out under the"
echo " release applicationId; installing it would collide with a real"
echo " install. Check that the applicationIdSuffix at the bottom of"
echo " src-tauri/android/app/build.gradle.kts survived into"
echo " src-tauri/gen/android/app/build.gradle.kts."
exit 1
fi
}
if [ "$BUILD_TYPE" = "debug" ]; then
assert_application_id debug "com.dtourolle.jellytau.debug"
elif [ "$SIDE_BY_SIDE" = "1" ]; then
assert_application_id release "com.dtourolle.jellytau.debug"
else
assert_application_id release "com.dtourolle.jellytau"
fi
echo ""
echo "✅ APK build complete!"
echo "📱 APK location: src-tauri/gen/android/app/build/outputs/apk/"