Skip to content

Commit

Permalink
add dropRepository task (#478)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielittner committed Dec 26, 2022
1 parent db9392a commit 2c1f3dd
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 16 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Expand Up @@ -19,7 +19,12 @@ Updated docs can be found on [the new website](https://vanniktech.github.io/grad
please use the new `coordinates` method instead.
- The `GROUP` and `VERSION_NAME` Gradle properties will not be explicitly set as `project.group` and
`project.version` anymore.
- Fix publishing Kotlin/JS project with the base plugin.
- **NEW**: Added `dropRepository` task that will drop a Sonatype staging repository. It is possible to specify
which repository to drop by adding a `--repository` parameter with the id of the staging repository that was
printed during `publish`. If no repository is specified and there is only one staging repository, that one
will be dropped.
- Fixed publishing Kotlin/JS projects with the base plugin.
- Fixed that a POM configured through the DSL is incomplete when publishing Gradle plugins.
- The minimum supported Gradle version has been increased to 7.3.

Version 0.22.0 *(2022-09-09)*
Expand Down
Expand Up @@ -261,6 +261,11 @@ class Nexus(
}
}

fun dropCurrentStagingRepository() {
val stagingRepository = findStagingRepository()
dropStagingRepository(stagingRepository.repositoryId)
}

companion object {
private const val PROGRESS_1 = "\u2839"
private const val PROGRESS_2 = "\u2838"
Expand Down
Expand Up @@ -2,6 +2,7 @@ package com.vanniktech.maven.publish

import com.vanniktech.maven.publish.sonatype.CloseAndReleaseSonatypeRepositoryTask.Companion.registerCloseAndReleaseRepository
import com.vanniktech.maven.publish.sonatype.CreateSonatypeRepositoryTask.Companion.registerCreateRepository
import com.vanniktech.maven.publish.sonatype.DropSonatypeRepositoryTask.Companion.registerDropRepository
import com.vanniktech.maven.publish.sonatype.SonatypeRepositoryBuildService.Companion.registerSonatypeRepositoryBuildService
import org.gradle.api.Action
import org.gradle.api.Incubating
Expand All @@ -12,8 +13,6 @@ import org.gradle.api.publish.maven.MavenPom
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
import org.gradle.build.event.BuildEventsListenerRegistry
import org.gradle.configurationcache.extensions.serviceOf
import org.gradle.plugins.signing.Sign
import org.gradle.plugins.signing.SigningPlugin
import org.gradle.util.GradleVersion
Expand Down Expand Up @@ -54,15 +53,12 @@ abstract class MavenPublishBaseExtension(
sonatypeHost.set(host)
sonatypeHost.finalizeValue()

val buildService = project.gradle
.sharedServices
.registerSonatypeRepositoryBuildService(
sonatypeHost = sonatypeHost,
repositoryUsername = project.providers.gradleProperty("mavenCentralUsername"),
repositoryPassword = project.providers.gradleProperty("mavenCentralPassword"),
automaticRelease = automaticRelease,
)
project.serviceOf<BuildEventsListenerRegistry>().onTaskCompletion(buildService)
val buildService = project.registerSonatypeRepositoryBuildService(
sonatypeHost = sonatypeHost,
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)
Expand All @@ -81,6 +77,7 @@ abstract class MavenPublishBaseExtension(
}

project.tasks.registerCloseAndReleaseRepository(buildService)
project.tasks.registerDropRepository(buildService)
}

/**
Expand Down Expand Up @@ -211,7 +208,7 @@ abstract class MavenPublishBaseExtension(
@Incubating
fun pom(configure: Action<in MavenPom>) {
project.mavenPublications { publication ->
// without afterEvaluate https://github.com/gradle/gradle/issues/12259 will happen
// TODO without afterEvaluate https://github.com/gradle/gradle/issues/12259 will happen
project.afterEvaluate {
publication.pom(configure)
}
Expand Down
@@ -0,0 +1,57 @@
package com.vanniktech.maven.publish.sonatype

import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.options.Option

internal abstract class DropSonatypeRepositoryTask : DefaultTask() {

@get:Internal
abstract val buildService: Property<SonatypeRepositoryBuildService>

@Option(option = "repository", description = "Specify which staging repository to drop.")
@Input
@Optional
var manualStagingRepositoryId: String? = null

@TaskAction
fun closeAndReleaseRepository() {
val service = this.buildService.get()

// if repository was already dropped in this build this is a no-op
if (service.repositoryDropped) {
return
}

val manualStagingRepositoryId = this.manualStagingRepositoryId
if (manualStagingRepositoryId != null) {
service.nexus.dropStagingRepository(manualStagingRepositoryId)
} else {
service.nexus.dropCurrentStagingRepository()
}

service.repositoryDropped = true
}

companion object {
private const val NAME = "dropRepository"

fun TaskContainer.registerDropRepository(
buildService: Provider<SonatypeRepositoryBuildService>,
): TaskProvider<DropSonatypeRepositoryTask> {
return register(NAME, DropSonatypeRepositoryTask::class.java) {
it.description = "Drops a staging repository on Sonatype OSS"
it.group = "release"
it.buildService.set(buildService)
it.usesService(buildService)
}
}
}
}
Expand Up @@ -4,13 +4,15 @@ import com.vanniktech.maven.publish.BuildConfig
import com.vanniktech.maven.publish.SonatypeHost
import com.vanniktech.maven.publish.nexus.Nexus
import java.io.IOException
import org.gradle.api.Project
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.api.services.BuildServiceRegistry
import org.gradle.build.event.BuildEventsListenerRegistry
import org.gradle.configurationcache.extensions.serviceOf
import org.gradle.tooling.events.FailureResult
import org.gradle.tooling.events.FinishEvent
import org.gradle.tooling.events.OperationCompletionListener
Expand Down Expand Up @@ -51,6 +53,10 @@ internal abstract class SonatypeRepositoryBuildService : BuildService<SonatypeRe
// indicates whether we already closed a staging repository to avoid doing it more than once in a build
var repositoryClosed: Boolean = false

// should only be accessed from DropSonatypeRepositoryTask
// indicates whether we already closed a staging repository to avoid doing it more than once in a build
var repositoryDropped: Boolean = false

private var buildIsSuccess: Boolean = true

override fun onFinish(event: FinishEvent) {
Expand Down Expand Up @@ -80,19 +86,22 @@ internal abstract class SonatypeRepositoryBuildService : BuildService<SonatypeRe
companion object {
private const val NAME = "sonatype-repository-build-service"

fun BuildServiceRegistry.registerSonatypeRepositoryBuildService(
@Suppress("UnstableApiUsage")
fun Project.registerSonatypeRepositoryBuildService(
sonatypeHost: Provider<SonatypeHost>,
repositoryUsername: Provider<String>,
repositoryPassword: Provider<String>,
automaticRelease: Boolean,
): Provider<SonatypeRepositoryBuildService> {
return registerIfAbsent(NAME, SonatypeRepositoryBuildService::class.java) {
val service = gradle.sharedServices.registerIfAbsent(NAME, SonatypeRepositoryBuildService::class.java) {
it.maxParallelUsages.set(1)
it.parameters.sonatypeHost.set(sonatypeHost)
it.parameters.repositoryUsername.set(repositoryUsername)
it.parameters.repositoryPassword.set(repositoryPassword)
it.parameters.automaticRelease.set(automaticRelease)
}
project.serviceOf<BuildEventsListenerRegistry>().onTaskCompletion(service)
return service
}
}
}

0 comments on commit 2c1f3dd

Please sign in to comment.