diff --git a/build.gradle.kts b/build.gradle.kts index 465885ab7c2..7a947d42797 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -540,16 +540,7 @@ allprojects { } } -apply { - from("libraries/commonConfiguration.gradle") -} - -if (extra.has("isDeployStagingRepoGenerationRequired") && - project.extra["isDeployStagingRepoGenerationRequired"] as Boolean == true -) { - logger.info("Applying configuration for sonatype release") - project.apply { from("libraries/prepareSonatypeStaging.gradle") } -} +preparePublication() gradle.taskGraph.whenReady { fun Boolean.toOnOff(): String = if (this) "on" else "off" diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f81ca1c6b1d..48e47f315c2 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -111,6 +111,8 @@ dependencies { implementation("net.sf.proguard:proguard-gradle:6.2.2") implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:1.0.1") + implementation("io.ktor:ktor-client-core:${rootProject.extra["versions.ktor-client-core"]}") + implementation("io.ktor:ktor-client-cio:${rootProject.extra["versions.ktor-client-cio"]}") compileOnly("com.gradle:gradle-enterprise-gradle-plugin:3.12.4") diff --git a/buildSrc/src/main/kotlin/preparePublication.kt b/buildSrc/src/main/kotlin/preparePublication.kt new file mode 100644 index 00000000000..430424c596c --- /dev/null +++ b/buildSrc/src/main/kotlin/preparePublication.kt @@ -0,0 +1,89 @@ +import io.ktor.client.* +import io.ktor.client.request.* +import io.ktor.client.statement.* +import io.ktor.http.* +import kotlinx.coroutines.runBlocking +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.kotlin.dsl.* + +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +fun Project.preparePublication() { + tasks.register("preparePublication") { + assert(project.version != "unspecified") + + val repositoryProviders = mapOf( + "sonatype-nexus-staging" to "sonatype", + "sonatype-nexus-snapshots" to "sonatype" + ) + val isRelease: Boolean by extra(!project.version.toString().contains("-SNAPSHOT")) + + val repo: String? = properties["deployRepo"]?.toString() ?: properties["deploy-repo"]?.toString() + val repoProvider = repositoryProviders.getOrDefault(repo, repo) + val isSonatypePublish: Boolean by extra(repoProvider == "sonatype") + val isSonatypeRelease: Boolean by extra(isSonatypePublish && isRelease) + + val deployRepoUrl = properties["deployRepoUrl"]?.toString() ?: properties["deploy-url"]?.toString() + val deployFolder = properties["deployRepoFolder"]?.toString() + ?.let { "file://${rootProject.buildDir}/$it" } + val sonatypeSnapshotsUrl = if (isSonatypePublish && !isRelease) { + "https://oss.sonatype.org/content/repositories/snapshots/" + } else { + null + } + val deployUrlFromParameters = deployRepoUrl ?: deployFolder ?: sonatypeSnapshotsUrl + + val isDeployStagingRepoGenerationRequired: Boolean by extra(isSonatypeRelease && deployUrlFromParameters == null) + + var repoUrl: String by extra((deployUrlFromParameters ?: "file://${rootProject.buildDir}/repo").toString()) + logger.info("Deployment repository preliminary url: $repoUrl ($repoProvider)") + + val username: String? by extra( + properties["deployRepoUsername"]?.toString() ?: properties["kotlin.${repoProvider}.user"]?.toString() + ) + val password: String? by extra( + properties["deployRepoPassword"]?.toString() ?: properties["kotlin.${repoProvider}.password"]?.toString() + ) + + if (isDeployStagingRepoGenerationRequired) { + doFirst { + HttpClient().use { client -> + runBlocking { + val sonatypeUsername = requireNotNull(username) { + "Username to authenticate on sonatype staging was not provided!" + } + val sonatypePassword = requireNotNull(password) { + "Password to authenticate on sonatype staging was not provided!" + } + + val response = client.post("https://oss.sonatype.org/service/local/staging/profiles/169b36e205a64e/start") { + basicAuth(sonatypeUsername, sonatypePassword) + contentType(ContentType.Application.Xml) + accept(ContentType.Application.Xml) + setBody("Repository for publishing $version") + } + + if (response.status.value in 200..299) { + val responseText = response.bodyAsText() + val repoId = responseText + .substringAfter("") + .substringBefore("") + repoUrl = "https://oss.sonatype.org/service/local/staging/deployByRepositoryId/$repoId/" + logger.warn("##teamcity[setParameter name='system.deploy-url' value='$repoUrl']") + } else { + throw GradleException("Failed to connect to sonatype API: ${response.status.description}") + } + } + } + } + } + + doLast { + logger.warn("Deployment repository url: $repoUrl") + } + } +} diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index eaa2eff28eb..7e471b22224 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -7383,12 +7383,24 @@ + + + + + + + + + + + + @@ -8667,12 +8679,24 @@ + + + + + + + + + + + + diff --git a/libraries/commonConfiguration.gradle b/libraries/commonConfiguration.gradle deleted file mode 100644 index c8c32707b3e..00000000000 --- a/libraries/commonConfiguration.gradle +++ /dev/null @@ -1,29 +0,0 @@ -task preparePublication { - def properties = project.properties - assert project.version != 'unspecified' - - Map repositoryProviders = ['sonatype-nexus-staging' : 'sonatype', 'sonatype-nexus-snapshots' : 'sonatype'] - project.ext.isRelease = !project.version.toString().contains('-SNAPSHOT') - - String repo = properties["deployRepo"] ?: properties['deploy-repo'] - String repoProvider = repositoryProviders.get(repo, repo) - project.ext.isSonatypePublish = repoProvider == 'sonatype' - project.ext.isSonatypeRelease = isSonatypePublish && isRelease - - String deployRepoUrl = properties["deployRepoUrl"] ?: properties["deploy-url"] - String deployFolder = properties["deployRepoFolder"] != null ? "file://${rootProject.buildDir}/${properties["deployRepoFolder"]}" : null - String sonatypeSnapshotsUrl = (isSonatypePublish && !isRelease) ? "https://oss.sonatype.org/content/repositories/snapshots/" : null - String deployUrlFromParameters = deployRepoUrl ?: deployFolder ?: sonatypeSnapshotsUrl - - project.ext.isDeployStagingRepoGenerationRequired = project.ext.isSonatypeRelease && deployUrlFromParameters == null - - ext.repoUrl = (deployUrlFromParameters ?: "file://${rootProject.buildDir}/repo").toString() - logger.info("Deployment repository preliminary url: ${ext.repoUrl} ($repoProvider)") - - ext.username = properties["deployRepoUsername"] ?: properties["kotlin.${repoProvider}.user"] - ext.password = properties["deployRepoPassword"] ?: properties["kotlin.${repoProvider}.password"] - - doLast { - println("Deployment repository url: ${ext.repoUrl}") - } -} diff --git a/libraries/prepareSonatypeStaging.gradle b/libraries/prepareSonatypeStaging.gradle deleted file mode 100644 index 9a5dc20e3a7..00000000000 --- a/libraries/prepareSonatypeStaging.gradle +++ /dev/null @@ -1,38 +0,0 @@ -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.2' - } -} -import groovyx.net.http.RESTClient - - -preparePublication { - doFirst { - def client = new RESTClient() - client.uri = 'https://oss.sonatype.org/service/local/staging/profiles/169b36e205a64e/start' - client.auth.basic(username, password) - - def params = [ - body: "Repository for publishing $version", - contentType: groovyx.net.http.ContentType.XML, - requestContentType: groovyx.net.http.ContentType.XML - ] - - def rootNode - try { - def serverResponse = client.post(params) - rootNode = serverResponse.getData() - } catch (groovyx.net.http.HttpResponseException e) { - throw new GradleException(e.getResponse().getData().toString(), e) - } - - def repoId = rootNode.data.stagedRepositoryId.text() - ext.repoUrl = "https://oss.sonatype.org/service/local/staging/deployByRepositoryId/$repoId/".toString() - println "##teamcity[setParameter name='system.deploy-url' value='${repoUrl}']" - } -} - -