diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 023cb621c0..7d454c370c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: java-version: 21 - uses: gradle/actions/setup-gradle@v6 - run: ./gradlew spotlessCheck - - run: ./gradlew assemble testClasses + - run: ./gradlew assemble testClasses publishToMavenLocal build-gradle: name: Gradle (Java ${{ matrix.jre }}, ${{ matrix.os }}) diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 8a72da2ef2..3d1f29ca75 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -17,7 +17,7 @@ dependencies { implementation(plugin("errorprone")) implementation(plugin("rewrite")) implementation(plugin("test-logger")) - implementation(plugin("nexus-publish")) + implementation(plugin("maven-publish")) implementation(plugin("develocity")) // TODO: https://github.com/gradle/gradle/issues/15383 diff --git a/build-logic/src/main/kotlin/spotless.java-publish.gradle.kts b/build-logic/src/main/kotlin/spotless.java-publish.gradle.kts index 3c33d1d817..a0391e48ca 100644 --- a/build-logic/src/main/kotlin/spotless.java-publish.gradle.kts +++ b/build-logic/src/main/kotlin/spotless.java-publish.gradle.kts @@ -1,18 +1,9 @@ plugins { `java-library` - `maven-publish` + id("com.vanniktech.maven.publish") signing } -java { - withJavadocJar() - withSourcesJar() -} - -tasks.named("sourcesJar") { - dependsOn(tasks.jar) -} - tasks.withType().configureEach { options { (this as? StandardJavadocDocletOptions)?.apply { @@ -22,160 +13,61 @@ tasks.withType().configureEach { addStringOption("Xdoclint:none", "-quiet") addStringOption("Xwerror", "-quiet") addStringOption("source", "17") - val artifactId = requiredProperty("artifactId") - val org = requiredProperty("org") val version = project.version.toString() val group = project.group.toString() + val artifactId = project.findProperty("POM_ARTIFACT_ID")?.toString() ?: project.name val javadocInfo = - "

$group:$artifactId:$version by DiffPlug

" + "

$group:$artifactId:$version by DiffPlug

" header = javadocInfo - val dotdotGradle = if (project.name.startsWith("eclipse-")) "../../gradle" else "../gradle" - linksOffline("https://docs.gradle.org/6.1.1/javadoc/", "$dotdotGradle/javadoc/gradle") + linksOffline("https://docs.gradle.org/6.1.1/javadoc/", "../gradle/javadoc/gradle") val versionLast = rootSpotlessChangelog.versionLast linksOffline( "https://javadoc.io/static/com.diffplug.spotless/spotless-lib/$versionLast", - "$dotdotGradle/javadoc/spotless-lib", + "../gradle/javadoc/spotless-lib", ) linksOffline( "https://javadoc.io/static/com.diffplug.spotless/spotless-lib-extra/$versionLast", - "$dotdotGradle/javadoc/spotless-lib-extra", + "../gradle/javadoc/spotless-lib-extra", ) } } } -// make sure bad javadoc breaks the build -tasks.check { - dependsOn(tasks.javadoc) -} - -afterEvaluate { - val isExt = project.name.startsWith("eclipse-") - val artifactId = requiredProperty("artifactId") - val org = requiredProperty("org") - val isPluginMaven = artifactId == "spotless-maven-plugin" - val isPluginGradle = pluginManager.hasPlugin("java-gradle-plugin") - - publishing { - publications { - // java-gradle-plugin creates 'pluginMaven' from its own afterEvaluate, with the java - // component already attached. Ours has to run after that one, which it only does because - // java-gradle-plugin is applied earlier in the consumer's plugins block. If that ever - // inverts we would create an empty publication here and ship a POM with no jar, so check - // rather than silently degrade. - val existing = findByName("pluginMaven") as? MavenPublication - check(!isPluginGradle || existing != null) { - "${project.path} applies java-gradle-plugin, which must be applied before " + - "spotless.java-publish so that it can create the 'pluginMaven' publication" - } - val pluginMaven = - existing ?: create("pluginMaven") { from(components["java"]) } - - pluginMaven.apply { - groupId = project.group.toString() - this.artifactId = artifactId - version = project.version.toString() - - pom { - name = artifactId - description = project.description - url = "https://github.com/$org/${rootProject.name}" - scm { - url = "https://github.com/$org/${rootProject.name}" - connection = "scm:git:https://github.com/$org/${rootProject.name}.git" - developerConnection = "scm:git:ssh:git@github.com/$org/${rootProject.name}.git" - } - licenses { - license { - if (isExt) { - name = "Eclipse Public License - v 1.0" - url = "https://www.eclipse.org/legal/epl-v10.html" - } else { - name = "The Apache Software License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - distribution = "repo" - } - } - developers { - if (isExt) { - @Suppress("UNCHECKED_CAST") - val devs = project.findProperty("developers") as? Map> - devs?.forEach { (extId, extValues) -> - developer { - id = extId - name = extValues["name"] - email = extValues["email"] - } - } - } else { - if (isPluginMaven) { - developer { - id = "lutovich" - name = "Konstantin Lutovich" - email = "konstantin.lutovich@neotechnology.com" - } - } - developer { - id = "nedtwigg" - name = "Ned Twigg" - email = "ned.twigg@diffplug.com" - } - } - } - if (isPluginMaven) { - // Maven plugin requires Maven 3.1.0+ to run - withXml { - val rootNode = asNode() - val prerequisites = rootNode.appendNode("prerequisites") - prerequisites.appendNode("maven", "3.1.0") - } - } - } - } +if (System.getenv("JITPACK") == "true") { + signing { + isRequired = false + } +} else { + signing { + if ( + !project.providers.gradleProperty("signingInMemoryKey").isPresent && + System.getenv("ORG_GRADLE_PROJECT_gpg_key64") != null + ) { + val gpgKey = decode64("ORG_GRADLE_PROJECT_gpg_key64") + useInMemoryPgpKeys( + "0x4272C851", + gpgKey, + System.getenv("ORG_GRADLE_PROJECT_gpg_passphrase"), + ) } - if (System.getenv("JITPACK") == "true" || project.version.toString().endsWith("-SNAPSHOT")) { - signing { - isRequired = false - } - } else { - signing { - val gpgKey = decode64("ORG_GRADLE_PROJECT_gpg_key64") - useInMemoryPgpKeys( - "0x4272C851", - gpgKey, - System.getenv("ORG_GRADLE_PROJECT_gpg_passphrase"), - ) - sign(publishing.publications) - } + } - // find the project with the changelog (this project for plugins, root project for libs) - val changelogProject = if (tasks.names.contains("changelogBump")) project else rootProject - val changelogTasks = changelogProject.tasks + // find the project with the changelog (this project for plugins, root project for libs) + val changelogProject = if (pluginManager.hasPlugin("spotless.changelog")) project else rootProject + val changelogTasks = changelogProject.tasks - // ensures that nothing will be built if changelogPush will end up failing - tasks.jar { - dependsOn(changelogTasks.named("changelogCheck")) - } + // ensures that nothing will be built if changelogPush will end up failing + tasks.jar { + dependsOn(changelogTasks.named("changelogCheck")) + } - // ensures that changelog bump and push only happens if the publish was successful - val thisProj = project - changelogTasks.named("changelogBump") { - dependsOn( - ":${thisProj.path.removePrefix(":")}:publishPluginMavenPublicationToSonatypeRepository" - ) - dependsOn(":closeAndReleaseSonatypeStagingRepository") - // if we have a Gradle plugin, we need to push it up to the plugin portal too - if (thisProj.tasks.names.contains("publishPlugins")) { - dependsOn(thisProj.tasks.named("publishPlugins")) - } - } + // ensures that changelog bump and push only happens if the publish was successful + changelogTasks.named("changelogBump") { + dependsOn(tasks.named("publishToMavenCentral")) + // if we have a Gradle plugin, we need to push it up to the plugin portal too + plugins.withId("com.gradle.plugin-publish") { + dependsOn(tasks.named("publishPlugins")) } } } - -tasks.withType().configureEach { - isPreserveFileTimestamps = false - isReproducibleFileOrder = true -} diff --git a/build-logic/src/main/kotlin/spotless.java-setup.gradle.kts b/build-logic/src/main/kotlin/spotless.java-setup.gradle.kts index e759c2720d..d003a5ce18 100644 --- a/build-logic/src/main/kotlin/spotless.java-setup.gradle.kts +++ b/build-logic/src/main/kotlin/spotless.java-setup.gradle.kts @@ -8,6 +8,8 @@ plugins { id("spotless.spotless-conventions") } +group = property("GROUP").toString() + tasks.withType().configureEach { options.encoding = Charsets.UTF_8.name() options.release = libs.versions.jdk.release.map { it.toInt() } diff --git a/build-logic/src/main/kotlin/spotless.nexus-publish.gradle.kts b/build-logic/src/main/kotlin/spotless.nexus-publish.gradle.kts deleted file mode 100644 index a1c54c8487..0000000000 --- a/build-logic/src/main/kotlin/spotless.nexus-publish.gradle.kts +++ /dev/null @@ -1,24 +0,0 @@ -plugins { - id("io.github.gradle-nexus.publish-plugin") -} - -group = "com.diffplug.spotless" - -nexusPublishing { - repositories { - sonatype { - nexusUrl = uri("https://ossrh-staging-api.central.sonatype.com/service/local/") - snapshotRepositoryUrl = uri("https://central.sonatype.com/repository/maven-snapshots/") - username = System.getenv("ORG_GRADLE_PROJECT_nexus_user") - password = decode64("ORG_GRADLE_PROJECT_nexus_pass64") - } - } -} - -val initTask = tasks.named("initializeSonatypeStagingRepository") - -allprojects { - initTask.configure { - shouldRunAfter(tasks.withType()) - } -} diff --git a/build.gradle.kts b/build.gradle.kts index 58c59d06ec..e7aaefd208 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,6 @@ plugins { alias(libs.plugins.version.compatibility) apply false alias(libs.plugins.maven.plugin.development) apply false alias(libs.plugins.p2deps) apply false - id("spotless.nexus-publish") id("spotless.changelog") id("spotless.rewrite") id("spotless.spotless-freshmark") diff --git a/gradle.properties b/gradle.properties index 314a778e40..c0d2db2891 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,17 +6,25 @@ org.gradle.configuration-cache=true org.gradle.configuration-cache.parallel=true org.gradle.kotlin.dsl.allWarningsAsErrors=true -name=spotless -description=Spotless - keep your code spotless with Gradle -org=diffplug -group=com.diffplug.spotless +########## Properties for publishing to Maven Central ########## -artifactIdLib=spotless-lib -artifactIdLibExtra=spotless-lib-extra -artifactIdTestLib=spotless-testlib +mavenCentralPublishing=true +mavenCentralAutomaticPublishing=true +mavenCentralDeploymentValidation=NONE +signAllPublications=true -# naming convention '-maven-plugin' allows mvn 'spotless:check' instead of 'spotless-plugin-maven:check' -artifactIdMaven=spotless-maven-plugin +GROUP=com.diffplug.spotless +POM_DESCRIPTION=Spotless - keep your code spotless with Gradle +POM_URL=https://github.com/diffplug/spotless +POM_SCM_URL=https://github.com/diffplug/spotless +POM_SCM_CONNECTION=scm:git:https://github.com/diffplug/spotless.git +POM_SCM_DEV_CONNECTION=scm:git:ssh:git@github.com/diffplug/spotless.git -artifactIdGradle=spotless-plugin-gradle +POM_LICENSE_NAME=The Apache Software License, Version 2.0 +POM_LICENSE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt +POM_LICENSE_DIST=repo + +POM_DEVELOPER_ID=nedtwigg +POM_DEVELOPER_NAME=Ned Twigg +POM_DEVELOPER_EMAIL=ned.twigg@diffplug.com diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b2860cda20..35b8df8b8a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -74,7 +74,7 @@ plugin-publish = "com.gradle.plugin-publish:2.1.1" equo-ide = "dev.equo.ide:1.7.8" version-compatibility = "io.github.davidburstrom.version-compatibility:0.5.0" p2deps = "dev.equo.p2deps:1.7.8" -nexus-publish = "io.github.gradle-nexus.publish-plugin:2.0.0" +maven-publish = "com.vanniktech.maven.publish:0.37.0" errorprone = "net.ltgt.errorprone:5.1.1" rewrite = "org.openrewrite.rewrite:7.39.0" maven-plugin-development = "org.gradlex.maven-plugin-development:1.0.3" diff --git a/lib-extra/build.gradle.kts b/lib-extra/build.gradle.kts index 4118bcbb7b..63ef257d6e 100644 --- a/lib-extra/build.gradle.kts +++ b/lib-extra/build.gradle.kts @@ -8,8 +8,6 @@ plugins { id("spotless.special-tests") } -extra["artifactId"] = property("artifactIdLibExtra") - version = spotlessChangelog.versionNext dependencies { diff --git a/lib-extra/gradle.properties b/lib-extra/gradle.properties new file mode 100644 index 0000000000..40324fece5 --- /dev/null +++ b/lib-extra/gradle.properties @@ -0,0 +1,2 @@ +POM_ARTIFACT_ID=spotless-lib-extra +POM_NAME=spotless-lib-extra diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 942a72b1de..c39dbe8328 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -8,8 +8,6 @@ plugins { id("spotless.special-tests") } -extra["artifactId"] = property("artifactIdLib") - version = spotlessChangelog.versionNext val needsGlue = diff --git a/lib/gradle.properties b/lib/gradle.properties new file mode 100644 index 0000000000..c04b6557c2 --- /dev/null +++ b/lib/gradle.properties @@ -0,0 +1,2 @@ +POM_ARTIFACT_ID=spotless-lib +POM_NAME=spotless-lib diff --git a/plugin-gradle/build.gradle.kts b/plugin-gradle/build.gradle.kts index b59f4a6f70..33cb375092 100644 --- a/plugin-gradle/build.gradle.kts +++ b/plugin-gradle/build.gradle.kts @@ -13,8 +13,6 @@ plugins { id("spotless.java-publish") } -extra["artifactId"] = property("artifactIdGradle") - version = spotlessChangelog.versionNext dependencies { @@ -60,7 +58,7 @@ gradlePlugin { id = "com.diffplug.spotless" implementationClass = "com.diffplug.gradle.spotless.SpotlessPlugin" displayName = "Spotless formatting plugin" - description = project.description + description = property("POM_DESCRIPTION").toString() tags = listOf( "format", diff --git a/plugin-gradle/gradle.properties b/plugin-gradle/gradle.properties new file mode 100644 index 0000000000..e01cb97a59 --- /dev/null +++ b/plugin-gradle/gradle.properties @@ -0,0 +1,2 @@ +POM_ARTIFACT_ID=spotless-plugin-gradle +POM_NAME=spotless-plugin-gradle diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 7b2cbbad08..56aa4c18ce 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -2,7 +2,7 @@ Spotless is a general-purpose formatting plugin used by [6,000 projects on GitHub (Jan 2023)](https://github.com/search?l=Maven+POM&q=spotless&type=Code). It is completely à la carte, but also includes powerful "batteries-included" if you opt-in. Plugin requires a version of Maven higher or equal to 3.1.0. diff --git a/plugin-maven/build.gradle.kts b/plugin-maven/build.gradle.kts index 1217ec3584..30d9fba106 100644 --- a/plugin-maven/build.gradle.kts +++ b/plugin-maven/build.gradle.kts @@ -7,14 +7,29 @@ plugins { id("spotless.java-publish") } -extra["artifactId"] = property("artifactIdMaven") - version = spotlessChangelog.versionNext mavenPlugin { - name = "Spotless Maven Plugin" - artifactId = property("artifactIdMaven").toString() - description = project.description + name = property("POM_NAME").toString() + artifactId = property("POM_ARTIFACT_ID").toString() + description = property("POM_DESCRIPTION").toString() +} + +mavenPublishing { + pom { + developers { + developer { + id = "lutovich" + name = "Konstantin Lutovich" + email = "konstantin.lutovich@neotechnology.com" + } + } + withXml { + val rootNode = asNode() + val prerequisites = rootNode.appendNode("prerequisites") + prerequisites.appendNode("maven", "3.1.0") + } + } } dependencies { diff --git a/plugin-maven/gradle.properties b/plugin-maven/gradle.properties new file mode 100644 index 0000000000..f0c5eeda09 --- /dev/null +++ b/plugin-maven/gradle.properties @@ -0,0 +1,2 @@ +POM_ARTIFACT_ID=spotless-maven-plugin +POM_NAME=Spotless Maven Plugin diff --git a/settings.gradle.kts b/settings.gradle.kts index 956bc4d804..e446301b93 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,5 @@ +import kotlin.io.encoding.Base64 + pluginManagement { includeBuild("build-logic") repositories { @@ -85,3 +87,26 @@ val excludeMaven = if (!excludeMaven) { include("plugin-maven") // maven-specific glue code } + +fun decode64(varName: String): String { + val envValue = System.getenv(varName) ?: return "" + return String(Base64.Mime.decode(envValue), Charsets.UTF_8) +} + +val projectProperties = startParameter.projectProperties.toMutableMap() + +if (!projectProperties.containsKey("mavenCentralUsername")) { + System.getenv("ORG_GRADLE_PROJECT_nexus_user")?.let { + projectProperties["mavenCentralUsername"] = it + } +} + +if (!projectProperties.containsKey("mavenCentralPassword")) { + decode64("ORG_GRADLE_PROJECT_nexus_pass64") + .takeIf { it.isNotEmpty() } + ?.let { + projectProperties["mavenCentralPassword"] = it + } +} + +startParameter.setProjectProperties(projectProperties) diff --git a/testlib/build.gradle.kts b/testlib/build.gradle.kts index 4956621aa0..68f37a0d93 100644 --- a/testlib/build.gradle.kts +++ b/testlib/build.gradle.kts @@ -6,8 +6,6 @@ plugins { id("spotless.special-tests") } -extra["artifactId"] = property("artifactIdTestLib") - version = spotlessChangelog.versionNext dependencies { diff --git a/testlib/gradle.properties b/testlib/gradle.properties new file mode 100644 index 0000000000..e319d0a4cb --- /dev/null +++ b/testlib/gradle.properties @@ -0,0 +1,2 @@ +POM_ARTIFACT_ID=spotless-testlib +POM_NAME=spotless-testlib