Add release signing, versioning and dist task

- Version defined once; versionCode = MAJOR*10000 + MINOR*100 + PATCH
- Optional release signing from ~/.gradle/gradle.properties
- ./gradlew dist copies signed APKs to dist/ with Obtainium-friendly names

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-15 22:06:13 +02:00
co-authored by Claude Opus 5.5
parent 0a7caf6c5f
commit f5b0fd2527
3 changed files with 47 additions and 3 deletions
+1
View File
@@ -13,3 +13,4 @@ env.sh
# Zugangsdaten – niemals committen
.giteatoken
*.token
dist/
+10 -1
View File
@@ -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-<flavor>-v<version>.apk
```
## License
GPLv3, see [LICENSE](LICENSE).
+36 -2
View File
@@ -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<Sync>("dist") {
description = "Copies signed release APKs to dist/ as pixelwall-<flavor>-v<version>.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"))