diff --git a/.gitignore b/.gitignore index a08bebc..41eee19 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ env.sh # Zugangsdaten – niemals committen .giteatoken *.token +dist/ diff --git a/README.md b/README.md index 90cb5ab..bc26a0d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Audit your device, fine-tune permissions and settings, and undo every change. Install and update through [Obtainium](https://obtainium.imranr.dev) with the button above, or add `https://git.mrblake.cc/MrBlake/Pixelwall` as an app source. Releases ship two APKs: pick `core` -(no network permission) or `full` with Obtainium's APK filter. No releases yet, the first one follows at the end of the roadmap. +(no network permission) or `full` with Obtainium's APK filter. ## Build variants @@ -29,6 +29,15 @@ Requirements: JDK 21, Android SDK (platform 37). ./gradlew check # unit tests, lint, network permission check ``` +## Releasing + +Release APKs are signed with a key kept outside the repository. Configure it in `~/.gradle/gradle.properties` +(`pixelwall.signing.storeFile`, `.storePassword`, `.keyAlias`, `.keyPassword`); without it the release APKs are unsigned. + +```sh +./gradlew dist # signed APKs in dist/ as pixelwall--v.apk +``` + ## License GPLv3, see [LICENSE](LICENSE). diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bc4dafe..fa9a9a6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,13 +4,31 @@ plugins { alias(libs.plugins.pixelwall.android.hilt) } +// Einzige Quelle der Version. versionCode = MAJOR*10000 + MINOR*100 + PATCH (streng monoton für Obtainium). +val appVersion = "0.1.0" +val appVersionCode = appVersion.split(".").map(String::toInt).let { (major, minor, patch) -> major * 10000 + minor * 100 + patch } + +// Release-Signatur aus ~/.gradle/gradle.properties; fehlt sie, entstehen unsignierte APKs (z. B. für F-Droid). +val signingStoreFile = providers.gradleProperty("pixelwall.signing.storeFile").orNull + android { namespace = "org.pixelwall.app" defaultConfig { applicationId = "org.pixelwall.app" - versionCode = 1 - versionName = "0.1.0" + versionCode = appVersionCode + versionName = appVersion + } + + signingConfigs { + if (signingStoreFile != null) { + create("release") { + storeFile = file(signingStoreFile) + storePassword = providers.gradleProperty("pixelwall.signing.storePassword").get() + keyAlias = providers.gradleProperty("pixelwall.signing.keyAlias").get() + keyPassword = providers.gradleProperty("pixelwall.signing.keyPassword").get() + } + } } flavorDimensions += "network" @@ -33,6 +51,7 @@ android { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + signingConfig = signingConfigs.findByName("release") } } @@ -47,6 +66,21 @@ android { } } +// Release-APKs mit stabilen Namen für Gitea-Releases/Obtainium nach dist/ kopieren. +val dist = tasks.register("dist") { + description = "Copies signed release APKs to dist/ as pixelwall--v.apk" + dependsOn("assembleCoreRelease", "assembleFullRelease") + val version = appVersion // lokale Kopie: Lambdas dürfen keine Skript-Objekte referenzieren (Configuration Cache) + for (flavor in listOf("core", "full")) { + val apkName = "pixelwall-$flavor-v$version.apk" + from(layout.buildDirectory.dir("outputs/apk/$flavor/release")) { + include("*.apk") + rename { apkName } + } + } + into(rootProject.layout.projectDirectory.dir("dist")) +} + dependencies { implementation(project(":core:model")) implementation(project(":core:domain"))