Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dropRepository task #478

Merged
merged 1 commit into from Dec 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -259,6 +259,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 @@ -3,13 +3,15 @@ package com.vanniktech.maven.publish.sonatype
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 @@ -48,6 +50,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 @@ -77,19 +83,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
}
}
}