diff --git a/README.md b/README.md index c906e93b..515bcf1f 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,26 @@ So the steps to publish and release in different Gradle invocations are: (in the above example, steps 1 and 2 could be also combined into `./gradlew publishToSonatype closeSonatypeStagingRepository`, to make only the releasing done in a separate step) +### Summary Tasks + +If you declare multiple repositories, you get a separate set of tasks for each of the repositories. +If you for example declared the repositories `sonatype` and `otherNexus`, you get these tasks: +- `closeSonatypeStagingRepository` +- `closeOtherNexusStagingRepository` +- `releaseSonatypeStagingRepository` +- `releaseOtherNexusStagingRepository` +- `closeAndReleaseSonatypeStagingRepository` +- `closeAndReleaseOtherNexusStagingRepository` + +For convenience there are also summary tasks generated, that group the tasks for the different repositories, which are +- `closeStagingRepository` +- `releaseStagingRepository` +- `closeAndReleaseStagingRepository` + +In the typical use-case, which is only one repository for publishing to Maven Central, these tasks still are useful, +especially if you are using Kotlin DSL build scripts, because those summary tasks are always added, independent of +declared repositories. Due to that there are type-safe accessors generated that can be used conveniently for task dependencies. + ### Full example #### Groovy DSL diff --git a/src/main/kotlin/io/github/gradlenexus/publishplugin/NexusPublishPlugin.kt b/src/main/kotlin/io/github/gradlenexus/publishplugin/NexusPublishPlugin.kt index 313b4d26..78f70181 100644 --- a/src/main/kotlin/io/github/gradlenexus/publishplugin/NexusPublishPlugin.kt +++ b/src/main/kotlin/io/github/gradlenexus/publishplugin/NexusPublishPlugin.kt @@ -45,8 +45,9 @@ import java.time.Duration class NexusPublishPlugin : Plugin { companion object { - // visibility for testing - const val SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME = "closeAndReleaseStagingRepository" + private const val SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME = "closeAndReleaseStagingRepository" + private const val SIMPLIFIED_CLOSE_TASK_NAME = "closeStagingRepository" + private const val SIMPLIFIED_RELEASE_TASK_NAME = "releaseStagingRepository" } override fun apply(project: Project) { @@ -125,10 +126,17 @@ class NexusPublishPlugin : Plugin { enabled = false } } - rootProject.tasks.register(SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME) { + rootProject.tasks.register(SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME) { group = PublishingPlugin.PUBLISH_TASK_GROUP description = "Closes and releases open staging repositories in all configured Nexus instances." - enabled = false + } + rootProject.tasks.register(SIMPLIFIED_CLOSE_TASK_NAME) { + group = PublishingPlugin.PUBLISH_TASK_GROUP + description = "Closes open staging repositories in all configured Nexus instances." + } + rootProject.tasks.register(SIMPLIFIED_RELEASE_TASK_NAME) { + group = PublishingPlugin.PUBLISH_TASK_GROUP + description = "Releases open staging repositories in all configured Nexus instances." } } @@ -235,7 +243,7 @@ class NexusPublishPlugin : Plugin { } } } - configureSimplifiedCloseAndReleaseTask(rootProject, extension) + configureSimplifiedCloseAndReleaseTasks(rootProject, extension) } } @@ -346,25 +354,37 @@ class NexusPublishPlugin : Plugin { } } - private fun configureSimplifiedCloseAndReleaseTask(rootProject: Project, extension: NexusPublishExtension) { + private fun configureSimplifiedCloseAndReleaseTasks(rootProject: Project, extension: NexusPublishExtension) { if (extension.repositories.isNotEmpty()) { - val closeAndReleaseSimplifiedTask = rootProject.tasks.named(SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME) - closeAndReleaseSimplifiedTask.configure { - val repositoryNamesAsString = extension.repositories.joinToString(", ") { "'${it.name}'" } - val instanceCardinalityAwareString = if (extension.repositories.size > 1) { - "instances" - } else { - "instance" - } + val repositoryNamesAsString = extension.repositories.joinToString(", ") { "'${it.name}'" } + val instanceCardinalityAwareString = if (extension.repositories.size > 1) { + "instances" + } else { + "instance" + } + val closeAndReleaseSimplifiedTask = rootProject.tasks.named(SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME) { description = "Closes and releases open staging repositories in the following Nexus $instanceCardinalityAwareString: $repositoryNamesAsString" - enabled = true + } + val closeSimplifiedTask = rootProject.tasks.named(SIMPLIFIED_CLOSE_TASK_NAME) { + description = "Closes open staging repositories in the following Nexus $instanceCardinalityAwareString: $repositoryNamesAsString" + } + val releaseSimplifiedTask = rootProject.tasks.named(SIMPLIFIED_RELEASE_TASK_NAME) { + description = "Releases open staging repositories in the following Nexus $instanceCardinalityAwareString: $repositoryNamesAsString" } extension.repositories.all { val repositoryCapitalizedName = this.capitalizedName val closeAndReleaseTask = rootProject.tasks.named("closeAndRelease${repositoryCapitalizedName}StagingRepository") - closeAndReleaseSimplifiedTask.configure { + closeAndReleaseSimplifiedTask { dependsOn(closeAndReleaseTask) } + val closeTask = rootProject.tasks.named("close${repositoryCapitalizedName}StagingRepository") + closeSimplifiedTask { + dependsOn(closeTask) + } + val releaseTask = rootProject.tasks.named("release${repositoryCapitalizedName}StagingRepository") + releaseSimplifiedTask { + dependsOn(releaseTask) + } } } } diff --git a/src/test/kotlin/io/github/gradlenexus/publishplugin/TaskOrchestrationTest.kt b/src/test/kotlin/io/github/gradlenexus/publishplugin/TaskOrchestrationTest.kt index 9b64c7a4..98f367fa 100644 --- a/src/test/kotlin/io/github/gradlenexus/publishplugin/TaskOrchestrationTest.kt +++ b/src/test/kotlin/io/github/gradlenexus/publishplugin/TaskOrchestrationTest.kt @@ -31,7 +31,9 @@ import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.io.TempDir import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.CsvSource import org.junit.jupiter.params.provider.MethodSource +import org.junit.jupiter.params.provider.ValueSource import java.nio.file.Path @KotlinParameterizeTest @@ -93,44 +95,64 @@ class TaskOrchestrationTest { .contains("closeSonatypeStagingRepository", "releaseSonatypeStagingRepository") } - @Test - internal fun `simplified close and release task without repository name should be available but trigger nothing if no repositories are configured`() { + @ParameterizedTest(name = "{0}") + @ValueSource( + strings = [ + "closeAndReleaseStagingRepository", + "closeStagingRepository", + "releaseStagingRepository" + ] + ) + internal fun `simplified task without repository name should be available but trigger nothing if no repositories are configured`(simplifiedTaskName: String) { initSingleProjectWithDefaultConfiguration() project.extensions.configure { repositories.clear() } - val simplifiedCloseAndReleaseTasks = project.getTasksByName(NexusPublishPlugin.SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME, true) + val simplifiedTasks = project.getTasksByName(simplifiedTaskName, true) - assertThat(simplifiedCloseAndReleaseTasks).hasSize(1) - assertThat(simplifiedCloseAndReleaseTasks.first().dependsOn).isEmpty() + assertThat(simplifiedTasks).hasSize(1) + assertThat(simplifiedTasks.first().dependsOn).isEmpty() } - @Test - internal fun `simplified closeAndRelease task without repository name should depend on all closeAndRelease (created one per defined repository)`() { + @ParameterizedTest(name = "{0}") + @CsvSource( + textBlock = """ + closeAndReleaseStagingRepository, closeAndReleaseSonatypeStagingRepository, closeAndReleaseOtherNexusStagingRepository + closeStagingRepository , closeSonatypeStagingRepository , closeOtherNexusStagingRepository + releaseStagingRepository , releaseSonatypeStagingRepository , releaseOtherNexusStagingRepository""" + ) + internal fun `simplified task without repository name should depend on all normal tasks (created one per defined repository)`(simplifiedTaskName: String, sonatypeTaskName: String, otherNexusTaskName: String) { initSingleProjectWithDefaultConfiguration() project.extensions.configure { repositories.create("otherNexus") } - val closeAndReleaseTask = getJustOneTaskByNameOrFail(NexusPublishPlugin.SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME) + val simplifiedTasks = getJustOneTaskByNameOrFail(simplifiedTaskName) - assertThat(closeAndReleaseTask.taskDependencies.getDependencies(null).map { it.name }) + assertThat(simplifiedTasks.taskDependencies.getDependencies(null).map { it.name }) .hasSize(2) - .contains("closeAndReleaseSonatypeStagingRepository") - .contains("closeAndReleaseOtherNexusStagingRepository") + .contains(sonatypeTaskName) + .contains(otherNexusTaskName) } - @Test - internal fun `description of simplified closeAndRelease task contains names of all defined Nexus instances`() { + @ParameterizedTest(name = "{0}") + @ValueSource( + strings = [ + "closeAndReleaseStagingRepository", + "closeStagingRepository", + "releaseStagingRepository" + ] + ) + internal fun `description of simplified task contains names of all defined Nexus instances`(simplifiedTaskName: String) { initSingleProjectWithDefaultConfiguration() project.extensions.configure { repositories.create("otherNexus") } - val closeAndReleaseTask = getJustOneTaskByNameOrFail(NexusPublishPlugin.SIMPLIFIED_CLOSE_AND_RELEASE_TASK_NAME) + val simplifiedTasks = getJustOneTaskByNameOrFail(simplifiedTaskName) - assertThat(closeAndReleaseTask.description) + assertThat(simplifiedTasks.description) .contains("sonatype") .contains("otherNexus") }