From 9c7275f14f42a6673aa39286d10b18f1ff568484 Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Thu, 19 Jun 2025 22:22:39 +0300 Subject: [PATCH 1/3] chore: refactor build script to convention plugins --- build.gradle.kts | 104 +--------- buildSrc/build.gradle.kts | 25 ++- .../kotlin/build.dokka-javadoc.gradle.kts | 35 ++++ .../kotlin/build.java-conventions.gradle.kts | 50 +++++ .../build.kotlin-conventions.gradle.kts | 61 ++++++ ...lin-dsl-published-gradle-plugin.gradle.kts | 44 +++++ .../kotlin/build.kotlin-library.gradle.kts | 21 +++ .../build.publish-to-central.gradle.kts | 133 +++++++++++++ .../build.published-gradle-plugin.gradle.kts | 21 +++ .../build.reproducible-timestamps.gradle.kts | 53 ++++++ .../main/kotlin/build.test-junit5.gradle.kts | 43 +++++ .../license-texts/license-texts.gradle.kts | 9 +- gradle.properties | 7 + plugins/build.gradle.kts | 178 ------------------ plugins/crlf-plugin/build.gradle.kts | 5 + plugins/gettext-plugin/build.gradle.kts | 21 +++ .../gradle-extensions-plugin/build.gradle.kts | 21 +++ plugins/ide-plugin/build.gradle.kts | 4 + plugins/jandex-plugin/build.gradle.kts | 21 +++ .../license-gather-plugin/build.gradle.kts | 5 +- .../vlsi/gradle/license/BatchingProcessor.kt | 4 +- .../build.gradle.kts | 5 + settings.gradle.kts | 5 +- testkit/build.gradle.kts | 6 +- 24 files changed, 588 insertions(+), 293 deletions(-) create mode 100644 buildSrc/src/main/kotlin/build.dokka-javadoc.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.java-conventions.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.kotlin-conventions.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.kotlin-dsl-published-gradle-plugin.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.kotlin-library.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.publish-to-central.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.published-gradle-plugin.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.reproducible-timestamps.gradle.kts create mode 100644 buildSrc/src/main/kotlin/build.test-junit5.gradle.kts delete mode 100644 plugins/build.gradle.kts create mode 100644 plugins/gettext-plugin/build.gradle.kts create mode 100644 plugins/gradle-extensions-plugin/build.gradle.kts create mode 100644 plugins/jandex-plugin/build.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index f62f33a0..869db3d0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,119 +17,29 @@ import org.gradle.plugins.ide.idea.model.IdeaProject import org.jetbrains.gradle.ext.CopyrightConfiguration import org.jetbrains.gradle.ext.ProjectSettings -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.dsl.KotlinVersion -import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile plugins { - id("com.gradle.plugin-publish") apply false - id("com.github.autostyle") id("org.jetbrains.gradle.plugin.idea-ext") - id("org.jetbrains.dokka") - `embedded-kotlin` } description = "A set of plugins to simplify Gradle release tasks" -val repoUrl = "https://github.com/vlsi/vlsi-release-plugins" +val repoUrl = property("repoUrl") val publishToCentral = (findProperty("publishToCentral") as? String) ?.ifBlank { "true" }?.toBoolean() ?: true -if (publishToCentral) { -} +val release = providers.gradleProperty("release").getOrElse("false").toBoolean() +val buildVersion = providers.gradleProperty("current.version").get() + if (release) "" else "-SNAPSHOT" + +println("Building $buildVersion") +version = buildVersion allprojects { group = "com.github.vlsi.gradle" - version = project.findProperty("current.version") as? String ?: rootProject.version - - tasks.withType { - enabled = false - } - - plugins.withId("java") { - configure { - withSourcesJar() - } - tasks.withType().configureEach { - options.release.set(8) - } - } - tasks.withType().configureEach { - compilerOptions { - freeCompilerArgs.add("-Xjdk-release=8") - @Suppress("DEPRECATION") - apiVersion.set(KotlinVersion.KOTLIN_1_4) - jvmTarget = JvmTarget.JVM_1_8 - } - } + version = buildVersion } val licenseHeader = file("gradle/license-header.txt").readText() -allprojects { - if (project.path != ":plugins:license-gather-plugin") { - apply(plugin = "com.github.autostyle") - autostyle { - kotlinGradle { - ktlint { - userData(mapOf("disabled_rules" to "no-wildcard-imports,import-ordering")) - } - trimTrailingWhitespace() - endWithNewline() - } - } - plugins.withId("org.jetbrains.kotlin.jvm") { - autostyle { - kotlin { - licenseHeader(licenseHeader) - trimTrailingWhitespace() - // Generated build/generated-sources/licenses/com/github/vlsi/gradle/license/api/License.kt - // has wrong indentation, and it is not clear how to exclude it - ktlint { - userData(mapOf("disabled_rules" to "no-wildcard-imports,import-ordering")) - } - // It prints errors regarding build/generated-sources/licenses/com/github/vlsi/gradle/license/api/License.kt - // so comment it for now :( - endWithNewline() - } - } - } - } - - tasks.withType().configureEach { - // Ensure builds are reproducible - isPreserveFileTimestamps = false - isReproducibleFileOrder = true - dirPermissions { - user { - read = true - write = true - execute = true - } - group { - read = true - write = true - execute = true - } - other { - read = true - execute = true - } - } - filePermissions { - user { - read = true - write = true - } - group { - read = true - write = true - } - other { - read = true - } - } - } -} fun IdeaProject.settings(configuration: ProjectSettings.() -> kotlin.Unit) = (this as ExtensionAware).configure(configuration) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1ec9fee7..95083fc5 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,5 +1,5 @@ +import org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile /* @@ -20,8 +20,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile */ plugins { - `java` - `kotlin-dsl` apply false + id("java") + `kotlin-dsl` id("com.github.autostyle") } @@ -55,17 +55,28 @@ fun Project.applyKotlinProjectConventions() { apply(plugin = "org.gradle.kotlin.kotlin-dsl") java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } + } + tasks.withType().configureEach { + options.release.set(11) } - tasks.withType { + tasks.withType().configureEach { compilerOptions { - jvmTarget = JvmTarget.JVM_1_8 + jvmTarget = JvmTarget.JVM_11 + freeCompilerArgs.add("-Xjdk-release=11") } } } dependencies { + api("com.github.autostyle:com.github.autostyle.gradle.plugin:4.0") + api("com.gradle.plugin-publish:com.gradle.plugin-publish.gradle.plugin:1.3.1") + api("org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:$expectedKotlinDslPluginsVersion") + api("org.jetbrains.dokka-javadoc:org.jetbrains.dokka-javadoc.gradle.plugin:2.0.0") + api("com.gradleup.nmcp:com.gradleup.nmcp.gradle.plugin:0.1.5") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") subprojects.forEach { runtimeOnly(project(it.path)) } diff --git a/buildSrc/src/main/kotlin/build.dokka-javadoc.gradle.kts b/buildSrc/src/main/kotlin/build.dokka-javadoc.gradle.kts new file mode 100644 index 00000000..e7e455e7 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.dokka-javadoc.gradle.kts @@ -0,0 +1,35 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + id("java-base") + id("org.jetbrains.dokka-javadoc") +} + +java { + // Workaround https://github.com/gradle/gradle/issues/21933, so it adds javadocElements configuration + withJavadocJar() +} + +val dokkaJar by tasks.registering(Jar::class) { + group = LifecycleBasePlugin.BUILD_GROUP + description = "Assembles a jar archive containing javadoc" + from(tasks.dokkaGeneratePublicationJavadoc) + archiveClassifier.set("javadoc") +} + +configurations[JavaPlugin.JAVADOC_ELEMENTS_CONFIGURATION_NAME].outgoing.artifact(dokkaJar) diff --git a/buildSrc/src/main/kotlin/build.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/build.java-conventions.gradle.kts new file mode 100644 index 00000000..f04cd067 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.java-conventions.gradle.kts @@ -0,0 +1,50 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.github.vlsi.gradle.buildtools.filterEolSimple + +plugins { + id("java") + id("build.reproducible-timestamps") +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +tasks.withType().configureEach { + options.release.set(8) + options.encoding = "UTF-8" +} + +tasks.withType().configureEach { + into("META-INF") { + filterEolSimple("crlf") + from("$rootDir/LICENSE") + from("$rootDir/NOTICE") + } + manifest { + attributes["Bundle-License"] = "Apache-2.0" + attributes["Specification-Title"] = project.name + " " + project.description + attributes["Specification-Vendor"] = "Vladimir Sitnikov" + attributes["Implementation-Vendor"] = "Vladimir Sitnikov" + attributes["Implementation-Vendor-Id"] = "com.github.vlsi" + // Implementation-Version is not here to make jar reproducible across versions + } +} diff --git a/buildSrc/src/main/kotlin/build.kotlin-conventions.gradle.kts b/buildSrc/src/main/kotlin/build.kotlin-conventions.gradle.kts new file mode 100644 index 00000000..50164047 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.kotlin-conventions.gradle.kts @@ -0,0 +1,61 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile + +plugins { + id("build.java-conventions") + id("com.github.autostyle") + kotlin("jvm") +} + +tasks.withType().configureEach { + compilerOptions { + freeCompilerArgs.add("-Xjdk-release=8") + @Suppress("DEPRECATION") + apiVersion.set(KotlinVersion.KOTLIN_1_4) + jvmTarget = JvmTarget.JVM_1_8 + } +} + +val licenseHeader = file("gradle/license-header.txt").takeIf { it.exists() }?.readText() + +if (licenseHeader != null) { + autostyle { + kotlinGradle { + ktlint { + userData(mapOf("disabled_rules" to "no-wildcard-imports,import-ordering")) + } + trimTrailingWhitespace() + endWithNewline() + } + kotlin { + licenseHeader(licenseHeader) + trimTrailingWhitespace() + // Generated build/generated-sources/licenses/com/github/vlsi/gradle/license/api/License.kt + // has wrong indentation, and it is not clear how to exclude it + ktlint { + userData(mapOf("disabled_rules" to "no-wildcard-imports,import-ordering")) + } + // It prints errors regarding build/generated-sources/licenses/com/github/vlsi/gradle/license/api/License.kt + // so comment it for now :( + endWithNewline() + } + } +} diff --git a/buildSrc/src/main/kotlin/build.kotlin-dsl-published-gradle-plugin.gradle.kts b/buildSrc/src/main/kotlin/build.kotlin-dsl-published-gradle-plugin.gradle.kts new file mode 100644 index 00000000..a47cfc63 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.kotlin-dsl-published-gradle-plugin.gradle.kts @@ -0,0 +1,44 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + id("org.gradle.kotlin.kotlin-dsl") + id("build.kotlin-conventions") + id("build.dokka-javadoc") + id("build.publish-to-central") +} + +val pluginDisplayName = project.property("plugin.display.name") as String + +val repoUrl = property("repoUrl") as String + +gradlePlugin { + description = project.description + website = repoUrl + vcsUrl = repoUrl + + val pluginId = project.name.removeSuffix("-plugin") + plugins { + create(pluginId) { + id = "com.github.vlsi.$pluginId" + displayName = pluginDisplayName + description = project.description + tags = (property("plugin.tags") as String).split(Regex("\\s*,\\s*")) + implementationClass = project.property("plugin.implementation.class") as String + } + } +} diff --git a/buildSrc/src/main/kotlin/build.kotlin-library.gradle.kts b/buildSrc/src/main/kotlin/build.kotlin-library.gradle.kts new file mode 100644 index 00000000..53dad6b6 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.kotlin-library.gradle.kts @@ -0,0 +1,21 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + kotlin("jvm") + id("build.kotlin-conventions") +} diff --git a/buildSrc/src/main/kotlin/build.publish-to-central.gradle.kts b/buildSrc/src/main/kotlin/build.publish-to-central.gradle.kts new file mode 100644 index 00000000..e745e5d3 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.publish-to-central.gradle.kts @@ -0,0 +1,133 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import java.time.Duration + +plugins { + id("java-library") + id("maven-publish") + id("signing") + id("com.gradleup.nmcp") +} + +val repoUrl = property("repoUrl") as String + +java { + withSourcesJar() +} + +val release = providers.gradleProperty("release").getOrElse("false").toBoolean() +val useInMemoryPgpKeys = providers.gradleProperty("useInMemoryPgpKeys").getOrElse("true").toBoolean() +val centralPortalPublishingType = providers.gradleProperty("centralPortalPublishingType").orElse("AUTOMATIC") +val centralPortalPublishingTimeout = providers.gradleProperty("centralPortalPublishingTimeout").map { it.toLong() } + +if (!release) { + publishing { + repositories { + maven { + name = "centralSnapshots" + url = uri("https://central.sonatype.com/repository/maven-snapshots") + credentials(PasswordCredentials::class) + } + } + } +} else { + signing { + sign(publishing.publications) + if (!useInMemoryPgpKeys) { + useGpgCmd() + } else { + val pgpPrivateKey = System.getenv("SIGNING_PGP_PRIVATE_KEY") + val pgpPassphrase = System.getenv("SIGNING_PGP_PASSPHRASE") + if (pgpPrivateKey.isNullOrBlank() || pgpPassphrase.isNullOrBlank()) { + throw IllegalArgumentException("GPP private key (SIGNING_PGP_PRIVATE_KEY) and passphrase (SIGNING_PGP_PASSPHRASE) must be set") + } + useInMemoryPgpKeys( + pgpPrivateKey, + pgpPassphrase + ) + } + } + nmcp { + centralPortal { + username = providers.environmentVariable("CENTRAL_PORTAL_USERNAME") + password = providers.environmentVariable("CENTRAL_PORTAL_PASSWORD") + publishingType = centralPortalPublishingType.get() + verificationTimeout = Duration.ofMinutes(centralPortalPublishingTimeout.get()) + } + } +} + +publishing { + repositories { + maven { + name = "sonatype" + url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") + credentials(PasswordCredentials::class) + } + } + + publications.withType().configureEach { + // Use the resolved versions in pom.xml + // Gradle might have different resolution rules, so we set the versions + // that were used in Gradle build/test. + versionMapping { + usage(Usage.JAVA_RUNTIME) { + fromResolutionResult() + } + usage(Usage.JAVA_API) { + fromResolutionOf("runtimeClasspath") + } + } + pom { + name.set( + (project.findProperty("artifact.name") as? String) + ?: project.name + ) + // This code might be executed before project-related build.gradle.kts is evaluated + // So we delay access to project.description + description.set( + project.provider { project.description } + ) + inceptionYear.set("2019") + url.set(repoUrl) + developers { + developer { + name.set("Vladimir Sitnikov") + id.set("vlsi") + email.set("sitnikov.vladmir@gmail.com") + } + } + issueManagement { + system.set("GitHub Issues") + url.set("$repoUrl/issues") + } + licenses { + license { + name.set("Apache-2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + scm { + connection.set("scm:git:$repoUrl.git") + developerConnection.set("scm:git:$repoUrl.git") + url.set(repoUrl) + tag.set("HEAD") + } + } + } +} diff --git a/buildSrc/src/main/kotlin/build.published-gradle-plugin.gradle.kts b/buildSrc/src/main/kotlin/build.published-gradle-plugin.gradle.kts new file mode 100644 index 00000000..83ddd976 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.published-gradle-plugin.gradle.kts @@ -0,0 +1,21 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + id("build.kotlin-conventions") + id("org.gradle.kotlin.kotlin-dsl") +} diff --git a/buildSrc/src/main/kotlin/build.reproducible-timestamps.gradle.kts b/buildSrc/src/main/kotlin/build.reproducible-timestamps.gradle.kts new file mode 100644 index 00000000..62fe4031 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.reproducible-timestamps.gradle.kts @@ -0,0 +1,53 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import org.gradle.api.tasks.bundling.AbstractArchiveTask + +tasks.withType().configureEach { + // Ensure builds are reproducible + isPreserveFileTimestamps = false + isReproducibleFileOrder = true + dirPermissions { + user { + read = true + write = true + execute = true + } + group { + read = true + write = true + execute = true + } + other { + read = true + execute = true + } + } + filePermissions { + user { + read = true + write = true + } + group { + read = true + write = true + } + other { + read = true + } + } +} diff --git a/buildSrc/src/main/kotlin/build.test-junit5.gradle.kts b/buildSrc/src/main/kotlin/build.test-junit5.gradle.kts new file mode 100644 index 00000000..672c1700 --- /dev/null +++ b/buildSrc/src/main/kotlin/build.test-junit5.gradle.kts @@ -0,0 +1,43 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import org.gradle.api.tasks.testing.logging.TestExceptionFormat + +plugins { + id("java") +} + +dependencies { + testImplementation(platform("org.junit:junit-bom:5.13.1")) + testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation("org.junit.jupiter:junit-jupiter-api") + testImplementation("org.junit.jupiter:junit-jupiter-params") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + findProject(":testkit")?.let { + testImplementation(it) + } +} + +tasks.withType().configureEach { + useJUnitPlatform() + testLogging { + exceptionFormat = TestExceptionFormat.FULL + showStandardStreams = false // individual tests log a lot for now :( + } + maxParallelForks = 8 +} diff --git a/buildSrc/subprojects/license-texts/license-texts.gradle.kts b/buildSrc/subprojects/license-texts/license-texts.gradle.kts index 40580a5e..0303623a 100644 --- a/buildSrc/subprojects/license-texts/license-texts.gradle.kts +++ b/buildSrc/subprojects/license-texts/license-texts.gradle.kts @@ -24,8 +24,13 @@ dependencies { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +tasks.withType().configureEach { + options.release.set(11) } gradlePlugin { diff --git a/gradle.properties b/gradle.properties index 493e5818..8ae7a418 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,4 +19,11 @@ org.gradle.jvmargs=-XX:MaxMetaspaceSize=768m # repository.apache.org does not yet support .sha256 and .sha512 checksums systemProp.org.gradle.internal.publish.checksums.insecure=true +# Kotlin Dokka is experimental, and we want to silence the build warning +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true + current.version=1.90 + +repoUrl=https://github.com/vlsi/vlsi-release-plugins +centralPortalPublishingTimeout=180 diff --git a/plugins/build.gradle.kts b/plugins/build.gradle.kts deleted file mode 100644 index cadb718a..00000000 --- a/plugins/build.gradle.kts +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2019 Vladimir Sitnikov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import com.github.vlsi.gradle.buildtools.filterEolSimple -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.tasks.testing.logging.TestExceptionFormat -import org.gradle.jvm.tasks.Jar - -plugins { - id("org.jetbrains.dokka") apply false - id("com.gradle.plugin-publish") apply false -} - -val repoUrl = "https://github.com/vlsi/vlsi-release-plugins" - -subprojects { - repositories { - gradlePluginPortal() - } - - apply() - apply(plugin = "java-library") - apply(plugin = "org.gradle.kotlin.kotlin-dsl") - apply(plugin = "java-gradle-plugin") - apply(plugin = "org.jetbrains.dokka") - apply(plugin = "com.gradle.plugin-publish") - apply(plugin = "org.gradle.maven-publish") - - dependencies { - "testImplementation"("org.junit.jupiter:junit-jupiter:5.4.2") - "testImplementation"(project(":testkit")) - } - - val pluginDisplayName = project.property("plugin.display.name") as String - -// configure { -// description = project.description -// website = repoUrl -// vcsUrl = repoUrl -// tags = (project.property("plugin.tags") as String).split(Regex("\\s*,\\s*")) -// } - - configure { - // gradlePlugin - val pluginId = project.name.removeSuffix("-plugin") - plugins { - create(pluginId) { - id = "com.github.vlsi.$pluginId" - displayName = pluginDisplayName - description = project.description - implementationClass = project.property("plugin.implementation.class") as String - } - } - } - - plugins.withType { - tasks { - withType().configureEach { - useJUnitPlatform() - testLogging { - exceptionFormat = TestExceptionFormat.FULL - showStandardStreams = false // individual tests log a lot for now :( - } - maxParallelForks = 8 - } - withType().configureEach { - options.encoding = "UTF-8" - } - withType().configureEach { - into("META-INF") { - filterEolSimple("crlf") - from("$rootDir/LICENSE") - from("$rootDir/NOTICE") - } - manifest { - attributes["Bundle-License"] = "Apache-2.0" - attributes["Specification-Title"] = project.name + " " + project.description - attributes["Specification-Vendor"] = "Vladimir Sitnikov" - attributes["Implementation-Vendor"] = "Vladimir Sitnikov" - attributes["Implementation-Vendor-Id"] = "com.github.vlsi" - // Implementation-Version is not here to make jar reproducible across versions - } - } - } - - val javadocJar by tasks.registering(org.gradle.api.tasks.bundling.Jar::class) { - group = LifecycleBasePlugin.BUILD_GROUP - description = "Assembles a jar archive containing javadoc" - archiveClassifier.set("javadoc") - from(tasks.named("dokkaJavadoc")) - } - - // used by plugin-publish plugin - val archives by configurations.getting - artifacts { - add(archives.name, javadocJar) - } - - configure { // publishing - publications { - withType { - // Use the resolved versions in pom.xml - // Gradle might have different resolution rules, so we set the versions - // that were used in Gradle build/test. - versionMapping { - usage(Usage.JAVA_RUNTIME) { - fromResolutionResult() - } - usage(Usage.JAVA_API) { - fromResolutionOf("runtimeClasspath") - } - } - pom { - withXml { - val sb = asString() - var s = sb.toString() - // compile is Maven default, so delete it - s = s.replace("compile", "") - // Cut because all dependencies have the resolved versions - s = s.replace( - Regex( - ".*?", - RegexOption.DOT_MATCHES_ALL - ), - "" - ) - sb.setLength(0) - sb.append(s) - // Re-format the XML - asNode() - } - name.set(pluginDisplayName) - description.set(project.description) - inceptionYear.set("2019") - url.set(repoUrl) - developers { - developer { - name.set("Vladimir Sitnikov") - id.set("vlsi") - email.set("sitnikov.vladmir@gmail.com") - } - } - issueManagement { - system.set("GitHub") - url.set("$repoUrl/issues") - } - licenses { - license { - name.set("Apache-2.0") - url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - scm { - connection.set("scm:git:$repoUrl.git") - developerConnection.set("scm:git:$repoUrl.git") - url.set(repoUrl) - tag.set("HEAD") - } - } - } - } - } - } -} diff --git a/plugins/crlf-plugin/build.gradle.kts b/plugins/crlf-plugin/build.gradle.kts index d99eec28..51fe0e6d 100644 --- a/plugins/crlf-plugin/build.gradle.kts +++ b/plugins/crlf-plugin/build.gradle.kts @@ -15,6 +15,11 @@ * */ +plugins { + id("build.kotlin-dsl-published-gradle-plugin") + id("build.test-junit5") +} + dependencies { implementation("org.eclipse.jgit:org.eclipse.jgit:5.13.3.202401111512-r") } diff --git a/plugins/gettext-plugin/build.gradle.kts b/plugins/gettext-plugin/build.gradle.kts new file mode 100644 index 00000000..f1c5516f --- /dev/null +++ b/plugins/gettext-plugin/build.gradle.kts @@ -0,0 +1,21 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + id("build.kotlin-dsl-published-gradle-plugin") + id("build.test-junit5") +} diff --git a/plugins/gradle-extensions-plugin/build.gradle.kts b/plugins/gradle-extensions-plugin/build.gradle.kts new file mode 100644 index 00000000..f1c5516f --- /dev/null +++ b/plugins/gradle-extensions-plugin/build.gradle.kts @@ -0,0 +1,21 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + id("build.kotlin-dsl-published-gradle-plugin") + id("build.test-junit5") +} diff --git a/plugins/ide-plugin/build.gradle.kts b/plugins/ide-plugin/build.gradle.kts index 8f27f826..fc6a7601 100644 --- a/plugins/ide-plugin/build.gradle.kts +++ b/plugins/ide-plugin/build.gradle.kts @@ -15,6 +15,10 @@ * */ +plugins { + id("build.kotlin-dsl-published-gradle-plugin") +} + dependencies { constraints { api("com.google.guava:guava:33.4.8-jre") { diff --git a/plugins/jandex-plugin/build.gradle.kts b/plugins/jandex-plugin/build.gradle.kts new file mode 100644 index 00000000..f1c5516f --- /dev/null +++ b/plugins/jandex-plugin/build.gradle.kts @@ -0,0 +1,21 @@ +/* + * Copyright 2019 Vladimir Sitnikov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + id("build.kotlin-dsl-published-gradle-plugin") + id("build.test-junit5") +} diff --git a/plugins/license-gather-plugin/build.gradle.kts b/plugins/license-gather-plugin/build.gradle.kts index c59ed5bf..55ed56c2 100644 --- a/plugins/license-gather-plugin/build.gradle.kts +++ b/plugins/license-gather-plugin/build.gradle.kts @@ -20,10 +20,13 @@ import com.github.vlsi.gradle.license.EnumGeneratorTask plugins { buildplugins.`license-texts` + id("build.kotlin-dsl-published-gradle-plugin") + id("build.test-junit5") } dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") + // kotlinx-coroutines-core 1.10+ results in internal kotlinc error + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") } tasks { diff --git a/plugins/license-gather-plugin/src/main/kotlin/com/github/vlsi/gradle/license/BatchingProcessor.kt b/plugins/license-gather-plugin/src/main/kotlin/com/github/vlsi/gradle/license/BatchingProcessor.kt index a8e0049f..75b6a9be 100644 --- a/plugins/license-gather-plugin/src/main/kotlin/com/github/vlsi/gradle/license/BatchingProcessor.kt +++ b/plugins/license-gather-plugin/src/main/kotlin/com/github/vlsi/gradle/license/BatchingProcessor.kt @@ -63,9 +63,9 @@ class BatchBuilder { } results.map { try { - Result.success(it.await()) + Result.success(it.await()) } catch (e: Exception) { - Result.failure(e) + Result.failure(e) } } } diff --git a/plugins/stage-vote-release-plugin/build.gradle.kts b/plugins/stage-vote-release-plugin/build.gradle.kts index 0cc73fa3..90897125 100644 --- a/plugins/stage-vote-release-plugin/build.gradle.kts +++ b/plugins/stage-vote-release-plugin/build.gradle.kts @@ -15,6 +15,11 @@ * */ +plugins { + id("build.kotlin-dsl-published-gradle-plugin") + id("build.test-junit5") +} + dependencies { implementation(project(":plugins:crlf-plugin")) implementation(project(":plugins:license-gather-plugin")) diff --git a/settings.gradle.kts b/settings.gradle.kts index 05d2bf91..79e73c85 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,16 +17,13 @@ pluginManagement { plugins { - id("com.github.autostyle") version "4.0" - id("com.gradle.plugin-publish") version "1.2.0" id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.10" - id("org.jetbrains.dokka") version "1.9.20" } } dependencyResolutionManagement { repositories { - mavenCentral() + gradlePluginPortal() } } diff --git a/testkit/build.gradle.kts b/testkit/build.gradle.kts index 114a3709..0c4e0c7c 100644 --- a/testkit/build.gradle.kts +++ b/testkit/build.gradle.kts @@ -16,10 +16,12 @@ */ plugins { - kotlin("jvm") + id("build.kotlin-library") + id("build.test-junit5") } dependencies { - api("org.junit.jupiter:junit-jupiter:5.4.2") api(gradleTestKit()) + api(platform("org.junit:junit-bom:5.13.1")) + implementation("org.junit.jupiter:junit-jupiter") } From ec5c9b350eb3b5fffe37250da58406e0ef782d8e Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Thu, 19 Jun 2025 22:59:34 +0300 Subject: [PATCH 2/3] chore: use Java 21 for release test --- .github/workflows/release-test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-test.yml b/.github/workflows/release-test.yml index d4301d79..f1f1f44f 100644 --- a/.github/workflows/release-test.yml +++ b/.github/workflows/release-test.yml @@ -29,7 +29,7 @@ jobs: - name: 'Set up JDK 11' uses: actions/setup-java@v4 with: - java-version: 11 + java-version: 21 distribution: 'zulu' - name: 'Start release environment' run: | @@ -75,7 +75,7 @@ jobs: - name: 'Set up JDK 11' uses: actions/setup-java@v4 with: - java-version: 11 + java-version: 21 distribution: 'zulu' - name: 'Start release environment' run: | @@ -121,7 +121,7 @@ jobs: - name: 'Set up JDK 11' uses: actions/setup-java@v4 with: - java-version: 11 + java-version: 21 distribution: 'zulu' - name: 'Start release environment' run: | @@ -167,7 +167,7 @@ jobs: - name: 'Set up JDK 8' uses: actions/setup-java@v4 with: - java-version: 8 + java-version: 21 distribution: 'zulu' - name: 'Start release environment' run: | @@ -213,7 +213,7 @@ jobs: - name: 'Set up JDK 8' uses: actions/setup-java@v4 with: - java-version: 8 + java-version: 21 distribution: 'zulu' - name: 'Start release environment' run: | From e58907b8a1562e62b6d35a78ac9248a37be3552f Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Thu, 19 Jun 2025 23:01:34 +0300 Subject: [PATCH 3/3] chore: use Java 21 for test workflow --- .github/workflows/main.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c5401b7..0583b41d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,30 +12,25 @@ on: jobs: build: - strategy: - fail-fast: true - matrix: - java-version: - - 8 - - 11 - gradle-version: [wrapper] - name: 'Test, Java ${{ matrix.java-version }}' + name: Test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 50 submodules: true - - name: 'Set up JDK ${{ matrix.java-version }}' + - name: Set up Java uses: actions/setup-java@v4 with: - java-version: ${{ matrix.java-version }} + java-version: | + 8 + 21 distribution: 'zulu' - - name: 'Test' + - name: Test uses: burrunan/gradle-cache-action@v3 with: - job-id: jdk${{ matrix.java-version }} - gradle-version: ${{ matrix.gradle-version }} + job-id: jdk21 + gradle-version: wrapper arguments: | --no-parallel --no-daemon --scan build