Files
android-backup-gui/app/build.gradle
sakuradairong f99585a7c0 feat(release): 阶段6-7 Restic streaming标识、发布治理、CI
阶段6:Restic streaming 策略
- ConfigScreen 流式备份文案改为'实验性 Restic 临时目录备份'
  并显示不完整备份警告
- ResticStreamBackup 写入 streaming_manifest.json 记录 excluded 项目
- RestoreViewModel 检测 streaming manifest 并在确认弹窗中显示警告

阶段7:发布与仓库治理
- .gitignore 排除 app/release/*.apk
- build.gradle release 构建强制签名,启用 R8 + shrinkResources
- proguard-rules.pro 修正 restic 类路径,启用 R8 keep 规则
- 新增 .github/workflows/android.yml (CI: lint/test/assembleDebug)
- 新增 .github/workflows/release.yml (Release: tag触发,签名,sha256)
2026-06-17 11:24:39 +08:00

138 lines
5.0 KiB
Groovy

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
apply plugin: 'org.jetbrains.kotlinx.kover'
kover {
reports {
filters {
excludes {
classes(
"*.BuildConfig",
"*.R",
"*.R\$*"
)
}
}
}
}
android {
namespace "com.example.androidbackupgui"
compileSdk 34
defaultConfig {
applicationId "com.example.androidbackupgui"
minSdk 24
targetSdk 34
versionCode 16
versionName "1.16"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
lint {
disable 'QueryAllPackagesPermission'
}
signingConfigs {
release {
storeFile rootProject.file("app/release.keystore")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias "release"
keyPassword System.getenv("KEY_PASSWORD")
v1SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
def ksFile = rootProject.file("app/release.keystore")
def ksPass = System.getenv("KEYSTORE_PASSWORD")
def kPass = System.getenv("KEY_PASSWORD")
def isReleaseTask = gradle.startParameter.taskNames.any { it.toLowerCase().contains("release") }
if (isReleaseTask) {
if (!ksFile.exists() || ksPass == null || ksPass.isEmpty() || kPass == null || kPass.isEmpty()) {
throw new GradleException("Release build requires signing config. Set KEYSTORE_PASSWORD and KEY_PASSWORD env vars and ensure app/release.keystore exists.")
}
signingConfig signingConfigs.release
} else if (ksFile.exists() && ksPass != null && !ksPass.isEmpty() && kPass != null && !kPass.isEmpty()) {
signingConfig signingConfigs.release
}
}
}
testOptions {
unitTests.all {
useJUnitPlatform()
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
packagingOptions {
jniLibs {
useLegacyPackaging true
}
resources {
excludes += [
'org/bouncycastle/pqc/crypto/picnic/lowmcL5.bin.properties',
'org/bouncycastle/pqc/crypto/picnic/lowmcL3.bin.properties',
'org/bouncycastle/pqc/crypto/picnic/lowmcL1.bin.properties',
]
}
}
}
dependencies {
// Compose BOM (manages all Compose library versions)
implementation platform('androidx.compose:compose-bom:2024.02.00')
implementation 'androidx.compose.material3:material3'
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.compose.foundation:foundation'
implementation 'androidx.compose.material:material-icons-extended'
implementation 'androidx.activity:activity-compose:1.8.2'
debugImplementation 'androidx.compose.ui:ui-tooling'
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.0"
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.7.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
// 方案A: jcifs-ng (SMB) + sardine-android (WebDAV) 替代 rclone serve
implementation("eu.agno3.jcifs:jcifs-ng:2.1.10") {
exclude group: 'org.bouncycastle'
}
implementation("com.github.thegrizzlylabs:sardine-android:v0.9") {
exclude group: 'xpp3'
exclude group: 'stax'
}
implementation "org.slf4j:slf4j-android:1.7.36"
// root shell via libsu (Magisk/KernelSU/APatch)
implementation 'com.github.topjohnwu:libsu:6.0.0'
// Full BouncyCastle provider (includes MD4 required by jcifs-ng SMB)
implementation 'org.bouncycastle:bcprov-jdk15to18:1.77'
implementation 'org.nanohttpd:nanohttpd:2.3.1'
testImplementation "io.kotest:kotest-runner-junit5:5.9.1"
testImplementation "io.kotest:kotest-assertions-core:5.9.1"
testImplementation "io.kotest:kotest-property:5.9.1"
testImplementation "io.mockk:mockk:1.13.12"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3"
}