diff --git a/.github/workflows/gradle-test.pr.yml b/.github/workflows/gradle-test.pr.yml index 2471033724..cacfdbb739 100644 --- a/.github/workflows/gradle-test.pr.yml +++ b/.github/workflows/gradle-test.pr.yml @@ -19,6 +19,7 @@ jobs: strategy: matrix: version: [ 11, 15, 16 ] + fail-fast: false runs-on: windows-latest steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/s3-snapshots.yml b/.github/workflows/s3-snapshots.yml index 847e9d7eb5..f698a0eedf 100644 --- a/.github/workflows/s3-snapshots.yml +++ b/.github/workflows/s3-snapshots.yml @@ -19,9 +19,6 @@ jobs: with: java-version: 12 - - name: Publish dokka locally - run: ./gradlew clean publishToMavenLocal --stacktrace - - name: Document stdlib run: ./gradlew :integration-tests:gradle:integrationTest --tests org.jetbrains.dokka.it.gradle.kotlin.StdlibGradleIntegrationTest --stacktrace env: @@ -52,9 +49,6 @@ jobs: with: java-version: 12 - - name: Publish dokka locally - run: ./gradlew clean publishToMavenLocal --stacktrace - - name: Document serialization run: ./gradlew :integration-tests:gradle:integrationTest --tests org.jetbrains.dokka.it.gradle.kotlin.SerializationGradleIntegrationTest --stacktrace env: @@ -85,9 +79,6 @@ jobs: with: java-version: 12 - - name: Publish dokka locally - run: ./gradlew clean publishToMavenLocal --stacktrace - - name: Document biojava-core run: ./gradlew :integration-tests:maven:integrationTest --tests org.jetbrains.dokka.it.maven.BiojavaIntegrationTest --stacktrace env: diff --git a/build.gradle.kts b/build.gradle.kts index dca6b9d93b..b702669332 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,11 @@ -import org.jetbrains.ValidatePublications -import org.jetbrains.configureDokkaVersion +import org.jetbrains.* import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") apply false id("java") - id("org.jetbrains.dokka") version "1.4.10.2" + id("org.jetbrains.dokka") version "1.4.32" + id("io.github.gradle-nexus.publish-plugin") } val dokka_version: String by project @@ -55,16 +55,13 @@ subprojects { val dokkaOutputDir = "$buildDir/dokka" dokkaHtml { + onlyIf { !isLocalPublication } outputDirectory.set(file(dokkaOutputDir)) } - val deleteDokkaOutputDir by registering(Delete::class) { - delete(dokkaOutputDir) - } - register("javadocJar") { - dependsOn(deleteDokkaOutputDir, dokkaHtml) archiveClassifier.set("javadoc") + dependsOn(dokkaHtml) from(dokkaOutputDir) } } @@ -80,3 +77,18 @@ tasks.whenTaskAdded { println("Publication version: $dokka_version") tasks.register("validatePublications") + +nexusPublishing { + repositories { + sonatype { + username.set(System.getenv("SONATYPE_USER")) + password.set(System.getenv("SONATYPE_PASSWORD")) + } + } +} + +tasks.maybeCreate("dokkaPublish").run { + if (publicationChannels.any { it.isMavenRepository }) { + finalizedBy(tasks.named("closeAndReleaseSonatypeStagingRepository")) + } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 75d59e8f65..1f1faaabfe 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -10,4 +10,5 @@ dependencies { implementation("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4") implementation("com.github.jengelman.gradle.plugins:shadow:2.0.4") implementation("org.jetbrains.kotlinx:binary-compatibility-validator:0.4.0") + implementation("io.github.gradle-nexus:publish-plugin:1.0.0") } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/DokkaPublicationChannel.kt b/buildSrc/src/main/kotlin/org/jetbrains/DokkaPublicationChannel.kt index 42af6e8e2d..c4f22a9083 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/DokkaPublicationChannel.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/DokkaPublicationChannel.kt @@ -4,18 +4,36 @@ package org.jetbrains import org.gradle.api.Project -internal enum class DokkaPublicationChannel { +enum class DokkaPublicationChannel { SpaceDokkaDev, BintrayKotlinDev, BintrayKotlinEap, - BintrayKotlinDokka; + BintrayKotlinDokka, + MavenCentral, + MavenCentralSnapshot; val isSpaceRepository get() = this == SpaceDokkaDev val isBintrayRepository get() = when (this) { - SpaceDokkaDev -> false BintrayKotlinDev, BintrayKotlinEap, BintrayKotlinDokka -> true + else -> false + } + + val isMavenRepository + get() = when (this) { + MavenCentral, MavenCentralSnapshot -> true + else -> false + } + + val acceptedDokkaVersionTypes: List + get() = when(this) { + MavenCentral -> listOf(DokkaVersionType.Release) + MavenCentralSnapshot -> listOf(DokkaVersionType.Snapshot) + SpaceDokkaDev -> listOf(DokkaVersionType.Release, DokkaVersionType.Dev, DokkaVersionType.MC, DokkaVersionType.Snapshot) + BintrayKotlinDev -> listOf(DokkaVersionType.Dev, DokkaVersionType.MC, DokkaVersionType.Snapshot) + BintrayKotlinEap -> listOf(DokkaVersionType.MC) + BintrayKotlinDokka -> listOf(DokkaVersionType.Release) } companion object { @@ -24,12 +42,14 @@ internal enum class DokkaPublicationChannel { "bintray-kotlin-dev" -> BintrayKotlinDev "bintray-kotlin-eap" -> BintrayKotlinEap "bintray-kotlin-dokka" -> BintrayKotlinDokka + "maven-central-release" -> MavenCentral + "maven-central-snapshot" -> MavenCentralSnapshot else -> throw IllegalArgumentException("Unknown dokka_publication_channel=$value") } } } -internal val Project.publicationChannels: Set +val Project.publicationChannels: Set get() { val publicationChannel = this.properties["dokka_publication_channel"]?.toString() val publicationChannels = this.properties["dokka_publication_channels"]?.toString() diff --git a/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt b/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt index 2a5c21a73f..05585d0682 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt @@ -24,3 +24,6 @@ private fun dokkaVersionFromBase(baseVersion: String): String { val Project.dokkaVersion: String get() = configureDokkaVersion() + +val Project.dokkaVersionType: DokkaVersionType? + get() = DokkaVersionType.values().find { it.suffix.matches(dokkaVersion.substringAfter("-", "")) } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersionType.kt b/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersionType.kt new file mode 100644 index 0000000000..dbf2d31264 --- /dev/null +++ b/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersionType.kt @@ -0,0 +1,5 @@ +package org.jetbrains + +enum class DokkaVersionType(val suffix: Regex) { + Release("^$".toRegex()), Snapshot("SNAPSHOT".toRegex()), Dev("dev-\\d+".toRegex()), MC("mc-\\d+".toRegex()) +} diff --git a/buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt b/buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt index 4659f6695f..4b97d74a4a 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt @@ -19,7 +19,7 @@ open class ValidatePublications : DefaultTask() { class UnpublishedProjectDependencyException( project: Project, dependencyProject: Project ) : GradleException( - "Published project ${project.path} cannot depend on unpublished projed ${dependencyProject.path}" + "Published project ${project.path} cannot depend on unpublished project ${dependencyProject.path}" ) @@ -36,6 +36,7 @@ open class ValidatePublications : DefaultTask() { checkPublicationIsConfiguredForBintray(subProject, publication) } checkProjectDependenciesArePublished(subProject) + subProject.assertPublicationVersion() } } } @@ -72,6 +73,19 @@ open class ValidatePublications : DefaultTask() { } } + private fun Project.assertPublicationVersion() { + if (System.getenv("SKIP_VERSION_CHECK")?.contains("true", ignoreCase = true) == true) + return + + if (!publicationChannels.all { publicationChannel -> + publicationChannel.acceptedDokkaVersionTypes.any { acceptedVersionType -> + acceptedVersionType == dokkaVersionType + } + }) { + throw AssertionError("Wrong version $dokkaVersion for configured publication channels $publicationChannels") + } + } + init { group = "verification" project.tasks.named("check") { diff --git a/buildSrc/src/main/kotlin/org/jetbrains/publication.kt b/buildSrc/src/main/kotlin/org/jetbrains/publication.kt index 821024676b..bb4f3ad3d7 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/publication.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/publication.kt @@ -4,13 +4,13 @@ import com.github.jengelman.gradle.plugins.shadow.ShadowExtension import com.jfrog.bintray.gradle.BintrayExtension import kotlinx.validation.ApiValidationExtension import org.gradle.api.Project -import org.gradle.api.provider.Provider import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.tasks.PublishToMavenRepository import org.gradle.kotlin.dsl.* import org.gradle.plugins.signing.SigningExtension import org.jetbrains.DokkaPublicationChannel.* +import io.github.gradlenexus.publishplugin.NexusPublishExtension import java.net.URI class DokkaPublicationBuilder { @@ -26,24 +26,25 @@ class DokkaPublicationBuilder { fun Project.registerDokkaArtifactPublication(publicationName: String, configure: DokkaPublicationBuilder.() -> Unit) { configure { publications { - val publicationProvider = register(publicationName) { + register(publicationName) { val builder = DokkaPublicationBuilder().apply(configure) artifactId = builder.artifactId when (builder.component) { DokkaPublicationBuilder.Component.Java -> from(components["java"]) DokkaPublicationBuilder.Component.Shadow -> run { - artifact(tasks["sourcesJar"]) extensions.getByType(ShadowExtension::class.java).component(this) + artifact(tasks["sourcesJar"]) } } + artifact(tasks["javadocJar"]) configurePom("Dokka ${project.name}") } - signPublicationIfKeyPresent(publicationProvider) } } configureBintrayPublicationIfNecessary(publicationName) configureSpacePublicationIfNecessary(publicationName) + configureSonatypePublicationIfNecessary(publicationName) createDokkaPublishTaskIfNecessary() registerBinaryCompatibilityCheck(publicationName) } @@ -83,6 +84,11 @@ fun Project.createDokkaPublishTaskIfNecessary() { if (publicationChannels.any { it.isSpaceRepository }) { dependsOn(tasks.named("publish")) } + + if (publicationChannels.any { it.isMavenRepository }) { + dependsOn(tasks.named("publishToSonatype")) + } + if (publicationChannels.any { it.isBintrayRepository }) { dependsOn(tasks.named("bintrayUpload")) } @@ -110,7 +116,7 @@ private fun Project.configureBintrayPublication(vararg publications: String) { } repo = when (bintrayPublicationChannels.single()) { - SpaceDokkaDev -> throw IllegalStateException("$SpaceDokkaDev is not a bintray repository") + SpaceDokkaDev, MavenCentral, MavenCentralSnapshot -> throw IllegalStateException("${bintrayPublicationChannels.single()} is not a bintray repository") BintrayKotlinDev -> "kotlin-dev" BintrayKotlinEap -> "kotlin-eap" BintrayKotlinDokka -> "dokka" @@ -129,8 +135,13 @@ private fun Project.configureBintrayPublication(vararg publications: String) { } } +fun Project.configureSonatypePublicationIfNecessary(vararg publications: String) { + if (publicationChannels.any { it.isMavenRepository }) { + signPublicationsIfKeyPresent(*publications) + } +} -private fun MavenPublication.configurePom(projectName: String) { +fun MavenPublication.configurePom(projectName: String) { pom { name.set(projectName) description.set("Dokka is a documentation engine for Kotlin and Java, performing the same function as Javadoc for Java") @@ -161,14 +172,23 @@ private fun MavenPublication.configurePom(projectName: String) { } @Suppress("UnstableApiUsage") -private fun Project.signPublicationIfKeyPresent(publicationProvider: Provider) { - val signingKey = System.getenv("SIGN_KEY") - val signingKeyPassphrase = System.getenv("SIGN_KEY_PASSPHRASE") +private fun Project.signPublicationsIfKeyPresent(vararg publications: String) { + val signingKeyId: String? = System.getenv("SIGN_KEY_ID") + val signingKey: String? = System.getenv("SIGN_KEY") + val signingKeyPassphrase: String? = System.getenv("SIGN_KEY_PASSPHRASE") if (!signingKey.isNullOrBlank()) { extensions.configure("signing") { - useInMemoryPgpKeys(signingKey, signingKeyPassphrase) - sign(publicationProvider.get()) + if (signingKeyId?.isNotBlank() == true) { + useInMemoryPgpKeys(signingKeyId, signingKey, signingKeyPassphrase) + } else { + useInMemoryPgpKeys(signingKey, signingKeyPassphrase) + } + publications.forEach { publicationName -> + extensions.findByType(PublishingExtension::class)!!.publications.findByName(publicationName)?.let { + sign(it) + } + } } } } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt b/buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt index ef9c5e6aac..261d1663cd 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt @@ -1,5 +1,6 @@ package org.jetbrains +import org.gradle.api.Project import org.gradle.api.Task fun Task.dependsOnMavenLocalPublication() { @@ -11,3 +12,11 @@ fun Task.dependsOnMavenLocalPublication() { } } } + +val Project.isLocalPublication: Boolean + get() = gradle.startParameter.taskNames.any { + it.endsWith("publishToMavenLocal", ignoreCase = true) || + it.endsWith("integrationTest", ignoreCase = true) || + it.endsWith("check", ignoreCase = true) || + it.endsWith("test", ignoreCase = true) + } diff --git a/gradle.properties b/gradle.properties index f82dc91e28..0532c422a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # Project Settings dokka_version_base=1.5.0 -dokka_publication_channels=bintray-kotlin-dev&space-dokka-dev +dokka_publication_channels=maven-central-snapshot&space-dokka-dev dokka_integration_test_parallelism=2 # Versions kotlin_version=1.5.0 @@ -13,5 +13,5 @@ language_version=1.4 # Code style kotlin.code.style=official # Gradle settings -org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -org.gradle.parallel=true \ No newline at end of file +org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=2g +org.gradle.parallel=true diff --git a/plugins/base/build.gradle.kts b/plugins/base/build.gradle.kts index b3f002ef52..3a4ee539de 100644 --- a/plugins/base/build.gradle.kts +++ b/plugins/base/build.gradle.kts @@ -44,6 +44,10 @@ tasks { dependsOn(copyFrontend) } + sourcesJar { + dependsOn(processResources) + } + test { maxHeapSize = "4G" } diff --git a/runners/gradle-plugin/build.gradle.kts b/runners/gradle-plugin/build.gradle.kts index 8d374a35f8..d44a2a4a39 100644 --- a/runners/gradle-plugin/build.gradle.kts +++ b/runners/gradle-plugin/build.gradle.kts @@ -1,11 +1,8 @@ -import org.jetbrains.configureBintrayPublicationIfNecessary -import org.jetbrains.configureSpacePublicationIfNecessary -import org.jetbrains.createDokkaPublishTaskIfNecessary -import org.jetbrains.dokkaVersion +import org.jetbrains.* plugins { `java-gradle-plugin` - id("com.gradle.plugin-publish") version "0.10.1" + id("com.gradle.plugin-publish") version "0.15.0" } repositories { @@ -43,8 +40,11 @@ gradlePlugin { plugins { create("dokkaGradlePlugin") { id = "org.jetbrains.dokka" + displayName = "Dokka plugin" + description = "Dokka, the Kotlin documentation tool" implementationClass = "org.jetbrains.dokka.gradle.DokkaPlugin" version = dokkaVersion + isAutomatedPublishing = true } } } @@ -52,14 +52,7 @@ gradlePlugin { pluginBundle { website = "https://www.kotlinlang.org/" vcsUrl = "https://github.com/kotlin/dokka.git" - description = "Dokka, the Kotlin documentation tool" - tags = listOf("dokka", "kotlin", "kdoc", "android") - - plugins { - getByName("dokkaGradlePlugin") { - displayName = "Dokka plugin" - } - } + tags = listOf("dokka", "kotlin", "kdoc", "android", "documentation") mavenCoordinates { groupId = "org.jetbrains.dokka" @@ -69,20 +62,26 @@ pluginBundle { publishing { publications { - register("pluginMaven") { - artifactId = "dokka-gradle-plugin" - } - register("dokkaGradlePluginForIntegrationTests") { artifactId = "dokka-gradle-plugin" from(components["java"]) version = "for-integration-tests-SNAPSHOT" } + + register("pluginMaven") { + configurePom("Dokka ${project.name}") + artifactId = "dokka-gradle-plugin" + } } } +tasks.withType().configureEach { + onlyIf { publication != publishing.publications["dokkaGradlePluginForIntegrationTests"] } +} -configureSpacePublicationIfNecessary("dokkaGradlePluginPluginMarkerMaven", "pluginMaven") -configureBintrayPublicationIfNecessary("dokkaGradlePluginPluginMarkerMaven", "pluginMaven") -createDokkaPublishTaskIfNecessary() - +afterEvaluate { // Workaround for interesting design choice https://github.com/gradle/gradle/blob/c4f935f77377f1783f70ec05381c8182b3ade3ea/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/MavenPluginPublishPlugin.java#L49 + configureBintrayPublicationIfNecessary("pluginMaven", "dokkaGradlePluginPluginMarkerMaven") + configureSpacePublicationIfNecessary("pluginMaven", "dokkaGradlePluginPluginMarkerMaven") + configureSonatypePublicationIfNecessary("pluginMaven", "dokkaGradlePluginPluginMarkerMaven") + createDokkaPublishTaskIfNecessary() +} diff --git a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt index 5228f44b21..58039ab970 100644 --- a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt +++ b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt @@ -22,7 +22,6 @@ import org.jetbrains.dokka.* import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink import java.io.File import java.net.URL -import java.util.stream.Collectors class SourceLinkMapItem { @Parameter(name = "path", required = true)