diff --git a/.gitignore b/.gitignore index a0946fe67..2cd35d25c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,6 @@ captures **/xcshareddata/WorkspaceSettings.xcsettings node_modules/ logs/ -Docs \ No newline at end of file +Docs +keystore/ +scripts/build-distribution.sh diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 8b1347e8d..0c4e11738 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -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 + + @get:Input + abstract val appVersionCode: Property + @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("generateRuntimeConfigs") { outputDir.set(generatedRuntimeConfigDir) localPropertiesFile.set(rootProject.layout.projectDirectory.file("local.properties")) + appVersionName.set(releaseAppVersionName) + appVersionCode.set(releaseAppVersionCode) } tasks.withType>().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 } } - diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt index 7bf6051e5..6bebcbefb 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt @@ -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, + ) + } } diff --git a/iosApp/Configuration/Config.xcconfig b/iosApp/Configuration/Config.xcconfig index 6d83cc157..03336317b 100644 --- a/iosApp/Configuration/Config.xcconfig +++ b/iosApp/Configuration/Config.xcconfig @@ -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 \ No newline at end of file +PRODUCT_BUNDLE_IDENTIFIER=com.nuvio.app.Nuvio$(TEAM_ID) \ No newline at end of file diff --git a/iosApp/Configuration/Version.xcconfig b/iosApp/Configuration/Version.xcconfig new file mode 100644 index 000000000..887a4c15c --- /dev/null +++ b/iosApp/Configuration/Version.xcconfig @@ -0,0 +1,2 @@ +CURRENT_PROJECT_VERSION=2 +MARKETING_VERSION=0.1.0-beta \ No newline at end of file