From 4ce6a59c67978077e9667f392f8cbe8b76a1b165 Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Thu, 12 Dec 2024 20:09:46 +0100 Subject: [PATCH] Fix old version uploading to Maven Central Stage (#5185) Fixes https://youtrack.jetbrains.com/issue/CMP-1339/Change-description-of-androidx-artifacts-in-Maven-Central-stage Fixes https://youtrack.jetbrains.com/issue/CMP-7198/Maven-Central-publication-publishes-old-artifacts-for-Core-Bundle Related change on CI: https://jetbrains.team/p/ui/repositories/compose-teamcity-config/revision/94d34d0e Now it matches by wildcards. It doesn't fix the core issue - associating the exact library group with the exact artifacts, but fixing that requires decoupling maven central upload per project instead of comparing it by packages. It is not easy, as we not only have artifacts in compose-multiplatform-core - we have Gradle plugin, components, `compose-full`, Compose HTML. ## Testing Run CI on igor.demin/upload-to-maven-central-fixes branch Should be verified on the next 1.8.0-alpha02 release as well. --- ci/build-helpers/build.gradle.kts | 9 +++---- .../publishing/FindModulesInSpaceTask.kt | 27 ++++++++++++------- .../publishing/MavenCentralProperties.kt | 10 +++++-- .../publishing/UploadToSonatypeTask.kt | 8 +++--- .../publishing/utils/ModuleValidator.kt | 5 ---- .../publishing/utils/SpaceApiClient.kt | 4 ++- 6 files changed, 35 insertions(+), 28 deletions(-) diff --git a/ci/build-helpers/build.gradle.kts b/ci/build-helpers/build.gradle.kts index b3074877cdb..c9e76d0f79c 100644 --- a/ci/build-helpers/build.gradle.kts +++ b/ci/build-helpers/build.gradle.kts @@ -5,8 +5,6 @@ plugins { } val mavenCentral = MavenCentralProperties(project) -val mavenCentralGroup = project.providers.gradleProperty("maven.central.group") -val mavenCentralStage = project.providers.gradleProperty("maven.central.stage") if (mavenCentral.signArtifacts) { signing.useInMemoryPgpKeys( mavenCentral.signArtifactsKey.get(), @@ -20,8 +18,7 @@ val preparedArtifactsRoot = publishingDir.map { it.dir("prepared") } val modulesFile = publishingDir.map { it.file("modules.txt") } val findComposeModules by tasks.registering(FindModulesInSpaceTask::class) { - requestedGroupId.set(mavenCentralGroup) - requestedVersion.set(mavenCentral.version) + requestedCoordinates.set(mavenCentral.coordinates) spaceInstanceUrl.set("https://public.jetbrains.space") spaceClientId.set(System.getenv("COMPOSE_REPO_USERNAME") ?: "") spaceClientSecret.set(System.getenv("COMPOSE_REPO_KEY") ?: "") @@ -50,14 +47,14 @@ val fixModulesBeforePublishing by tasks.registering(FixModulesBeforePublishingTa val reuploadArtifactsToMavenCentral by tasks.registering(UploadToSonatypeTask::class) { dependsOn(fixModulesBeforePublishing) - version.set(mavenCentral.version) modulesToUpload.set(project.provider { readComposeModules(modulesFile, preparedArtifactsRoot) }) sonatypeServer.set("https://oss.sonatype.org") user.set(mavenCentral.user) password.set(mavenCentral.password) autoCommitOnSuccess.set(mavenCentral.autoCommitOnSuccess) - stagingProfileName.set(mavenCentralStage) + stagingProfileName.set(mavenCentral.stage) + stagingDescription.set(mavenCentral.description) } fun readComposeModules( diff --git a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/FindModulesInSpaceTask.kt b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/FindModulesInSpaceTask.kt index 92f552e2dbc..08dbbea1c8f 100644 --- a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/FindModulesInSpaceTask.kt +++ b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/FindModulesInSpaceTask.kt @@ -13,15 +13,14 @@ import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.jetbrains.compose.internal.publishing.utils.SpaceApiClient +import org.jetbrains.compose.internal.publishing.utils.SpaceApiClient.PackageInfo import space.jetbrains.api.runtime.types.PackageRepositoryIdentifier import space.jetbrains.api.runtime.types.ProjectIdentifier +import java.util.regex.Pattern abstract class FindModulesInSpaceTask : DefaultTask() { @get:Input - abstract val requestedGroupId: Property - - @get:Input - abstract val requestedVersion: Property + abstract val requestedCoordinates: Property @get:Input abstract val spaceInstanceUrl: Property @@ -52,11 +51,14 @@ abstract class FindModulesInSpaceTask : DefaultTask() { val projectId = ProjectIdentifier.Id(spaceProjectId.get()) val repoId = PackageRepositoryIdentifier.Id(spaceRepoId.get()) val modules = ArrayList() - val requestedGroupId = requestedGroupId.get() - val requestedVersion = requestedVersion.get() - space.forEachPackageWithVersion(projectId, repoId, requestedVersion) { pkg -> - if (pkg.groupId.startsWith(requestedGroupId)) { - modules.add("${pkg.groupId}:${pkg.artifactId}:${pkg.version}") + val requestedCoordinates = requestedCoordinates.get().split(",") + requestedCoordinates.forEach { req -> + val version = req.substringAfterLast(":") // suppose we don't support wildcards in version + space.forEachPackageWithVersion(projectId, repoId, version) { pkg -> + val pkgStr = pkg.toString() + if (pkgStr.matchesWildcard(req)) { + modules.add(pkgStr) + } } } @@ -65,4 +67,9 @@ abstract class FindModulesInSpaceTask : DefaultTask() { writeText(modules.joinToString("\n")) } } -} \ No newline at end of file +} + +private fun String.matchesWildcard(pattern: String): Boolean = "\\Q$pattern\\E" + .replace("*", "\\E.*\\Q") + .toRegex() + .matches(this) diff --git a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/MavenCentralProperties.kt b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/MavenCentralProperties.kt index 576041d780d..c464eeaaa4b 100644 --- a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/MavenCentralProperties.kt +++ b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/MavenCentralProperties.kt @@ -10,8 +10,14 @@ import org.gradle.api.provider.Provider @Suppress("unused") // public api class MavenCentralProperties(private val myProject: Project) { - val version: Provider = - propertyProvider("maven.central.version") + val coordinates: Provider = + propertyProvider("maven.central.coordinates") + + val stage: Provider = + propertyProvider("maven.central.stage") + + val description: Provider = + propertyProvider("maven.central.description") val user: Provider = propertyProvider("maven.central.user", envVar = "MAVEN_CENTRAL_USER") diff --git a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/UploadToSonatypeTask.kt b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/UploadToSonatypeTask.kt index 901a2b330aa..7602814d890 100644 --- a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/UploadToSonatypeTask.kt +++ b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/UploadToSonatypeTask.kt @@ -28,10 +28,10 @@ abstract class UploadToSonatypeTask : DefaultTask() { abstract val stagingProfileName: Property @get:Internal - abstract val autoCommitOnSuccess: Property + abstract val stagingDescription: Property @get:Internal - abstract val version: Property + abstract val autoCommitOnSuccess: Property @get:Internal abstract val modulesToUpload: ListProperty @@ -59,7 +59,7 @@ abstract class UploadToSonatypeTask : DefaultTask() { validate(stagingProfile, modules) val stagingRepo = sonatype.createStagingRepo( - stagingProfile, "Staging repo for '${stagingProfile.name}' release '${version.get()}'" + stagingProfile, stagingDescription.get() ) try { for (module in modules) { @@ -76,7 +76,7 @@ abstract class UploadToSonatypeTask : DefaultTask() { private fun validate(stagingProfile: StagingProfile, modules: List) { val validationIssues = arrayListOf>() for (module in modules) { - val status = ModuleValidator(stagingProfile, module, version.get()).validate() + val status = ModuleValidator(stagingProfile, module).validate() if (status is ModuleValidator.Status.Error) { validationIssues.add(module to status) } diff --git a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/ModuleValidator.kt b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/ModuleValidator.kt index 0188674d8b7..812a7435d69 100644 --- a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/ModuleValidator.kt +++ b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/ModuleValidator.kt @@ -12,7 +12,6 @@ import java.io.File internal class ModuleValidator( private val stagingProfile: StagingProfile, private val module: ModuleToUpload, - private val version: String ) { private val errors = arrayListOf() private var status: Status? = null @@ -37,10 +36,6 @@ internal class ModuleValidator( errors.add("Module's group id '${module.groupId}' does not match staging repo '${stagingProfile.name}'") } - if (module.version != version) { - errors.add("Unexpected version '${module.version}' (expected: '$version')") - } - val pomFile = artifactFile(extension = "pom") val pom = when { pomFile.exists() -> diff --git a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/SpaceApiClient.kt b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/SpaceApiClient.kt index 77ae75945a5..7f18e44689a 100644 --- a/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/SpaceApiClient.kt +++ b/ci/build-helpers/buildSrc/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/SpaceApiClient.kt @@ -21,7 +21,9 @@ internal class SpaceApiClient( val groupId: String, val artifactId: String, val version: String - ) + ) { + override fun toString() = "$groupId:$artifactId:$version" + } fun forEachPackageWithVersion( projectId: ProjectIdentifier,