Skip to content

Instantly share code, notes, and snippets.

@vasmarfas
Created May 28, 2025 08:03
Show Gist options
  • Save vasmarfas/a2ccfda18d77b83f9ca92eb2193558b0 to your computer and use it in GitHub Desktop.
Save vasmarfas/a2ccfda18d77b83f9ca92eb2193558b0 to your computer and use it in GitHub Desktop.
Автоматическое обновление управление/обновление версии приложения из одного файла mainProjectVersion.txt, который расположен в корне проекта. Таска градла будет зарегистрирована и выполняется перед каждой сборкой - берёт версию из txt файла и подставляет везде где нужно в plist/pbxproj, в т.ч. там, где ожидается код версии в числовом, а не строч…
...
android {
namespace = "com.example.app"
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("src/androidMain/res")
sourceSets["main"].resources.srcDirs("src/commonMain/resources")
defaultConfig {
applicationId = "com.example.app"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
versionCode = rootProject.extra["projectVersionCode"] as Int
versionName = rootProject.extra["projectVersionName"] as String
}
//Plugins
...
// Чтение версии из файла mainProjectVersion.txt
val versionFile = file("mainProjectVersion.txt")
val projectVersionString = if (versionFile.exists()) {
versionFile.readText().trim()
} else {
"1.0.0"
}
// Создание различных форматов версии
val versionParts = projectVersionString.split(".")
val versionCode = if (versionParts.size >= 3) {
val major = versionParts[0].toIntOrNull() ?: 1
val minor = versionParts[1].toIntOrNull() ?: 0
val patch = versionParts[2].toIntOrNull() ?: 0
String.format("%d%02d%02d", major, minor, patch).toInt()
} else {
10000
}
// Создание экстра-свойств для использования в подпроектах
extra["projectVersionName"] = projectVersionString
extra["projectVersionCode"] = versionCode
println("Project version: $projectVersionString (code: $versionCode)")
// Task для обновления версий в iOS файлах
tasks.register("updateiOSVersions") {
description = "Updates version numbers in iOS project files"
group = "versioning"
doLast {
val versionName = projectVersionString
val versionCodeValue = versionCode
// Обновление iosApp/iosApp.xcodeproj/project.pbxproj
val pbxprojFile = file("iosApp/iosApp.xcodeproj/project.pbxproj")
if (pbxprojFile.exists()) {
var content = pbxprojFile.readText()
content = content.replace(Regex("MARKETING_VERSION = [^;]+;"), "MARKETING_VERSION = $versionName;")
content = content.replace(Regex("CURRENT_PROJECT_VERSION = [^;]+;"), "CURRENT_PROJECT_VERSION = $versionCodeValue;")
pbxprojFile.writeText(content)
println("Updated iosApp/iosApp.xcodeproj/project.pbxproj")
}
// Обновление iosApp/iosApp/Info.plist
val infoPlistFile = file("iosApp/iosApp/Info.plist")
if (infoPlistFile.exists()) {
var content = infoPlistFile.readText()
content = content.replace(Regex("<key>CFBundleShortVersionString</key>\\s*<string>[^<]+</string>"),
"<key>CFBundleShortVersionString</key>\n\t<string>$versionName</string>")
content = content.replace(Regex("<key>CFBundleVersion</key>\\s*<string>[^<]+</string>"),
"<key>CFBundleVersion</key>\n\t<string>$versionCodeValue</string>")
infoPlistFile.writeText(content)
println("Updated iosApp/iosApp/Info.plist")
}
// Обновление iosApp-old/iosApp.xcodeproj/project.pbxproj (если существует)
val oldPbxprojFile = file("iosApp-old/iosApp.xcodeproj/project.pbxproj")
if (oldPbxprojFile.exists()) {
var content = oldPbxprojFile.readText()
content = content.replace(Regex("MARKETING_VERSION = [^;]+;"), "MARKETING_VERSION = $versionName;")
content = content.replace(Regex("CURRENT_PROJECT_VERSION = [^;]+;"), "CURRENT_PROJECT_VERSION = $versionCodeValue;")
oldPbxprojFile.writeText(content)
println("Updated iosApp-old/iosApp.xcodeproj/project.pbxproj")
}
// Обновление iosApp-old/iosApp/Info.plist (если существует)
val oldInfoPlistFile = file("iosApp-old/iosApp/Info.plist")
if (oldInfoPlistFile.exists()) {
var content = oldInfoPlistFile.readText()
content = content.replace(Regex("<key>CFBundleShortVersionString</key>\\s*<string>[^<]+</string>"),
"<key>CFBundleShortVersionString</key>\n\t<string>$versionName</string>")
content = content.replace(Regex("<key>CFBundleVersion</key>\\s*<string>[^<]+</string>"),
"<key>CFBundleVersion</key>\n\t<string>$versionCodeValue</string>")
oldInfoPlistFile.writeText(content)
println("Updated iosApp-old/iosApp/Info.plist")
}
}
}
// Автоматическое выполнение updateiOSVersions при сборке
allprojects {
afterEvaluate {
tasks.matching { task ->
task.name in listOf(
"build", "assemble", "assembleDebug", "assembleRelease",
"packageDebug", "packageRelease", "bundleDebug", "bundleRelease",
"linkDebugFrameworkIosArm64", "linkReleaseFrameworkIosArm64",
"linkDebugFrameworkIosX64", "linkReleaseFrameworkIosX64",
"linkDebugFrameworkIosSimulatorArm64", "linkReleaseFrameworkIosSimulatorArm64",
"packageDebugUniversalApk", "packageReleaseUniversalApk",
"createDistributable", "packageDistributionForCurrentOS",
"packageDmg", "packagePkg", "packageMsi", "packageDeb", "packageExe"
) || task.name.startsWith("assemble") ||
task.name.startsWith("bundle") ||
task.name.startsWith("package") ||
task.name.startsWith("link") ||
task.name.startsWith("create")
}.configureEach {
dependsOn(rootProject.tasks.named("updateiOSVersions"))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment