Building Tamed from source gives you the most control: you can target any device architecture, enable optional integrations like Last.fm scrobbling with your own API keys, and sign the output with your own keystore. This guide covers every step from cloning the repository to producing a signed release APK, including code-quality checks required before opening a pull request.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/calmerism/Tamed/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Make sure the following tools are installed and on yourPATH before you begin. These are the minimum versions validated against the Tamed build system.
| Tool | Minimum Version | Notes |
|---|---|---|
| Android Studio | Ladybug 2024.2.1 | Bundles a compatible Gradle plugin and Kotlin toolchain |
| JDK | 21 | Amazon Corretto or Azul Zulu recommended for deterministic builds |
| Android SDK | API Level 34 (Upside Down Cake) | Install via Android Studio SDK Manager |
| Git | 2.40 | Required for submodule-aware cloning |
The project compiles with
sourceCompatibility = JavaVersion.VERSION_21 and targets JVM_21 in the Kotlin compiler options. Android Studio Ladybug ships with JBR 21, so no extra JDK installation is needed if you use the bundled runtime.Step 1 — Clone the Repository
Open in Android Studio
Launch Android Studio and choose File → Open, then select the
Tamed directory you just cloned. The IDE will detect the Gradle project automatically.Wait for Gradle sync
Android Studio triggers a Gradle sync immediately after opening. The first sync downloads all dependencies (Media3, Hilt, Compose, Ktor, Room, and the internal modules). This can take several minutes on a first run depending on your internet connection.Dependency resolution uses Version Catalogs (
libs.versions.toml), so all library versions are locked to tested combinations — no manual version alignment is required.Step 2 — Configure local.properties (Optional)
Tamed reads optional API keys and signing credentials from local.properties at the project root. This file is excluded from version control and never committed. Create it if it does not exist:
Every key shown above is also readable from environment variables, so CI systems can inject secrets without writing a file to disk.
Step 3 — Build Commands
Tamed defines two product flavors along theabi dimension: arm64 (arm64-v8a only) and universal (armeabi-v7a + arm64-v8a + x86 + x86_64). Combine a flavor with a build type to produce your target APK.
| Command | Output file | Use case |
|---|---|---|
./gradlew :app:assembleArm64Debug | app/build/outputs/apk/arm64/debug/app-arm64-debug.apk | Local testing on arm64 devices |
./gradlew :app:assembleArm64Release | app/build/outputs/apk/arm64/release/Tamed.apk | Named release APK matching the GitHub release artifact |
./gradlew :app:assembleUniversalDebug | app/build/outputs/apk/universal/debug/app-universal-debug.apk | Local testing on all ABI targets |
./gradlew :app:assembleUniversalRelease | app/build/outputs/apk/universal/release/app-universal-release.apk | All ABIs: armeabi-v7a, arm64-v8a, x86, x86_64 |
./gradlew bundleRelease | app-release.aab | App Bundle for Play Store distribution |
./gradlew clean | — | Flushes the build cache to resolve stale sync issues |
APK Output Paths
Step 4 — Signing
Release builds require a signing configuration. Tamed resolves the keystore in this order:- The path specified by
RELEASE_STORE_FILEinlocal.propertiesor the environment. - The default Android debug keystore at
~/.android/debug.keystore, if the above file does not exist. - The raw path value as-is (the build will fail if neither file is present).
android as both the store password and key password, and androiddebugkey as the key alias. This means a release build still succeeds out of the box without any keystore setup, though you should use a proper keystore for any APK you distribute.
To generate a production keystore with the JDK keytool:
Troubleshooting
Code Quality Gates
Before opening a pull request, all three quality gates must pass cleanly. Run them from the project root:The lint configuration (
app/lint.xml) has warningsAsErrors = false and abortOnError = false set for development builds, so lint warnings will not block a local build. The CI pipeline enforces stricter rules on pull requests.