The phone client is Tauri v2 mobile (operator decision), so it reuses the Vue frontend and the Rust store and sync engine that already exist rather than becoming a third implementation to keep in step by hand. gen/android is committed. tauri android init generated it, its own .gitignore already excludes the build outputs and every keystore file, and CI must not have to regenerate a project that manifest edits will accumulate in. What the scaffold confirms is that the image's JDK pin was load-bearing rather than incidental: Tauri templated Gradle 8.14.3 with AGP 8.11.0, and CI-android's versions.env records that JDK 25 needs Gradle 9.1.0+ and that anything older fails with an opaque "25.0.3" message. Picking 17 for ci-tauri-android avoided exactly that. namespace and applicationId came out as com.fabledsword.thoughtsync, matching the desktop identifier, so the app-data story stays consistent. The lane builds a DEBUG APK for arm64 only. Release APKs need signing, and the keystore has to be generated by the operator and never pass through CI logs or an agent session — the constraint recorded for the updater key applies unchanged. Gradle's throwaway debug keystore needs nothing from anyone, so this can prove the app compiles and packages today and grow a signed job when a key exists. arm64 is every real device; the image carries the other three ABIs, so widening is a word. Triggered by frontend/** as well as desktop/**, because generate_context! compiles the frontend into the app — the same reasoning that widened desktop.yml. Android, desktop and web are peers on one quality bar, and a frontend commit that skipped this lane would ship a stale phone build. Green here will mean it BUILT. A Linux runner cannot execute an APK, so nothing in this lane proves the app runs, renders, or is usable by finger. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
71 lines
2.2 KiB
Kotlin
71 lines
2.2 KiB
Kotlin
import java.util.Properties
|
|
|
|
plugins {
|
|
id("com.android.application")
|
|
id("org.jetbrains.kotlin.android")
|
|
id("rust")
|
|
}
|
|
|
|
val tauriProperties = Properties().apply {
|
|
val propFile = file("tauri.properties")
|
|
if (propFile.exists()) {
|
|
propFile.inputStream().use { load(it) }
|
|
}
|
|
}
|
|
|
|
android {
|
|
compileSdk = 36
|
|
namespace = "com.fabledsword.thoughtsync"
|
|
defaultConfig {
|
|
manifestPlaceholders["usesCleartextTraffic"] = "false"
|
|
applicationId = "com.fabledsword.thoughtsync"
|
|
minSdk = 24
|
|
targetSdk = 36
|
|
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
|
|
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
|
|
}
|
|
buildTypes {
|
|
getByName("debug") {
|
|
manifestPlaceholders["usesCleartextTraffic"] = "true"
|
|
isDebuggable = true
|
|
isJniDebuggable = true
|
|
isMinifyEnabled = false
|
|
packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
|
|
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
|
|
jniLibs.keepDebugSymbols.add("*/x86/*.so")
|
|
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
|
|
}
|
|
}
|
|
getByName("release") {
|
|
isMinifyEnabled = true
|
|
proguardFiles(
|
|
*fileTree(".") { include("**/*.pro") }
|
|
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))
|
|
.toList().toTypedArray()
|
|
)
|
|
}
|
|
}
|
|
kotlinOptions {
|
|
jvmTarget = "1.8"
|
|
}
|
|
buildFeatures {
|
|
buildConfig = true
|
|
}
|
|
}
|
|
|
|
rust {
|
|
rootDirRel = "../../../"
|
|
}
|
|
|
|
dependencies {
|
|
implementation("androidx.webkit:webkit:1.14.0")
|
|
implementation("androidx.appcompat:appcompat:1.7.1")
|
|
implementation("androidx.activity:activity-ktx:1.10.1")
|
|
implementation("com.google.android.material:material:1.12.0")
|
|
implementation("androidx.lifecycle:lifecycle-process:2.10.0")
|
|
testImplementation("junit:junit:4.13.2")
|
|
androidTestImplementation("androidx.test.ext:junit:1.1.4")
|
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
|
|
}
|
|
|
|
apply(from = "tauri.build.gradle.kts") |