Overview
MiTensión uses Gradle as its build system with Kotlin DSL for build scripts. The project supports multiple build variants and configurations for development and production releases.
Build System
Project Structure
MiTensión/
├── build.gradle.kts # Root build configuration
├── settings.gradle.kts # Project settings and modules
├── gradle.properties # Gradle configuration
├── gradle/
│ ├── libs.versions.toml # Version catalog for dependencies
│ └── wrapper/ # Gradle wrapper files
└── app/
├── build.gradle.kts # App module build configuration
└── proguard-rules.pro # ProGuard rules for release builds
Build Configuration
Key build settings from app/build.gradle.kts:
android {
namespace = "com.fxn.mitension"
compileSdk = 36
defaultConfig {
applicationId = "com.fxn.mitension"
minSdk = 31
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.11"
}
}
Android Version Requirements:
Minimum SDK: 31 (Android 12)
Target SDK: 35 (Android 15)
Compile SDK: 36
Build Variants
Debug Build
The debug build is optimized for development with additional debugging tools:
No code obfuscation
Debug symbols included
Faster build times
Compose UI tooling enabled
Release Build
From app/build.gradle.kts:
buildTypes {
release {
isMinifyEnabled = false
proguardFiles (
getDefaultProguardFile ( "proguard-android-optimize.txt" ),
"proguard-rules.pro"
)
}
}
Currently, minification is disabled. For production releases, consider enabling isMinifyEnabled = true to reduce APK size and add code obfuscation.
Gradle Commands
Building the App
Debug Build
Release Build
All Variants
Bundle (AAB)
# Build debug APK
./gradlew assembleDebug
# Output: app/build/outputs/apk/debug/app-debug.apk
Installing on Device
Install Debug
Install Release
Install and Run
# Install debug build on connected device/emulator
./gradlew installDebug
Cleaning Build Artifacts
# Remove all build directories
./gradlew clean
# Clean and rebuild
./gradlew clean assembleDebug
Dependency Management
MiTensión uses Gradle Version Catalogs (gradle/libs.versions.toml) for centralized dependency management:
[ versions ]
agp = "8.13.1"
kotlin = "1.9.23"
ksp = "1.9.23-1.0.19"
composeB om = "2024.09.00"
room = "2.6.1"
lifecycle = "2.10.0"
[ libraries ]
androidx-core-ktx = { group = "androidx.core" , name = "core-ktx" , version.ref = "coreKtx" }
androidx-compose-bom = { group = "androidx.compose" , name = "compose-bom" , version.ref = "composeBom" }
androidx-room-runtime = { group = "androidx.room" , name = "room-runtime" , version.ref = "room" }
[ plugins ]
android-application = { id = "com.android.application" , version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android" , version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp" , version.ref = "ksp" }
Updating Dependencies
Edit Version Catalog
Update versions in gradle/libs.versions.toml
Sync Project
./gradlew --refresh-dependencies
Verify Build
./gradlew clean assembleDebug
Room Database Schema
Room database schemas are exported during build:
ksp {
arg ( "room.schemaLocation" , " $projectDir /schemas" )
}
Schemas are saved to app/schemas/ for version control and migration tracking.
Room schema files help track database changes across versions. Commit these files to version control.
Code Generation with KSP
The project uses Kotlin Symbol Processing (KSP) for code generation:
plugins {
id ( "com.google.devtools.ksp" ) version "1.9.23-1.0.19"
}
dependencies {
ksp (libs.androidx.room.compiler)
}
KSP generates Room DAO implementations and database classes during compilation.
Signing Configuration
Debug Signing
Debug builds are automatically signed with the default Android debug keystore:
Location: ~/.android/debug.keystore
Alias: androiddebugkey
Password: android
Release Signing
For production releases, create a release keystore:
Generate Keystore
keytool -genkey -v -keystore mitension-release.keystore \
-alias mitension -keyalg RSA -keysize 2048 -validity 10000
Create keystore.properties
Create keystore.properties in the project root (add to .gitignore): storeFile =/path/to/mitension-release.keystore
storePassword =YOUR_STORE_PASSWORD
keyAlias =mitension
keyPassword =YOUR_KEY_PASSWORD
Update build.gradle.kts
Add signing configuration to app/build.gradle.kts: val keystorePropertiesFile = rootProject. file ( "keystore.properties" )
val keystoreProperties = Properties ()
if (keystorePropertiesFile. exists ()) {
keystoreProperties. load ( FileInputStream (keystorePropertiesFile))
}
android {
signingConfigs {
create ( "release" ) {
storeFile = file (keystoreProperties[ "storeFile" ] ?: "" )
storePassword = keystoreProperties[ "storePassword" ] as ? String
keyAlias = keystoreProperties[ "keyAlias" ] as ? String
keyPassword = keystoreProperties[ "keyPassword" ] as ? String
}
}
buildTypes {
release {
signingConfig = signingConfigs. getByName ( "release" )
isMinifyEnabled = true
proguardFiles (
getDefaultProguardFile ( "proguard-android-optimize.txt" ),
"proguard-rules.pro"
)
}
}
}
Build Signed APK
./gradlew assembleRelease
Output: app/build/outputs/apk/release/app-release.apk (signed)
Never commit keystore.properties or the keystore file to version control! Add them to .gitignore.
ProGuard Configuration
ProGuard rules are defined in app/proguard-rules.pro. Common rules for MiTensión:
# Keep Room entities
-keep class com.fxn.mitension.data.** { *; }
# Keep Compose runtime
-keep class androidx.compose.** { *; }
-dontwarn androidx.compose.**
# Keep Kotlin metadata
-keep class kotlin.Metadata { *; }
# Keep WorkManager
-keep class androidx.work.** { *; }
-dontwarn androidx.work.**
Build Outputs
After building, artifacts are located in:
APK Files app/build/outputs/apk/[variant]/
app-debug.apk
app-release.apk
App Bundles app/build/outputs/bundle/[variant]/
Build Logs app/build/outputs/logs/
Compilation logs
Lint reports
Test Results app/build/reports/tests/
Unit test reports
Instrumentation test reports
Version Management
Update app version in app/build.gradle.kts:
defaultConfig {
versionCode = 2 // Increment for each release
versionName = "1.1.0" // User-visible version
}
Version Code : Integer incremented with each release (1, 2, 3…)Version Name : Semantic version string (1.0.0, 1.1.0, 2.0.0)
Gradle Wrapper
The project includes a Gradle wrapper for consistent builds:
# Use wrapper (recommended)
./gradlew assembleDebug
# Update wrapper version
./gradlew wrapper --gradle-version=8.13
Always use ./gradlew instead of system-installed gradle to ensure consistent build environment across machines.
Common Build Tasks
# List all available tasks
./gradlew tasks
# Show project dependencies
./gradlew dependencies
# Check for dependency updates
./gradlew dependencyUpdates
# Analyze APK size
./gradlew analyzeReleaseBundle
# Generate build scan
./gradlew build --scan
Android Studio Build
Select Build Variant
Open Build Variants panel (View → Tool Windows → Build Variants) Select:
debug for development
release for production
Build APK
Build → Build Bundle(s) / APK(s) → Build APK(s)
Generate Signed Bundle
Build → Generate Signed Bundle / APK Follow the wizard to select keystore and create signed release
Continuous Integration
Example GitHub Actions workflow for building MiTensión:
name : Build APK
on :
push :
branches : [ main , develop ]
pull_request :
branches : [ main ]
jobs :
build :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- name : Set up JDK 11
uses : actions/setup-java@v3
with :
java-version : '11'
distribution : 'temurin'
- name : Cache Gradle packages
uses : actions/cache@v3
with :
path : |
~/.gradle/caches
~/.gradle/wrapper
key : ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
- name : Grant execute permission for gradlew
run : chmod +x gradlew
- name : Build with Gradle
run : ./gradlew assembleDebug
- name : Run tests
run : ./gradlew test
- name : Upload APK
uses : actions/upload-artifact@v3
with :
name : app-debug
path : app/build/outputs/apk/debug/app-debug.apk
Troubleshooting
Build Failures
# Clean KSP generated code
./gradlew clean
rm -rf app/build/generated/ksp
./gradlew assembleDebug
Dependency resolution failures
# Clear dependency cache
./gradlew clean --refresh-dependencies
rm -rf ~/.gradle/caches
Add to gradle.properties: org.gradle.jvmargs =-Xmx4096m -XX: MaxMetaspaceSize =512m
Compose compiler version mismatch
Ensure Kotlin and Compose compiler versions are compatible:
Kotlin 1.9.23 → Compose Compiler 1.5.11
Update in app/build.gradle.kts: composeOptions {
kotlinCompilerExtensionVersion = "1.5.11"
}
Enable Build Cache Add to gradle.properties:
Configuration Cache org.gradle.configuration-cache =true
Incremental Compilation Already enabled by default in Kotlin 1.9.23
For faster builds during development, use ./gradlew assembleDebug --offline when dependencies haven’t changed.