Skip to content

Building from source

JP Hein edited this page May 10, 2026 · 6 revisions

Building from source

Toolchain

  • JDK 17 (any distribution; OpenJDK works).
  • Android SDK 35 (compileSdk + targetSdk; minSdk = 26).
  • Gradle 8.x — the wrapper is checked in, just ./gradlew.
  • No NDK needed — VoxSherpa-TTS ships as an AAR with prebuilt natives.

Clone + build

git clone https://github.com/jphein/storyvox.git
cd storyvox
./gradlew :app:assembleDebug

The signed debug APK lands at app/build/outputs/apk/debug/app-debug.apk.

Modules

Thirteen modules — :app, :feature, :core-data, :core-llm, :core-playback, :core-ui, :source-royalroad, :source-github, :source-mempalace, :source-rss, :source-epub, :source-outline, :source-azure, :wear. See Architecture.

Tests

./gradlew :app:testDebugUnitTest :feature:testDebugUnitTest

JVM unit tests only; Robolectric pulls in Android resources for the few tests that need android.net.Uri. No instrumented tests in CI today (real-tablet QA covers integration).

Install on device

adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell monkey -p in.jphe.storyvox -c android.intent.category.LAUNCHER 1

Signing

The debug keystore is committed (app/storyvox-debug.keystore, password "android"). Every build uses this cert so sideload upgrades land cleanly. Pre-release distribution is sideload-only via GitHub Releases — the security trade-off is documented in app/build.gradle.kts.

For Play Store distribution, swap to a CI-secret-stored release keystore; tracked at #16.

CI

.github/workflows/android.yml builds the debug APK on every main push and on every tag. Tagged releases attach the APK to the GitHub release. Copilot review runs on PRs as the merge gate.

Configure-time git provenance

app/build.gradle.kts injects the git hash, branch, dirty flag, and last-commit timestamp into BuildConfig via providers.exec (configuration-cache compatible). Settings → About reads these to render the realm sigil.

Runtime configuration

No runtime config files. All preferences live in DataStore (storyvox_settings.preferences_pb). The first run hydrates with hard-coded defaults; everything is editable via Settings.

Clone this wiki locally