plugins { alias(libs.plugins.kotlin.multiplatform) apply false alias(libs.plugins.kotlin.jvm) apply false alias(libs.plugins.kotlin.serialization) apply false // maven-publish — стандартный плагин Gradle, объявлен apply'ем в subprojects ниже. } group = "pw.binom.agentik" // projectVersion определяется ниже как val, чтобы subprojects могли его // прочитать через rootProject.extra["projectVersion"]. // Publication version: -Pversion= (CICD publishes by release tag) с // fallback в gradle.properties ("version=0.1.0"). Без версии maven-publish падает // с "Invalid publication 'kotlinMultiplatform': version cannot be empty" — // это известный gotcha: subprojects читают rootProject.version ДО того, как // if-блок ниже успевает его установить. Фикс: provider+orElse вычисляется // eagerly, и subprojects получают готовую строку. val projectVersion: String = providers.gradleProperty("version") .map { it.trimStart('v', 'V') } // strip optional "v" prefix from tag .getOrElse("0.1.0") version = projectVersion extra["projectVersion"] = projectVersion // Home Nexus URL/creds — передаются через -Pbinom.repo.* из CI/CD workflow // (.gitea/workflows/release.yml). Локально для дебага: // ./gradlew publish -Pbinom.repo.url=http://... -Pbinom.repo.user=... -Pbinom.repo.password=... // Без -P URL падает на дефолтный placeholder (заглушка для локальной разработки). val binomRepoUrl = (findProperty("binom.repo.url") as String? ?: "http://nexus.xx/repository/caffeine/").toString() val binomRepoUser = (findProperty("binom.repo.user") as String? ?: "").toString() val binomRepoPassword = (findProperty("binom.repo.password") as String? ?: "").toString() subprojects { group = rootProject.group // KMP-плагин читает project.version на ранней стадии evaluation — ДО того // как сработает внешний subprojects-блок. Если version ещё "unspecified", // publication 'kotlinMultiplatform' создаётся с пустой version, и тогда // maven-publish падает с 'InvalidMavenPublicationException: version cannot // be empty'. Поэтому: // 1) eagerly переопределяем version в rootProject.extra (см. выше) // 2) на КАЖДЫЙ subproject вешаем beforeEvaluate, который выставляет // version до того, как KMP-плагин начнёт создавать publications. beforeEvaluate { version = rootProject.extra["projectVersion"] as String } apply(plugin = "maven-publish") extensions.configure("publishing") { repositories { maven { name = "caffeine" url = uri(binomRepoUrl) isAllowInsecureProtocol = true credentials { username = binomRepoUser password = binomRepoPassword } } } // Per-subproject POM-метаданные (name, scm, licenses, developers). // Также явно выставляем version/group для каждой публикации. В KMP-модулях // (особенно JVM-only с одним jvm() target) kotlin-multiplatform plugin // создаёт publication 'kotlinMultiplatform' на ранней стадии evaluation, // когда project.version ещё 'unspecified'. Простое присваивание // subprojects { version = ... } НЕ перезаписывает уже зафиксированную // version в publication → InvalidMavenPublicationException в CI. // Явная установка version здесь гарантирует, что публикация всегда // использует актуальное значение из rootProject.extra. publications.withType().configureEach { val v = rootProject.extra["projectVersion"] as String println("DEBUG-CFG publication=${this.name} project=${project.name} setting version=$v (was=$version)") groupId = rootProject.group.toString() artifactId = project.name version = v pom { name = project.name description = providers.provider { project.findProperty("description")?.toString() ?: "agentik: ${project.name} (pw.binom.agentik)" } url = "https://git.binom.pw/subochev/agentik" licenses { license { name = "Apache-2.0" url = "https://www.apache.org/licenses/LICENSE-2.0" } } developers { developer { id = "subochev" name = "Subochev Alexey" url = "https://git.binom.pw/subochev" } } scm { connection = "scm:git:https://git.binom.pw/subochev/agentik.git" developerConnection = "scm:git:ssh://git@git.binom.pw/subochev/agentik.git" url = "https://git.binom.pw/subochev/agentik" } } } } }