Add release/build tooling and README

- Real release build type: R8 shrinking + shrunk resources, with a keep
  rule for VeilHook specifically — LSPosed finds it by exact class name via
  the plaintext xposed_init asset, which R8 can't see, so obfuscating it
  would silently break module loading with no build error to point at why.
- Signing config that reads keystore.properties if present (gitignored,
  generated via scripts/generate-keystore.sh), falling back to debug
  signing otherwise so assembleRelease always produces something
  installable.
- scripts/release.sh builds and copies a version-stamped APK into dist/.
- GitHub Actions workflow building and publishing a release on any tag
  matching *.*.* (bare semver, e.g. 1.2.0 — no v prefix required), optionally
  using repo secrets for real release signing in CI.
- README covering setup, the feature table, and the DenyList gotcha.

No native code in this module, so a single APK already covers every
architecture — no per-ABI splitting needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Claude Sonnet 5
2026-08-06 21:46:16 +06:00
parent 615f000800
commit 328237d722
7 changed files with 218 additions and 1 deletions
+34 -1
View File
@@ -1,23 +1,56 @@
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
val hasReleaseKeystore = keystorePropertiesFile.exists()
if (hasReleaseKeystore) {
keystoreProperties.load(keystorePropertiesFile.inputStream())
}
android {
namespace = "space.bdeshi.veil"
compileSdk = 35
defaultConfig {
applicationId = "space.bdeshi.veil"
// 27 (Android 8.1) is LSPosed/Zygisk's own practical floor — nothing here restricts
// it further. No upper bound: compileSdk is a compile-time API surface, not a ceiling
// on which OS versions can install and run the app.
minSdk = 27
targetSdk = 35
versionCode = 1
versionName = "1.0"
}
signingConfigs {
create("release") {
if (hasReleaseKeystore) {
storeFile = rootProject.file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
}
}
}
buildTypes {
release {
isMinifyEnabled = false
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
// Falls back to debug signing when no keystore.properties exists (e.g. a fresh
// clone, or CI without release-signing secrets configured), so assembleRelease
// always produces something installable. See scripts/generate-keystore.sh.
signingConfig = if (hasReleaseKeystore) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
}
}