# Build and Deployment
**Referenced Files in This Document**
- [build.gradle.kts](file://build.gradle.kts)
- [settings.gradle.kts](file://settings.gradle.kts)
- [gradle.properties](file://gradle.properties)
- [gradle/libs.versions.toml](file://gradle/libs.versions.toml)
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [app/proguard-rules.pro](file://app/proguard-rules.pro)
- [.github/workflows/build.yml](file://.github/workflows/build.yml)
- [.github/workflows/release.yml](file://.github/workflows/release.yml)
- [core/data/build.gradle.kts](file://core/data/build.gradle.kts)
- [core/domain/build.gradle.kts](file://core/domain/build.gradle.kts)
- [media-source/build.gradle.kts](file://media-source/build.gradle.kts)
- [scrobbler/build.gradle.kts](file://scrobbler/build.gradle.kts)
- [com.suvojeet.suvmusic.yml](file://com.suvojeet.suvmusic.yml)
## Table of Contents
1. [Introduction](#introduction)
2. [Project Structure](#project-structure)
3. [Core Components](#core-components)
4. [Architecture Overview](#architecture-overview)
5. [Detailed Component Analysis](#detailed-component-analysis)
6. [Dependency Analysis](#dependency-analysis)
7. [Performance Considerations](#performance-considerations)
8. [Troubleshooting Guide](#troubleshooting-guide)
9. [Conclusion](#conclusion)
10. [Appendices](#appendices)
## Introduction
This document explains how SuvMusic is built and deployed. It covers the multi-module Gradle configuration, dependency management via Gradle Version Catalogs, signing and release builds, ProGuard optimization, CI/CD with GitHub Actions, and the current state of Fastlane metadata. It also outlines build variants, flavor configurations, and release channel management, along with troubleshooting tips and optimization techniques.
## Project Structure
SuvMusic is a multi-module Android project with a shared top-level Gradle configuration and per-module build scripts. Modules are organized by feature and core layers, including the main app module, updater, media source providers, scrobbler, lyric providers, extractor, and core libraries (model, data, domain, ui).
```mermaid
graph TB
Root["Root Project
build.gradle.kts, settings.gradle.kts, gradle.properties"] --> App["App Module
app/build.gradle.kts"]
Root --> Updater["Updater Module
updater"]
Root --> MediaSource["Media Source Module
media-source/build.gradle.kts"]
Root --> Scrobbler["Scrobbler Module
scrobbler/build.gradle.kts"]
Root --> LyricSimp["Lyric Provider: SimpMusic
lyric-simpmusic"]
Root --> LyricLrcLib["Lyric Provider: LrcLib
lyric-lrclib"]
Root --> LyricKugou["Lyric Provider: KuGou
lyric-kugou"]
Root --> Extractor["Extractor Module
extractor"]
Root --> CoreModel["Core Model
core/model"]
Root --> CoreData["Core Data
core/data/build.gradle.kts"]
Root --> CoreDomain["Core Domain
core/domain/build.gradle.kts"]
Root --> CoreUI["Core UI
core/ui"]
App --> MediaSource
App --> Updater
App --> CoreData
App --> CoreDomain
App --> CoreUI
App --> Scrobbler
App --> LyricSimp
App --> LyricLrcLib
App --> LyricKugou
App --> Extractor
CoreData --> CoreModel
CoreData --> CoreDomain
MediaSource --> CoreModel
Scrobbler --> CoreModel
```
**Diagram sources**
- [settings.gradle.kts](file://settings.gradle.kts)
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [core/data/build.gradle.kts](file://core/data/build.gradle.kts)
- [core/domain/build.gradle.kts](file://core/domain/build.gradle.kts)
- [media-source/build.gradle.kts](file://media-source/build.gradle.kts)
- [scrobbler/build.gradle.kts](file://scrobbler/build.gradle.kts)
**Section sources**
- [settings.gradle.kts](file://settings.gradle.kts)
- [build.gradle.kts](file://build.gradle.kts)
- [gradle.properties](file://gradle.properties)
## Core Components
- Multi-module Gradle build with shared plugin aliases and version catalog.
- Centralized dependency versions via Gradle Version Catalogs.
- App module with release signing, minification, resource filtering, and native CMake integration.
- Core modules for model, data, domain, and UI layered architecture.
- Media source and scrobbler modules with Last.fm credentials injected via environment or local properties.
- CI/CD workflows for automated builds and releases.
**Section sources**
- [build.gradle.kts](file://build.gradle.kts)
- [gradle/libs.versions.toml](file://gradle/libs.versions.toml)
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [core/data/build.gradle.kts](file://core/data/build.gradle.kts)
- [core/domain/build.gradle.kts](file://core/domain/build.gradle.kts)
- [media-source/build.gradle.kts](file://media-source/build.gradle.kts)
- [scrobbler/build.gradle.kts](file://scrobbler/build.gradle.kts)
## Architecture Overview
The build system relies on:
- Top-level plugin management and plugin aliasing.
- Version catalogs for consistent dependency versions across modules.
- App module configuration for ABI filters, resource splits, desugaring, and native build integration.
- CI/CD workflows orchestrating signing, building, artifact renaming, and GitHub Releases.
```mermaid
graph TB
subgraph "Local Build"
A_Gradle["Gradle Wrapper"]
A_Versions["Version Catalog
gradle/libs.versions.toml"]
A_App["App Build Config
app/build.gradle.kts"]
A_Proguard["ProGuard Rules
app/proguard-rules.pro"]
end
subgraph "CI/CD"
W_Build[".github/workflows/build.yml"]
W_Release[".github/workflows/release.yml"]
end
A_Gradle --> A_Versions
A_Gradle --> A_App
A_App --> A_Proguard
W_Build --> A_Gradle
W_Release --> A_Gradle
```
**Diagram sources**
- [gradle/libs.versions.toml](file://gradle/libs.versions.toml)
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [app/proguard-rules.pro](file://app/proguard-rules.pro)
- [.github/workflows/build.yml](file://.github/workflows/build.yml)
- [.github/workflows/release.yml](file://.github/workflows/release.yml)
## Detailed Component Analysis
### Gradle Build Configuration and Version Catalogs
- Plugin aliasing is centralized in the root build script, enabling consistent plugin usage across modules.
- Version Catalogs define versions and library coordinates, ensuring uniform dependency versions and simplifying updates.
- Global Gradle properties enable AndroidX, non-transitive R classes, legacy DSL opt-out for compatibility, and JVM tuning.
Key behaviors:
- Plugins applied at root level with apply false to avoid applying to all subprojects.
- Version catalog provides libraries and plugins for consistent dependency resolution.
**Section sources**
- [build.gradle.kts](file://build.gradle.kts)
- [gradle/libs.versions.toml](file://gradle/libs.versions.toml)
- [gradle.properties](file://gradle.properties)
### Multi-Module Project Structure
Modules included:
- App: main application module.
- Updater: update checking and download UI.
- Media source provider: common media source abstractions.
- Scrobbler: Last.fm scrobbling logic.
- Lyric providers: SimpMusic, LrcLib, KuGou.
- Extractor: NewPipe extractor integration.
- Core: model, data, domain, ui.
Each module defines its own Android configuration and dependencies, with the app module aggregating them.
**Section sources**
- [settings.gradle.kts](file://settings.gradle.kts)
- [core/data/build.gradle.kts](file://core/data/build.gradle.kts)
- [core/domain/build.gradle.kts](file://core/domain/build.gradle.kts)
- [media-source/build.gradle.kts](file://media-source/build.gradle.kts)
- [scrobbler/build.gradle.kts](file://scrobbler/build.gradle.kts)
### App Module Build Configuration
Highlights:
- Compile and target SDK set to 36; minSdk 26.
- ABI filters limit native artifacts to arm64-v8a and armeabi-v7a.
- Resource configurations limit supported locales to reduce APK size.
- Desugaring enabled for Java 8+ APIs on older Android versions.
- Native CMake integration with a specific NDK version.
- BuildConfig fields for Last.fm credentials loaded from environment or local.properties.
- Signing configuration reads keystore path and credentials from environment variables.
- Release build type enables minification and resource shrinking with custom ProGuard rules.
- Compose and buildConfig features enabled.
- Protobuf plugin configured with lite generation for Java/Kotlin.
**Section sources**
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [app/proguard-rules.pro](file://app/proguard-rules.pro)
### ProGuard Optimization Rules
Rules preserve:
- NewPipe Extractor and its Rhino dependency.
- OkHttp and Gson.
- Hilt DI classes.
- Jetpack Compose runtime.
- Media3 ExoPlayer classes.
- Coil image loading.
- Ktor client and kotlinx serialization.
- JAudioTagger.
- Protobuf and Listen Together protobuf messages.
Warnings are suppressed for Android-specific missing classes and logging frameworks.
**Section sources**
- [app/proguard-rules.pro](file://app/proguard-rules.pro)
### CI/CD Pipeline with GitHub Actions
Automated builds:
- Build workflow:
- Checks out code, sets up JDK 21, installs Protobuf compiler.
- Caches Gradle wrapper and dependencies.
- Decodes keystore from secret and builds release APK/AAB with environment variables.
- Renames artifacts with version and build number.
- Uploads artifacts and creates a pre-release on GitHub.
- Release workflow:
- Manual trigger to produce production releases.
- Builds APK/AAB with keystore decoded from secrets.
- Generates release notes from updater changelog JSON.
- Extracts artifacts and publishes a GitHub Release as non-prerelease.
Both workflows pass Last.fm credentials via environment variables and use the same keystore decoding pattern.
```mermaid
sequenceDiagram
participant Dev as "Developer"
participant GH as "GitHub Actions"
participant Gradle as "Gradle Build"
participant Store as "GitHub Releases"
Dev->>GH : Push to main/dev or workflow dispatch
GH->>GH : Checkout code
GH->>GH : Setup JDK 21
GH->>GH : Install Protobuf
GH->>GH : Cache Gradle
GH->>GH : Decode keystore from secret
GH->>Gradle : ./gradlew assembleRelease/bundleRelease
Gradle-->>GH : APK/AAB outputs
GH->>GH : Rename artifacts with version and run number
GH->>Store : Upload artifacts and create pre-release
Store-->>Dev : Release assets available
```
**Diagram sources**
- [.github/workflows/build.yml](file://.github/workflows/build.yml)
- [.github/workflows/release.yml](file://.github/workflows/release.yml)
**Section sources**
- [.github/workflows/build.yml](file://.github/workflows/build.yml)
- [.github/workflows/release.yml](file://.github/workflows/release.yml)
### Fastlane Integration
Fastlane metadata exists under fastlane/metadata/android/en-US with changelog, full description, and short description. Screenshots are present under screenshots/. However, the Fastfile is not found in the repository snapshot. As a result, automated store publishing and screenshot uploads are not configured in this repository snapshot.
Recommendation:
- Add a Fastfile to automate store metadata updates and screenshot uploads.
- Integrate Fastlane with CI/CD for streamlined release distribution.
**Section sources**
- [com.suvojeet.suvmusic.yml](file://com.suvojeet.suvmusic.yml)
### Build Variants and Flavor Configurations
- Current configuration defines debug and release build types in the app module.
- No product flavors are defined in the provided build scripts.
- Debug variant suffixes the application ID and disables minification.
- Release variant enables minification and resource shrinking with ProGuard rules.
To add flavors:
- Define flavor dimensions and product flavors in the app module.
- Configure signingConfigs per flavor and manage secrets accordingly.
- Use flavor-specific res/values and manifest placeholders.
**Section sources**
- [app/build.gradle.kts](file://app/build.gradle.kts)
### Release Channel Management
- GitHub Releases are used to publish artifacts.
- Build workflow marks releases as prerelease.
- Release workflow publishes stable releases and sets as latest.
For Play Console:
- Consider integrating Play App Bundle consumption and internal/test/production tracks.
- Automate release tracks via internal APIs or Fastlane with Play Developer API.
**Section sources**
- [.github/workflows/build.yml](file://.github/workflows/build.yml)
- [.github/workflows/release.yml](file://.github/workflows/release.yml)
## Dependency Analysis
The app module aggregates numerous libraries for UI, networking, media, DI, persistence, and more. Dependencies are grouped by category and resolved via the version catalog.
```mermaid
graph LR
App["App Module"] --> MediaSource["Media Source"]
App --> Updater["Updater"]
App --> CoreData["Core Data"]
App --> CoreDomain["Core Domain"]
App --> CoreUI["Core UI"]
App --> Scrobbler["Scrobbler"]
App --> LyricSimp["Lyric SimpMusic"]
App --> LyricLrcLib["Lyric LrcLib"]
App --> LyricKugou["Lyric KuGou"]
App --> Extractor["Extractor"]
CoreData --> CoreModel["Core Model"]
MediaSource --> CoreModel
Scrobbler --> CoreModel
```
**Diagram sources**
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [core/data/build.gradle.kts](file://core/data/build.gradle.kts)
- [core/domain/build.gradle.kts](file://core/domain/build.gradle.kts)
- [media-source/build.gradle.kts](file://media-source/build.gradle.kts)
- [scrobbler/build.gradle.kts](file://scrobbler/build.gradle.kts)
**Section sources**
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [core/data/build.gradle.kts](file://core/data/build.gradle.kts)
- [core/domain/build.gradle.kts](file://core/domain/build.gradle.kts)
- [media-source/build.gradle.kts](file://media-source/build.gradle.kts)
- [scrobbler/build.gradle.kts](file://scrobbler/build.gradle.kts)
## Performance Considerations
- ABI filters and resource splits reduce APK size and improve install/download performance.
- Minification and resource shrinking in release builds reduce binary size.
- Desugaring allows modern Java APIs on older Android versions without bloating multidex.
- Protobuf lite reduces serialization overhead.
- Compose BOM ensures consistent UI toolkit versions.
- Caching Gradle wrapper and dependencies accelerates CI builds.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and resolutions:
- Missing keystore secrets in CI:
- Ensure environment variables are set in GitHub Secrets and passed to Gradle tasks.
- Verify keystore decoding step succeeds and paths match the signingConfig.
- ProGuard errors after dependency updates:
- Review keep/dontwarn rules for updated libraries.
- Re-run with verbose ProGuard logs to identify missing keep rules.
- Native build failures:
- Confirm NDK version matches the configured version and CMakeLists path is correct.
- Ensure Protobuf compiler is installed in CI runners.
- Desugaring conflicts:
- Align Java language level and desugaring settings across modules.
- Ensure consistent JVM target settings.
- Last.fm credentials not applied:
- Confirm environment variables or local.properties contain the keys.
- Verify BuildConfig fields are generated and accessible.
**Section sources**
- [.github/workflows/build.yml](file://.github/workflows/build.yml)
- [app/build.gradle.kts](file://app/build.gradle.kts)
- [app/proguard-rules.pro](file://app/proguard-rules.pro)
## Conclusion
SuvMusic employs a robust multi-module Gradle setup with centralized version catalogs, optimized release builds, and automated CI/CD pipelines. The app module integrates native components, Compose UI, and extensive libraries while maintaining a lean footprint through ABI/resource filters and minification. CI workflows produce APKs and AABs, and GitHub Releases streamline distribution. While Fastlane metadata exists, the Fastfile is not present in this snapshot; adding it would further automate store publishing. For future enhancements, consider adding product flavors, Play Console automation, and expanded Fastlane tasks.
[No sources needed since this section summarizes without analyzing specific files]
## Appendices
### Appendix A: Key Build Properties and Flags
- AndroidX enabled globally.
- Non-transitive R classes enabled to reduce R class size.
- Legacy DSL disabled for KSP compatibility.
- JVM arguments tuned for Gradle daemon memory.
**Section sources**
- [gradle.properties](file://gradle.properties)
### Appendix B: Version Catalog Highlights
- Android Gradle Plugin and Kotlin versions pinned centrally.
- Jetpack Compose BOM, Media3, Hilt, Room, WorkManager, OkHttp, Retrofit, Coil, Ktor, Protobuf, and more defined in one place.
**Section sources**
- [gradle/libs.versions.toml](file://gradle/libs.versions.toml)