feat: add app versioning and display in settings

This commit is contained in:
tapframe 2026-04-05 00:57:13 +05:30
parent 7143f14779
commit 4ff1c6a982
5 changed files with 76 additions and 8 deletions

4
.gitignore vendored
View file

@ -18,4 +18,6 @@ captures
**/xcshareddata/WorkspaceSettings.xcsettings
node_modules/
logs/
Docs
Docs
keystore/
scripts/build-distribution.sh

View file

@ -2,6 +2,8 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
@ -18,6 +20,12 @@ abstract class GenerateRuntimeConfigsTask : DefaultTask() {
@get:InputFile
abstract val localPropertiesFile: RegularFileProperty
@get:Input
abstract val appVersionName: Property<String>
@get:Input
abstract val appVersionCode: Property<Int>
@TaskAction
fun generate() {
val props = Properties()
@ -67,9 +75,37 @@ abstract class GenerateRuntimeConfigsTask : DefaultTask() {
""".trimMargin()
)
}
outDir.resolve("com/nuvio/app/core/build").apply {
mkdirs()
resolve("AppVersionConfig.kt").writeText(
"""
|package com.nuvio.app.core.build
|
|object AppVersionConfig {
| const val VERSION_NAME = "${appVersionName.get()}"
| const val VERSION_CODE = ${appVersionCode.get()}
|}
""".trimMargin()
)
}
}
}
fun readXcconfigValue(file: File, key: String): String? {
if (!file.exists()) return null
return file.readLines()
.asSequence()
.map(String::trim)
.filter { it.isNotEmpty() && !it.startsWith("#") && it.contains('=') }
.map { line ->
val separatorIndex = line.indexOf('=')
line.substring(0, separatorIndex).trim() to line.substring(separatorIndex + 1).trim()
}
.firstOrNull { (entryKey, _) -> entryKey == key }
?.second
}
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidApplication)
@ -87,6 +123,12 @@ val releaseStorePassword = supabaseProps.getProperty("NUVIO_RELEASE_STORE_PASSWO
val releaseKeyAlias = supabaseProps.getProperty("NUVIO_RELEASE_KEY_ALIAS")?.takeIf { it.isNotBlank() }
val releaseKeyPassword = supabaseProps.getProperty("NUVIO_RELEASE_KEY_PASSWORD")?.takeIf { it.isNotBlank() }
val releaseKeystore = releaseStoreFile?.let(rootProject::file)
val appVersionConfigFile = rootProject.file("iosApp/Configuration/Version.xcconfig")
val releaseAppVersionName = readXcconfigValue(appVersionConfigFile, "MARKETING_VERSION")
?: error("MARKETING_VERSION is missing from ${appVersionConfigFile.path}")
val releaseAppVersionCode = readXcconfigValue(appVersionConfigFile, "CURRENT_PROJECT_VERSION")
?.toIntOrNull()
?: error("CURRENT_PROJECT_VERSION is missing or invalid in ${appVersionConfigFile.path}")
val iosDistribution = (
providers.gradleProperty("nuvio.ios.distribution").orNull
?: System.getenv("NUVIO_IOS_DISTRIBUTION")
@ -106,6 +148,8 @@ val generatedRuntimeConfigDir = layout.buildDirectory.dir("generated/runtime-con
val generateRuntimeConfigs = tasks.register<GenerateRuntimeConfigsTask>("generateRuntimeConfigs") {
outputDir.set(generatedRuntimeConfigDir)
localPropertiesFile.set(rootProject.layout.projectDirectory.file("local.properties"))
appVersionName.set(releaseAppVersionName)
appVersionCode.set(releaseAppVersionCode)
}
tasks.withType<KotlinCompilationTask<*>>().configureEach {
@ -238,8 +282,8 @@ android {
applicationId = "com.nuvio.app"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
versionCode = 1
versionName = "1.0"
versionCode = releaseAppVersionCode
versionName = releaseAppVersionName
}
flavorDimensions += "distribution"
productFlavors {
@ -268,6 +312,9 @@ android {
getByName("release") {
isMinifyEnabled = false
signingConfig = signingConfigs.getByName("release")
ndk {
debugSymbolLevel = "FULL"
}
}
}
compileOptions {
@ -275,4 +322,3 @@ android {
targetCompatibility = JavaVersion.VERSION_11
}
}

View file

@ -1,5 +1,7 @@
package com.nuvio.app.features.settings
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.AccountCircle
@ -9,6 +11,12 @@ import androidx.compose.material.icons.rounded.Notifications
import androidx.compose.material.icons.rounded.Palette
import androidx.compose.material.icons.rounded.People
import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.nuvio.app.core.build.AppVersionConfig
internal fun LazyListScope.settingsRootContent(
isTablet: Boolean,
@ -109,4 +117,15 @@ internal fun LazyListScope.settingsRootContent(
}
}
}
item {
Text(
text = "Version ${AppVersionConfig.VERSION_NAME} (${AppVersionConfig.VERSION_CODE})",
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp, vertical = if (isTablet) 20.dp else 16.dp),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
)
}
}

View file

@ -1,7 +1,6 @@
#include? "Version.xcconfig"
TEAM_ID=
PRODUCT_NAME=Nuvio
PRODUCT_BUNDLE_IDENTIFIER=com.nuvio.app.Nuvio$(TEAM_ID)
CURRENT_PROJECT_VERSION=1
MARKETING_VERSION=1.0
PRODUCT_BUNDLE_IDENTIFIER=com.nuvio.app.Nuvio$(TEAM_ID)

View file

@ -0,0 +1,2 @@
CURRENT_PROJECT_VERSION=2
MARKETING_VERSION=0.1.0-beta