Skip to content

Commit

Permalink
move repository creation to build service (#695)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielittner authored Jan 1, 2024
1 parent 6eff41b commit 94f54e1
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,22 @@ abstract class MavenPublishBaseExtension(

val buildService = project.registerSonatypeRepositoryBuildService(
sonatypeHost = sonatypeHost,
groupId = groupId,
versionIsSnapshot = version.map { it.endsWith("-SNAPSHOT") },
repositoryUsername = project.providers.gradleProperty("mavenCentralUsername"),
repositoryPassword = project.providers.gradleProperty("mavenCentralPassword"),
automaticRelease = automaticRelease,
)

val versionIsSnapshot = version.map { it.endsWith("-SNAPSHOT") }
val createRepository = project.tasks.registerCreateRepository(groupId, versionIsSnapshot, buildService)
val url = sonatypeHost.map { it.publishingUrl(versionIsSnapshot, buildService, project.configurationCache()) }

val configCacheEnabled = project.configurationCache()
project.gradlePublishing.repositories.maven { repo ->
repo.name = "mavenCentral"
repo.setUrl(url)
repo.setUrl(buildService.map { it.publishingUrl(configCacheEnabled) })
repo.credentials(PasswordCredentials::class.java)
}

val createRepository = project.tasks.registerCreateRepository(buildService)

project.tasks.withType(PublishToMavenRepository::class.java).configureEach { publishTask ->
if (publishTask.name.endsWith("ToMavenCentralRepository")) {
publishTask.dependsOn(createRepository)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.vanniktech.maven.publish

import com.vanniktech.maven.publish.sonatype.SonatypeRepositoryBuildService
import java.io.Serializable
import org.gradle.api.provider.Provider

/**
* Describes the various hosts for Sonatype OSSRH. Depending on when a user signed up with Sonatype
Expand All @@ -17,31 +15,6 @@ data class SonatypeHost(
return "$rootUrl/service/local/"
}

internal fun publishingUrl(
snapshot: Provider<Boolean>,
buildService: Provider<SonatypeRepositoryBuildService>,
configCache: Boolean,
): String {
return if (snapshot.get()) {
require(buildService.get().stagingRepositoryId == null) {
"Staging repositories are not supported for SNAPSHOT versions."
}
"$rootUrl/content/repositories/snapshots/"
} else {
val stagingRepositoryId = buildService.get().stagingRepositoryId
requireNotNull(stagingRepositoryId) {
if (configCache) {
"Publishing releases to Maven Central is not supported yet with configuration caching enabled, because of " +
"this missing Gradle feature: https://github.com/gradle/gradle/issues/22779"
} else {
"The staging repository was not created yet. Please open a bug with a build scan or build logs and stacktrace"
}
}

"$rootUrl/service/local/staging/deployByRepositoryId/$stagingRepositoryId/"
}
}

companion object {
@JvmStatic
fun valueOf(sonatypeHost: String): SonatypeHost = when (sonatypeHost) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,51 +31,31 @@ internal abstract class CreateSonatypeRepositoryTask : DefaultTask() {
val workQueue: WorkQueue = getWorkerExecutor().noIsolation()
workQueue.submit(CreateStagingRepository::class.java) {
requireNotNull(it)
it.projectGroup.set(projectGroup)
it.versionIsSnapshot.set(versionIsSnapshot)
it.buildService.set(buildService)
}
}

internal interface CreateStagingRepositoryParameters : WorkParameters {
val projectGroup: Property<String>
val versionIsSnapshot: Property<Boolean>
val buildService: Property<SonatypeRepositoryBuildService>
}

abstract class CreateStagingRepository : WorkAction<CreateStagingRepositoryParameters?> {
override fun execute() {
val parameters = requireNotNull(parameters)
if (parameters.versionIsSnapshot.get()) {
return
}

val service = parameters.buildService.get()

// if repository was already created in this build this is a no-op
val currentStagingRepositoryId = service.stagingRepositoryId
if (currentStagingRepositoryId != null) {
return
}

val id = service.nexus.createRepositoryForGroup(parameters.projectGroup.get())
service.stagingRepositoryId = id
service.createStagingRepository()
}
}

companion object {
private const val NAME = "createStagingRepository"

fun TaskContainer.registerCreateRepository(
projectGroup: Provider<String>,
versionIsSnapshot: Provider<Boolean>,
buildService: Provider<SonatypeRepositoryBuildService>,
): TaskProvider<CreateSonatypeRepositoryTask> {
return register(NAME, CreateSonatypeRepositoryTask::class.java) {
it.description = "Create a staging repository on Sonatype OSS"
it.group = "release"
it.projectGroup.set(projectGroup)
it.versionIsSnapshot.set(versionIsSnapshot)
it.buildService.set(buildService)
it.usesService(buildService)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ internal abstract class SonatypeRepositoryBuildService :

internal interface Params : BuildServiceParameters {
val sonatypeHost: Property<SonatypeHost>
val groupId: Property<String>
val versionIsSnapshot: Property<Boolean>
val repositoryUsername: Property<String>
val repositoryPassword: Property<String>
val automaticRelease: Property<Boolean>
Expand All @@ -42,10 +44,7 @@ internal abstract class SonatypeRepositoryBuildService :
)
}

// should only be accessed from CreateSonatypeRepositoryTask
// for all other use cases use MavenPublishBaseExtension
// the id of the staging repository that was created during this build
var stagingRepositoryId: String? = null
private var stagingRepositoryId: String? = null
set(value) {
if (field != null) {
throw IllegalStateException("stagingRepositoryId was already set")
Expand All @@ -63,6 +62,41 @@ internal abstract class SonatypeRepositoryBuildService :

private var buildIsSuccess: Boolean = true

/**
* Is only be allowed to be called from task actions.
*/
fun createStagingRepository() {
if (parameters.versionIsSnapshot.get()) {
return
}

if (stagingRepositoryId != null) {
return
}

this.stagingRepositoryId = nexus.createRepositoryForGroup(parameters.groupId.get())
}

internal fun publishingUrl(configCacheEnabled: Boolean): String {
return if (parameters.versionIsSnapshot.get()) {
require(stagingRepositoryId == null) {
"Staging repositories are not supported for SNAPSHOT versions."
}
"${parameters.sonatypeHost.get().rootUrl}/content/repositories/snapshots/"
} else {
val stagingRepositoryId = requireNotNull(stagingRepositoryId) {
if (configCacheEnabled) {
"Publishing releases to Maven Central is not supported yet with configuration caching enabled, because of " +
"this missing Gradle feature: https://github.com/gradle/gradle/issues/22779"
} else {
"The staging repository was not created yet. Please open a bug with a build scan or build logs and stacktrace"
}
}

"${parameters.sonatypeHost.get().rootUrl}/service/local/staging/deployByRepositoryId/$stagingRepositoryId/"
}
}

override fun onFinish(event: FinishEvent) {
if (event.result is FailureResult) {
buildIsSuccess = false
Expand Down Expand Up @@ -92,6 +126,8 @@ internal abstract class SonatypeRepositoryBuildService :

fun Project.registerSonatypeRepositoryBuildService(
sonatypeHost: Provider<SonatypeHost>,
groupId: Provider<String>,
versionIsSnapshot: Provider<Boolean>,
repositoryUsername: Provider<String>,
repositoryPassword: Provider<String>,
automaticRelease: Boolean,
Expand All @@ -105,6 +141,8 @@ internal abstract class SonatypeRepositoryBuildService :
val service = gradle.sharedServices.registerIfAbsent(NAME, SonatypeRepositoryBuildService::class.java) {
it.maxParallelUsages.set(1)
it.parameters.sonatypeHost.set(sonatypeHost)
it.parameters.groupId.set(groupId)
it.parameters.versionIsSnapshot.set(versionIsSnapshot)
it.parameters.repositoryUsername.set(repositoryUsername)
it.parameters.repositoryPassword.set(repositoryPassword)
it.parameters.automaticRelease.set(automaticRelease)
Expand Down

0 comments on commit 94f54e1

Please sign in to comment.