diff --git a/build.gradle b/build.gradle index 76339b6d8..b0c88fc11 100644 --- a/build.gradle +++ b/build.gradle @@ -12,15 +12,6 @@ group = "org.hibernate.reactive" // leverage the ProjectVersion which comes from the `local.versions` plugin version = project.projectVersion.fullName -ext { - if ( !project.hasProperty( 'hibernatePublishUsername' ) ) { - hibernatePublishUsername = null - } - if ( !project.hasProperty( 'hibernatePublishPassword' ) ) { - hibernatePublishPassword = null - } -} - // Versions which need to be aligned across modules; this also // allows overriding the build using a parameter, which can be // useful to monitor compatibility for upcoming versions on CI: @@ -39,15 +30,10 @@ ext { logger.lifecycle "Vert.x SQL Client Version: " + project.vertxSqlClientVersion } -// To release, see task ciRelease in release/build.gradle -// To publish on Sonatype (Maven Central): -// ./gradlew publishToSonatype closeAndReleaseStagingRepository -PhibernatePublishUsername="" -PhibernatePublishPassword="" +// Publishing to Sonatype (Maven Central): nexusPublishing { repositories { - sonatype { - username = project.hibernatePublishUsername - password = project.hibernatePublishPassword - } + sonatype() } } diff --git a/ci/release/Jenkinsfile b/ci/release/Jenkinsfile index bb4315fb8..87e009d49 100644 --- a/ci/release/Jenkinsfile +++ b/ci/release/Jenkinsfile @@ -165,24 +165,18 @@ pipeline { configFile(fileId: 'release.config.ssh', targetLocation: "${env.HOME}/.ssh/config"), configFile(fileId: 'release.config.ssh.knownhosts', targetLocation: "${env.HOME}/.ssh/known_hosts") ]) { - withCredentials([ - usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USER'), - usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'PLUGIN_PORTAL_PASSWORD', usernameVariable: 'PLUGIN_PORTAL_USERNAME'), - file(credentialsId: 'release.gpg.private-key', variable: 'RELEASE_GPG_PRIVATE_KEY_PATH'), - string(credentialsId: 'release.gpg.passphrase', variable: 'RELEASE_GPG_PASSPHRASE') - ]) { - sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) { - // set release version - // update changelog from JIRA - // tags the version - // changes the version to the provided development version - withEnv([ - "BRANCH=${env.GIT_BRANCH}", - // Increase the amount of memory for this part since asciidoctor doc rendering consumes a lot of metaspace - "GRADLE_OPTS=-Dorg.gradle.jvmargs='-Dlog4j2.disableJmx -Xmx4g -XX:MaxMetaspaceSize=768m -XX:+HeapDumpOnOutOfMemoryError -Duser.language=en -Duser.country=US -Duser.timezone=UTC -Dfile.encoding=UTF-8'" - ]) { - sh ".release/scripts/prepare-release.sh ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION}" - } + + sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) { + // set release version + // update changelog from JIRA + // tags the version + // changes the version to the provided development version + withEnv([ + "BRANCH=${env.GIT_BRANCH}", + // Increase the amount of memory for this part since asciidoctor doc rendering consumes a lot of metaspace + "GRADLE_OPTS=-Dorg.gradle.jvmargs='-Dlog4j2.disableJmx -Xmx4g -XX:MaxMetaspaceSize=768m -XX:+HeapDumpOnOutOfMemoryError -Duser.language=en -Duser.country=US -Duser.timezone=UTC -Dfile.encoding=UTF-8'" + ]) { + sh ".release/scripts/prepare-release.sh ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION}" } } } @@ -199,10 +193,10 @@ pipeline { configFile(fileId: 'release.config.ssh.knownhosts', targetLocation: "${env.HOME}/.ssh/known_hosts") ]) { withCredentials([ - usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USER'), - usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'PLUGIN_PORTAL_PASSWORD', usernameVariable: 'PLUGIN_PORTAL_USERNAME'), - file(credentialsId: 'release.gpg.private-key', variable: 'RELEASE_GPG_PRIVATE_KEY_PATH'), - string(credentialsId: 'release.gpg.passphrase', variable: 'RELEASE_GPG_PASSPHRASE'), + // https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh + usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'ORG_GRADLE_PROJECT_sonatypePassword', usernameVariable: 'ORG_GRADLE_PROJECT_sonatypeUsername'), + file(credentialsId: 'release.gpg.private-key', variable: 'SIGNING_GPG_PRIVATE_KEY_PATH'), + string(credentialsId: 'release.gpg.passphrase', variable: 'SIGNING_GPG_PASSPHRASE') gitUsernamePassword(credentialsId: 'username-and-token.Hibernate-CI.github.com', gitToolName: 'Default') ]) { sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) { diff --git a/ci/snapshot-publish.Jenkinsfile b/ci/snapshot-publish.Jenkinsfile index c95f6663f..c2fba1d6b 100644 --- a/ci/snapshot-publish.Jenkinsfile +++ b/ci/snapshot-publish.Jenkinsfile @@ -31,15 +31,12 @@ pipeline { stage('Publish') { steps { withCredentials([ - usernamePassword(credentialsId: 'ossrh.sonatype.org', usernameVariable: 'hibernatePublishUsername', passwordVariable: 'hibernatePublishPassword'), - string(credentialsId: 'release.gpg.passphrase', variable: 'SIGNING_PASS'), - file(credentialsId: 'release.gpg.private-key', variable: 'SIGNING_KEYRING') + // https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh + usernamePassword(credentialsId: 'ossrh.sonatype.org', usernameVariable: 'ORG_GRADLE_PROJECT_sonatypeUsername', passwordVariable: 'ORG_GRADLE_PROJECT_sonatypePassword'), + file(credentialsId: 'release.gpg.private-key', variable: 'SIGNING_GPG_PRIVATE_KEY_PATH'), + string(credentialsId: 'release.gpg.passphrase', variable: 'SIGNING_GPG_PASSPHRASE') ]) { - sh '''./gradlew clean publish \ - -PhibernatePublishUsername=$hibernatePublishUsername \ - -PhibernatePublishPassword=$hibernatePublishPassword \ - --no-scan \ - ''' + sh "./gradlew clean publish --no-scan" } } } diff --git a/publish.gradle b/publish.gradle index 3c48e1298..977092d9a 100644 --- a/publish.gradle +++ b/publish.gradle @@ -1,13 +1,14 @@ +apply plugin: 'java' apply plugin: 'maven-publish' +apply plugin: 'signing' -tasks.register( 'sourcesJar', Jar ) { - from sourceSets.main.allJava - archiveClassifier = 'sources' -} +// Java / publishing -tasks.register( 'javadocJar', Jar ) { - from javadoc - archiveClassifier = 'javadoc' +java { + // Configure the Java "software component" to include javadoc and sources jars in addition to the classes jar. + // Ultimately, this component is what makes up the publication for this project. + withJavadocJar() + withSourcesJar() } jar { @@ -35,14 +36,9 @@ javadoc { publishing { publications { - logger.lifecycle "Publishing groupId: '" + project.group + "', version: '" + project.version + "'" - - publishedArtifacts(MavenPublication) { - groupId = project.group - version = project.version + register( "publishedArtifacts", MavenPublication) { from components.java - artifact sourcesJar - artifact javadocJar + pom { name = project.mavenPomName description = project.description @@ -80,3 +76,96 @@ publishing { } } } + + +// Signing + +var signingExtension = project.getExtensions().getByType(SigningExtension) as SigningExtension + +var publishingExtension = project.getExtensions().getByType(PublishingExtension) as PublishingExtension +signingExtension.sign publishingExtension.publications.publishedArtifacts + +var signingKey = resolveSigningKey() +var signingPassphrase = resolveSigningPassphrase() +signingExtension.useInMemoryPgpKeys(signingKey, signingPassphrase) + +gradle.taskGraph.whenReady { TaskExecutionGraph graph -> + boolean wasPublishingRequested = false + + graph.allTasks.each {task -> + if ( task instanceof PublishToMavenRepository ) { + logger.lifecycle( "Found PublishToMavenRepository task : {}", task.path ) + wasPublishingRequested = true + } + } + + if ( wasPublishingRequested ) { + def publishUser = resolvePublishUser() + def publishPass = resolvePublishPass() + if ( publishUser == null || publishPass == null ) { + throw new RuntimeException( "Cannot perform publishing to OSSRH without credentials." ) + } + + logger.lifecycle "Publishing {} : {} : {}", project.group, project.name, project.version + + // require signing if publishing to OSSRH + signingExtension.required = true + } + else if ( signingKey == null || signingPassphrase == null ) { + tasks.withType( Sign ).each { t-> t.enabled = false } + } +} + + +static String resolveSigningKey() { + var key = System.getenv().get( "SIGNING_GPG_PRIVATE_KEY" ) + if ( key != null ) { + return key + } + + var keyFile = System.getenv().get( "SIGNING_GPG_PRIVATE_KEY_PATH" ) + if ( keyFile != null ) { + return new File( keyFile ).text + } + + return null +} + +static String resolveSigningPassphrase() { + return System.getenv().get( "SIGNING_GPG_PASSPHRASE" ) +} + +String resolvePublishUser() { + var envVar = System.getenv().get( "ORG_GRADLE_PROJECT_sonatypeUsername" ) + if ( envVar != null ) { + return envVar + } + + def projectProp = projectPropOrNull( "sonatypeUsername" ) + if ( projectProp != null ) { + return projectProp + } + + return null +} + +String resolvePublishPass() { + var envVar = System.getenv().get( "ORG_GRADLE_PROJECT_sonatypePassword" ) + if ( envVar != null ) { + return envVar + } + + def projectProp = projectPropOrNull( "sonatypePassword" ) + if ( projectProp != null ) { + return projectProp + } + + return null +} + +String projectPropOrNull(String name) { + if ( project.hasProperty( name ) ) { + return project.findProperty( name ) + } + return null; +} \ No newline at end of file