android: build the release APK with a debug-profile .so, for now
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m0s
Android / Kotlin + Rust (APK) (push) Failing after 4m24s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m29s
Desktop (Tauri) / Update manifest (push) Successful in 5s

`d0a9c73` switched the lane to a release Cargo profile alongside the release
variant. The variant was the point; the profile was mine, and it broke the build
(run 4077): `generateUniffiBindings` fails with "No UniFFI metadata found" on
the release `.so`.

The workspace release profile sets `strip = true`, and uniffi's `--library` mode
finds its interface metadata through symbols. That is the obvious suspect and it
is recorded as a suspect, not a finding — `lto = true` dropping the metadata
statics would print the identical message and the two have not been told apart.

Backed out to the debug profile rather than guessing at a fix, because the two
halves of that commit are not equally important. Signing and a rising
versionCode are what make an install replace the last one instead of wiping the
notes; the Rust profile only makes the result faster. The APK this produces is
no worse than every previous build, all of which shipped a debug-profile `.so`.

Recorded as Scribe #2810 with the four candidate fixes and, more usefully, the
instruction to establish the cause on a host build before spending another
four-minute cold cross-compile on a guess.
This commit is contained in:
2026-08-20 19:16:03 -04:00
parent d0a9c73bf9
commit cae9888eb9
2 changed files with 14 additions and 4 deletions
+6 -1
View File
@@ -91,7 +91,12 @@ jobs:
if [ -n "${ANDROID_KEYSTORE_BASE64:-}" ]; then
printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 -d > /tmp/thoughtsync-release.jks
echo "variant=Release" >> $GITHUB_OUTPUT
echo "profile=release" >> $GITHUB_OUTPUT
# DEBUG profile, in a release APK, deliberately — see the note above
# the cargoNdk task. The release profile strips the symbols uniffi
# reads its metadata out of, so `generateUniffiBindings` fails
# outright (run 4077). Unpicking that is worth doing and is not worth
# blocking signed builds on.
echo "profile=debug" >> $GITHUB_OUTPUT
echo "keystore=/tmp/thoughtsync-release.jks" >> $GITHUB_OUTPUT
echo "apk=android/app/build/outputs/apk/release/app-release.apk" >> $GITHUB_OUTPUT
echo "Signed release build — $version (versionCode $GITHUB_RUN_NUMBER)"
+8 -3
View File
@@ -131,9 +131,14 @@ val rustInputs =
* profiles. `android.yml` picks one profile and uses it for every Gradle call in
* the run.
*
* Defaults to debug so a local build stays fast; CI passes release, because an
* unoptimised store and sync engine is a real difference on a phone, not a
* theoretical one.
* CI currently passes `debug` even for a release APK, which is not where this
* should end up: an unoptimised store and sync engine is a real difference on a
* phone, not a theoretical one. The blocker is that the workspace's release
* profile sets `strip = true`, which removes the symbols uniffi reads its
* interface metadata from — `generateUniffiBindings` then fails with "No UniFFI
* metadata found" (run 4077). Fixing it means either an Android-specific profile
* that keeps symbols or generating the bindings from a separate unstripped
* build, and neither is worth holding signed APKs up for. Scribe #2810.
*/
val rustProfile =
(project.findProperty("THOUGHTSYNC_CARGO_PROFILE") as String?)?.takeIf { it.isNotBlank() }