From 1262030f8b3e385119359732064c23ed3233cb88 Mon Sep 17 00:00:00 2001 From: Andreas Schmid Date: Sat, 21 Dec 2019 20:09:49 +0100 Subject: [PATCH 1/3] migrate to "maven-publish" plugin to get rid of deprecated "maven" plugin * migrate project specific settings to use with new API * move referenced sources and javadoc tasks before publishing * classifier are no longer generated so do not need to be removed * TNG nexus stuff is no longer used, therefore removed Open points: * `repackagesAsm` property is initialized too late for retrieving it in `license.gradle` * Is check for non-parallel build on publish still required else use `./gradlew --no-parallel publish` * Is 'signArchive dependsOn finishArchive' or something equivalent still required? * Maybe refactor code to use JUnit* module mechanism also for archunit core Signed-off-by: Andreas Schmid Signed-off-by: Peter Gafert --- .travis.yml | 2 +- archunit-junit/build.gradle | 11 +- archunit-junit/junit4/build.gradle | 7 +- archunit-junit/junit5/api/build.gradle | 7 +- archunit-junit/junit5/engine-api/build.gradle | 8 +- archunit-junit/junit5/engine/build.gradle | 7 +- archunit/build.gradle | 15 +- build-steps/license/license.gradle | 38 ++-- .../maven-integration-test.gradle | 2 +- .../release/expected/archunit-junit4.pom | 2 +- .../release/expected/archunit-junit5-api.pom | 4 +- .../expected/archunit-junit5-engine-api.pom | 2 +- .../expected/archunit-junit5-engine.pom | 4 +- .../release/expected/archunit-junit5.pom | 4 +- build-steps/release/expected/archunit.pom | 5 +- build-steps/release/publish.gradle | 174 +++++++++--------- 16 files changed, 153 insertions(+), 139 deletions(-) diff --git a/.travis.yml b/.travis.yml index b60ac6d13d..4bc3cf9dd9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: java script: -- ./gradlew --no-daemon -PallTests -PscanBuild clean build install runMavenTest +- ./gradlew --no-daemon -PallTests -PscanBuild clean build publishToMavenLocal runMavenTest jdk: - openjdk11 diff --git a/archunit-junit/build.gradle b/archunit-junit/build.gradle index 002b5eeacf..b434cacfe3 100644 --- a/archunit-junit/build.gradle +++ b/archunit-junit/build.gradle @@ -84,8 +84,15 @@ ext.configureJUnitArchive = { configureDependencies -> delegate.with addCleanThirdPartyTask compileJava.dependsOn project(':archunit-junit').finishArchive - install.repositories.mavenInstaller.pom.whenConfigured configureDependencies - uploadArchives.repositories.mavenDeployer.pom.whenConfigured configureDependencies + publishing{ + publications{ + mavenJava{ + pom.withXml { + configureDependencies(asNode().dependencies.first()) // there is only one "dependencies" element + } + } + } + } } } diff --git a/archunit-junit/junit4/build.gradle b/archunit-junit/junit4/build.gradle index d4bd6fb6c4..3f8fdb5012 100644 --- a/archunit-junit/junit4/build.gradle +++ b/archunit-junit/junit4/build.gradle @@ -43,10 +43,9 @@ shadowJar { } } -def configureDependencies = { pom -> - pom.dependencies.removeAll { - it.scope != 'compile' || !(it.artifactId in ['archunit', 'archunit-junit5-api', 'archunit-junit5-engine-api', 'junit']) +def configureDependencies = { deps -> + deps.children().removeIf { dep -> + dep.scope.text() != 'compile' || !(dep.artifactId.text() in ['archunit', 'archunit-junit5-api', 'archunit-junit5-engine-api', 'junit']) } - pom.dependencies.find { it.artifactId == 'archunit' }.classifier = null } this.with project(':archunit-junit').configureJUnitArchive(configureDependencies) \ No newline at end of file diff --git a/archunit-junit/junit5/api/build.gradle b/archunit-junit/junit5/api/build.gradle index 993f18a20e..0f6174d9db 100644 --- a/archunit-junit/junit5/api/build.gradle +++ b/archunit-junit/junit5/api/build.gradle @@ -25,10 +25,9 @@ shadowJar { } } -def configureDependencies = { pom -> - pom.dependencies.removeAll { - it.scope != 'compile' || !(it.artifactId in ['archunit']) +def configureDependencies = { deps -> + deps.children().removeIf { dep -> + dep.scope.text() != 'compile' || !(dep.artifactId.text() in ['archunit']) } - pom.dependencies.find { it.artifactId == 'archunit' }.classifier = null } this.with project(':archunit-junit').configureJUnitArchive(configureDependencies) \ No newline at end of file diff --git a/archunit-junit/junit5/engine-api/build.gradle b/archunit-junit/junit5/engine-api/build.gradle index 8c43e54f84..1f4638a2e9 100644 --- a/archunit-junit/junit5/engine-api/build.gradle +++ b/archunit-junit/junit5/engine-api/build.gradle @@ -36,8 +36,10 @@ shadowJar { } } -def configureDependencies = { pom -> - // dependencies to archunit only cover annotations; we can skip those without breaking consumers to keep the dependency slim - pom.dependencies.removeAll { it.artifactId != 'junit-platform-engine' } +// dependencies to archunit only cover annotations; we can skip those without breaking consumers to keep the dependency slim +def configureDependencies = { deps -> + deps.children().removeIf{ dep -> + dep.artifactId.text() != 'junit-platform-engine' + } } this.with project(':archunit-junit').configureJUnitArchive(configureDependencies) \ No newline at end of file diff --git a/archunit-junit/junit5/engine/build.gradle b/archunit-junit/junit5/engine/build.gradle index 03baaeed2d..92fe9f2808 100644 --- a/archunit-junit/junit5/engine/build.gradle +++ b/archunit-junit/junit5/engine/build.gradle @@ -49,10 +49,9 @@ shadowJar { } } -def configureDependencies = { pom -> - pom.dependencies.removeAll { - it.scope != 'compile' || !(it.artifactId in ['archunit', 'archunit-junit5-api', 'archunit-junit5-engine-api']) +def configureDependencies = { deps -> + deps.children().removeIf { dep -> + dep.scope.text() != 'compile' || !(dep.artifactId.text() in ['archunit', 'archunit-junit5-api', 'archunit-junit5-engine-api']) } - pom.dependencies.find { it.artifactId == 'archunit' }.classifier = null } this.with project(':archunit-junit').configureJUnitArchive(configureDependencies) diff --git a/archunit/build.gradle b/archunit/build.gradle index 2a572498ef..053b830a3d 100644 --- a/archunit/build.gradle +++ b/archunit/build.gradle @@ -30,13 +30,18 @@ shadowJar { } /* Besides SLF4J we'll shadow everything we need into the JAR to avoid conflicts with other libraries*/ -def configureDependenciesAfterShadow = { pom -> - pom.dependencies.removeAll { - it.artifactId != 'slf4j-api' || it.scope != 'compile' +publishing{ + publications{ + mavenJava{ + pom.withXml { + def deps = asNode().dependencies.first() // there is only one "dependencies" element + deps.children().removeIf { dep -> + dep.artifactId.text() != 'slf4j-api' || dep.scope.text() != 'compile' + } + } + } } } -install.repositories.mavenInstaller.pom.whenConfigured configureDependenciesAfterShadow -uploadArchives.repositories.mavenDeployer.pom.whenConfigured configureDependenciesAfterShadow addTestJarTo this configureSlowTestsFor this diff --git a/build-steps/license/license.gradle b/build-steps/license/license.gradle index 7e5c2e9760..829fe4e66a 100644 --- a/build-steps/license/license.gradle +++ b/build-steps/license/license.gradle @@ -87,23 +87,25 @@ task updateLicenses { } releaseProjects*.with { - def installer = install.repositories.mavenInstaller - def deployer = uploadArchives.repositories.mavenDeployer - - [installer, deployer]*.pom*.whenConfigured { - project { - licenses { - license { - name app.license.name - url app.license.url - distribution 'repo' - } - if (repackagesAsm) { - def asmLicense = rootProject.file(asmLicenseFile).readLines() as Queue - license { - name asmLicense.poll().replaceAll(/^.*?: /, '') - url asmLicense.poll().replaceAll(/^.*?: /, '') - distribution 'repo' + ext.repackagesAsm = project.name == "archunit" + publishing { + publications { + mavenJava(MavenPublication) { + pom { + licenses { + license { + name = app.license.name + url = app.license.url + distribution = 'repo' + } + if (repackagesAsm) { + def asmLicense = rootProject.file(asmLicenseFile).readLines() as Queue + license { + name = asmLicense.poll().replaceAll(/^.*?: /, '') + url = asmLicense.poll().replaceAll(/^.*?: /, '') + distribution = 'repo' + } + } } } } @@ -138,4 +140,4 @@ releaseProjects*.with { shadowJar.mustRunAfter updateLicenses } } -} \ No newline at end of file +} diff --git a/build-steps/maven-integration-test/maven-integration-test.gradle b/build-steps/maven-integration-test/maven-integration-test.gradle index fb5bc6fc99..620094ba63 100644 --- a/build-steps/maven-integration-test/maven-integration-test.gradle +++ b/build-steps/maven-integration-test/maven-integration-test.gradle @@ -175,7 +175,7 @@ def addMavenTest = { config -> def executeRulesTask = tasks[executeRules] releaseProjects*.with { - [install, uploadArchives].each { executeRulesTask.mustRunAfter it } + [publish, publishToMavenLocal].each { executeRulesTask.mustRunAfter it } } } } diff --git a/build-steps/release/expected/archunit-junit4.pom b/build-steps/release/expected/archunit-junit4.pom index 9eda131d3e..37b21bc30f 100644 --- a/build-steps/release/expected/archunit-junit4.pom +++ b/build-steps/release/expected/archunit-junit4.pom @@ -1,5 +1,5 @@ - 4.0.0 com.tngtech.archunit diff --git a/build-steps/release/expected/archunit-junit5-api.pom b/build-steps/release/expected/archunit-junit5-api.pom index 2f179b0724..997fba34a7 100644 --- a/build-steps/release/expected/archunit-junit5-api.pom +++ b/build-steps/release/expected/archunit-junit5-api.pom @@ -1,5 +1,5 @@ - 4.0.0 com.tngtech.archunit @@ -49,4 +49,4 @@ compile - \ No newline at end of file + diff --git a/build-steps/release/expected/archunit-junit5-engine-api.pom b/build-steps/release/expected/archunit-junit5-engine-api.pom index e2225590f3..0fd9f9e9af 100644 --- a/build-steps/release/expected/archunit-junit5-engine-api.pom +++ b/build-steps/release/expected/archunit-junit5-engine-api.pom @@ -1,5 +1,5 @@ - 4.0.0 com.tngtech.archunit diff --git a/build-steps/release/expected/archunit-junit5-engine.pom b/build-steps/release/expected/archunit-junit5-engine.pom index 8545d1ce17..b2c49502ee 100644 --- a/build-steps/release/expected/archunit-junit5-engine.pom +++ b/build-steps/release/expected/archunit-junit5-engine.pom @@ -1,5 +1,5 @@ - 4.0.0 com.tngtech.archunit @@ -62,4 +62,4 @@ compile - \ No newline at end of file + diff --git a/build-steps/release/expected/archunit-junit5.pom b/build-steps/release/expected/archunit-junit5.pom index aa9974a580..e27e51002c 100644 --- a/build-steps/release/expected/archunit-junit5.pom +++ b/build-steps/release/expected/archunit-junit5.pom @@ -1,6 +1,6 @@ - + 4.0.0 com.tngtech.archunit archunit-junit5 diff --git a/build-steps/release/expected/archunit.pom b/build-steps/release/expected/archunit.pom index feeda386f8..cfc5434a12 100644 --- a/build-steps/release/expected/archunit.pom +++ b/build-steps/release/expected/archunit.pom @@ -1,5 +1,5 @@ - 4.0.0 com.tngtech.archunit @@ -54,4 +54,5 @@ compile - \ No newline at end of file + + diff --git a/build-steps/release/publish.gradle b/build-steps/release/publish.gradle index 88120b2da0..714e78333a 100644 --- a/build-steps/release/publish.gradle +++ b/build-steps/release/publish.gradle @@ -1,90 +1,18 @@ -releaseProjects*.with { - apply plugin: 'maven' - apply plugin: 'signing' - - install.dependsOn(build) - uploadArchives.dependsOn(build) +ext.isReleaseVersion = !project.version.endsWith("-SNAPSHOT") - signing { - // requires gradle.properties, see http://www.gradle.org/docs/current/userguide/signing_plugin.html - required { - gradle.taskGraph.hasTask('uploadArchives') && project.hasProperty('sonatypeUsername') - } - sign configurations.archives - } - signArchives.dependsOn finishArchive +if (!hasProperty("sonatypeUsername")) { + ext.sonatypeUsername = "" +} +if (!hasProperty("sonatypePassword")) { + ext.sonatypePassword = "" +} - uploadArchives { - doFirst { - assert project.property('org.gradle.parallel') == 'false': - 'uploading archives with parallel execution seems to lead to broken uploads in Sonatype Nexus' - } - - repositories { - mavenDeployer { - beforeDeployment { deployment -> - signing.signPom(deployment) - } - - // respective username and password can be configured in ~/.gradle/gradle.properties - if (project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword')) { - repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2/') { - authentication(userName: sonatypeUsername, password: sonatypePassword) - } - snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') { - authentication(userName: sonatypeUsername, password: sonatypePassword) - } - } - if (project.hasProperty('tngNexusUsername') && project.hasProperty('tngNexusPassword')) { - repository(url: 'https://nexus.int.tngtech.com/repository/maven-releases/') { - authentication(userName: tngNexusUsername, password: tngNexusPassword) - } - snapshotRepository(url: 'https://nexus.int.tngtech.com/repository/maven-snapshots/') { - authentication(userName: tngNexusUsername, password: tngNexusPassword) - } - } - } - } - } - - def installer = install.repositories.mavenInstaller - def deployer = uploadArchives.repositories.mavenDeployer - - [installer, deployer]*.pom*.whenConfigured { - project { - name app.name - description description - url app.urls.entry - - organization { - name company.name - url company.url - } - - scm { - url app.urls.source - connection "scm:${app.gitRepo}" - developerConnection "scm:${app.gitRepo}" - } +releaseProjects*.with { + apply plugin: "maven-publish" + apply plugin: "signing" - developers { - developer { - id 'codecholeric' - name 'Peter Gafert' - email 'peter.gafert@tngtech.com' - } - developer { - id 'rweisleder' - name 'Roland Weisleder' - email 'roland.weisleder@googlemail.com' - } - developer { - id 'hankem' - name 'Manfred Hanke' - email 'manfred.hanke@tngtech.com' - } - } - } + tasks.withType(GenerateModuleMetadata) { + enabled = isReleaseVersion // signing of these artifacts causes failure for snapshot versions } task sourcesJar(type: Jar, dependsOn: classes) { @@ -106,7 +34,79 @@ releaseProjects*.with { } } - artifacts { - archives sourcesJar, javadocJar + publish.dependsOn(build) + + publishing { + publications { + mavenJava(MavenPublication) { + artifactId = project.archivesBaseName + from components.java + artifact tasks.sourcesJar + artifact tasks.javadocJar + pom { + name = app.name + packaging = "jar" + description = project.description + url = app.urls.entry + + developers { + developer { + id = 'codecholeric' + name = 'Peter Gafert' + email = 'peter.gafert@tngtech.com' + } + developer { + id = 'rweisleder' + name = 'Roland Weisleder' + email = 'roland.weisleder@googlemail.com' + } + developer { + id = 'hankem' + name = 'Manfred Hanke' + email = 'manfred.hanke@tngtech.com' + } + } + + organization { + name = company.name + url = company.url + } + + scm { + url = app.urls.source + connection = "scm:${app.gitRepo}" + developerConnection = "scm:${app.gitRepo}" + } + } + } + } + + repositories { + // respective username and password can be configured in ~/.gradle/gradle.properties + if (project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword')) { + maven { + def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + def snapshotRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/" + url = isReleaseVersion ? releasesRepoUrl : snapshotRepoUrl + + credentials { + username = sonatypeUsername + password = sonatypePassword + } + + metadataSources { + gradleMetadata() + } + } + } + } + } + + signing { + // requires gradle.properties, see http://www.gradle.org/docs/current/userguide/signing_plugin.html + required { + isReleaseVersion && gradle.taskGraph.hasTask('publish') && project.hasProperty('sonatypeUsername') + } + sign publishing.publications.mavenJava } -} \ No newline at end of file +} From 675be4f4efe7e7c0040cb9bc52bcf90845a2c6b2 Mon Sep 17 00:00:00 2001 From: Peter Gafert Date: Sun, 9 Feb 2020 22:37:49 +0100 Subject: [PATCH 2/3] add check for non-parallel upload and remove obsolete `repackagesAsm` Somehow uploads to Maven Central break when done in parallel, thus we should keep the check for now. Originally the idea was to keep `repackagesAsm` decentralized, i.e. every project can decide itself. In fact it will always only be `archunit` though, so I think it is easier to keep this logic within `license.gradle`. Signed-off-by: Peter Gafert --- archunit/build.gradle | 3 +-- build-steps/archiving/archiving.gradle | 4 +--- build-steps/release/publish.gradle | 4 ++++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/archunit/build.gradle b/archunit/build.gradle index 053b830a3d..06d8ec8dbc 100644 --- a/archunit/build.gradle +++ b/archunit/build.gradle @@ -20,7 +20,6 @@ dependencies { } } -ext.repackagesAsm = true // Will cause the ASM License to be packaged -> license.gradle shadowJar { exclude 'META-INF/**' @@ -96,4 +95,4 @@ idea { sourceDirs -= jdk9TestDirs.collect { file(it) } testSourceDirs += jdk9TestDirs.collect { file(it) } } -} \ No newline at end of file +} diff --git a/build-steps/archiving/archiving.gradle b/build-steps/archiving/archiving.gradle index 70b14130c3..839ee3f694 100644 --- a/build-steps/archiving/archiving.gradle +++ b/build-steps/archiving/archiving.gradle @@ -5,8 +5,6 @@ buildscript { } subprojects { - ext.repackagesAsm = false - afterEvaluate { tasks.withType(Jar) { manifest { @@ -47,4 +45,4 @@ productionProjects*.with { task finishArchive(dependsOn: shadowJar) {} build.dependsOn(finishArchive) -} \ No newline at end of file +} diff --git a/build-steps/release/publish.gradle b/build-steps/release/publish.gradle index 714e78333a..683c9b55a6 100644 --- a/build-steps/release/publish.gradle +++ b/build-steps/release/publish.gradle @@ -35,6 +35,10 @@ releaseProjects*.with { } publish.dependsOn(build) + publish.doFirst { + assert !gradle.startParameter.isParallelProjectExecutionEnabled(): + 'uploading archives with parallel execution seems to lead to broken uploads in Sonatype Nexus' + } publishing { publications { From 90572b62113ec85cb2c9f509de5d3d428abe9200 Mon Sep 17 00:00:00 2001 From: Andreas Schmid Date: Sun, 16 Feb 2020 13:16:50 +0100 Subject: [PATCH 3/3] make junit5 aggregator a java-library in order to publish them in correct scope automatically. To get the `checkUploadedArtifacts` not to fail, I have to change the order of namespaces of the expected pom. Note: * I also replaced tabs with spaces in `junit5/aggregator/build.gradle`. But only one additinal line, so no separate commit. Signed-off-by: Andreas Schmid --- archunit-junit/junit5/aggregator/build.gradle | 8 +++++--- build-steps/release/expected/archunit-junit5.pom | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/archunit-junit/junit5/aggregator/build.gradle b/archunit-junit/junit5/aggregator/build.gradle index 072e75f61c..5d42410dd8 100644 --- a/archunit-junit/junit5/aggregator/build.gradle +++ b/archunit-junit/junit5/aggregator/build.gradle @@ -1,13 +1,15 @@ +apply plugin: 'java-library' + ext.moduleName = 'com.tngtech.archunit.junit5' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 dependencies { - compile(project(":archunit-junit5-api")) - runtime(project(":archunit-junit5-engine")) + api(project(":archunit-junit5-api")) + implementation(project(":archunit-junit5-engine")) } shadowJar { - exclude '**' + exclude '**' } diff --git a/build-steps/release/expected/archunit-junit5.pom b/build-steps/release/expected/archunit-junit5.pom index e27e51002c..490e28a9a8 100644 --- a/build-steps/release/expected/archunit-junit5.pom +++ b/build-steps/release/expected/archunit-junit5.pom @@ -1,5 +1,6 @@ - 4.0.0 com.tngtech.archunit