Sync engine / providers: - LocalAccessor: replace createOutputStream with writeAtomically (temp sibling + rename/commit) for both JavaFile and SAF backends, so an interrupted download no longer truncates the destination file. - SyncEngine: use writeAtomically for DOWNLOAD and propagate downloadFile failures via getOrThrow (was silently swallowed -> false success + state). - WebDavProvider (covers Nextcloud/ownCloud): PUT to hidden temp then MOVE onto destination, so a failed upload can't leave a truncated remote file. - SftpProvider: upload to temp then rename onto destination. Build / CI: - compileSdk 34 -> 35 (was below targetSdk 35). - Release signing reads keystore from local.properties or env (CI), with a debug-key fallback so builds still succeed without secrets. - Disable R8/minify for release (never exercised by CI; keeps signed release behaving like the debug builds in use today). - CI: run unit tests on every push/PR, build assembleRelease (signed when KEYSTORE_BASE64 present), publish APK only on v* tags.
This commit is contained in:
+23
-8
@@ -18,9 +18,15 @@ val localProps = Properties().apply {
|
||||
if (f.exists()) load(f.inputStream())
|
||||
}
|
||||
|
||||
// Release signing is read from local.properties (local builds) or environment variables
|
||||
// (CI). When no keystore is available the release build falls back to the debug key so the
|
||||
// build still succeeds — it just isn't a distributable, properly-signed APK.
|
||||
val keystorePath = (localProps["KEYSTORE_PATH"] as String?) ?: System.getenv("KEYSTORE_PATH")
|
||||
val hasReleaseKeystore = keystorePath != null && file(keystorePath).exists()
|
||||
|
||||
android {
|
||||
namespace = "com.syncflow"
|
||||
compileSdk = 34
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.syncflow"
|
||||
@@ -38,19 +44,28 @@ android {
|
||||
|
||||
signingConfigs {
|
||||
create("release") {
|
||||
storeFile = localProps["KEYSTORE_PATH"]?.toString()?.let { file(it) }
|
||||
storePassword = localProps["KEYSTORE_PASSWORD"]?.toString()
|
||||
keyAlias = localProps["KEY_ALIAS"]?.toString()
|
||||
keyPassword = localProps["KEY_PASSWORD"]?.toString()
|
||||
if (hasReleaseKeystore) {
|
||||
storeFile = file(keystorePath!!)
|
||||
storePassword = (localProps["KEYSTORE_PASSWORD"] as String?) ?: System.getenv("KEYSTORE_PASSWORD")
|
||||
keyAlias = (localProps["KEY_ALIAS"] as String?) ?: System.getenv("KEY_ALIAS")
|
||||
keyPassword = (localProps["KEY_PASSWORD"] as String?) ?: System.getenv("KEY_PASSWORD")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
// R8/minify has never been exercised by CI (it only built debug), so leave it off
|
||||
// to keep the signed release behaving identically to the debug builds in use today.
|
||||
// Re-enable with proper keep rules and an on-device smoke test if APK size matters.
|
||||
isMinifyEnabled = false
|
||||
isShrinkResources = false
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
signingConfig = if (hasReleaseKeystore) {
|
||||
signingConfigs.getByName("release")
|
||||
} else {
|
||||
signingConfigs.getByName("debug")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user