Recently Written · git

scan-subread

PDF reader that follows an audiobook with the SubRead suite

git clone https://github.com/equwal/scan-subread

Log | Files | Refs


commit e75565ed2c6080bfdda57d85c3f8af8278e8bd28
truex <truex@equwal.com>
2026-09-26 23:03:19 -0700

Sign the release build with the SubRead key, and set the version to 0.1.0

Gradle reads the key store and its password from SUBREAD_KEYSTORE_FILE and SUBREAD_KEYSTORE_PASSWORD, the same as the other apps of the suite. Without them the release build is not signed. The version name now agrees with package.json.

 README.md                | 16 ++++++++++++++++
 android/app/build.gradle | 19 ++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 58810e1..6950b9c 100644
--- a/README.md
+++ b/README.md
@@ -388,6 +388,22 @@ Install it on a connected phone with USB debugging on:
 adb install -r android/app/build/outputs/apk/debug/app-debug.apk
 ```
 
+A release APK gets the key of the SubRead suite from two environment
+variables: `SUBREAD_KEYSTORE_FILE` (the key store, key alias `subread`)
+and `SUBREAD_KEYSTORE_PASSWORD`. The key never goes into the repository.
+Without the two variables, the release build is not signed. Increase
+`versionCode` in `android/app/build.gradle` for each release. Build it
+in `android/`:
+
+```bash
+.\gradlew.bat assembleRelease
+```
+
+The APK lands at `android/app/build/outputs/apk/release/app-release.apk`.
+A release has an annotated tag `vX.Y.Z`, the title "Scan SubRead X.Y.Z"
+and the asset `Scan-SubRead-X.Y.Z.apk`, the same as the other apps of the
+suite.
+
 Notes:
 
 - The WebView serves the app from `https://localhost`. The file fields
diff --git a/android/app/build.gradle b/android/app/build.gradle
index d02d7fb..781694c 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,5 +1,10 @@
 apply plugin: 'com.android.application'
 
+// Release signing comes from the environment, so the key never lives in the repository.
+def keystorePath = System.getenv("SUBREAD_KEYSTORE_FILE")
+def keystorePassword = System.getenv("SUBREAD_KEYSTORE_PASSWORD")
+def signingReady = keystorePath && keystorePassword && file(keystorePath).isFile()
+
 android {
     namespace = "com.equwal.scansubread"
     compileSdk = rootProject.ext.compileSdkVersion
@@ -7,8 +12,9 @@ android {
         applicationId "com.equwal.scansubread"
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
+        // versionCode must increase with each release.
         versionCode 1
-        versionName "1.0"
+        versionName "0.1.0"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         aaptOptions {
              // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -16,10 +22,21 @@ android {
             ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
         }
     }
+    if (signingReady) {
+        signingConfigs {
+            release {
+                storeFile file(keystorePath)
+                storePassword keystorePassword
+                keyAlias "subread"
+                keyPassword keystorePassword
+            }
+        }
+    }
     buildTypes {
         release {
             minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+            if (signingReady) signingConfig signingConfigs.release
         }
     }
 }