diff --git a/build.gradle b/build.gradle index ae82eac..85d3475 100644 --- a/build.gradle +++ b/build.gradle @@ -1,27 +1,6 @@ plugins { - id "io.github.gradle-nexus.publish-plugin" id "release-process" id 'com.diffplug.spotless' version '6.25.0' apply false id "com.dorongold.task-tree" version "4.0.0" } - -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// OSSRH publishing -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -String hibernatePublishUsername = project.hasProperty( 'hibernatePublishUsername' ) - ? project.property( 'hibernatePublishUsername' ) - : null -String hibernatePublishPassword = project.hasProperty( 'hibernatePublishPassword' ) - ? project.property( 'hibernatePublishPassword' ) - : null - -nexusPublishing { - repositories { - sonatype { - username = hibernatePublishUsername - password = hibernatePublishPassword - } - } -} diff --git a/buildSrc/src/main/groovy/published-java-module.gradle b/buildSrc/src/main/groovy/published-java-module.gradle index 64d8186..6a7be6c 100644 --- a/buildSrc/src/main/groovy/published-java-module.gradle +++ b/buildSrc/src/main/groovy/published-java-module.gradle @@ -5,7 +5,6 @@ plugins { id "maven-publish" id "publishing-config" - id "signing-config" } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -35,4 +34,4 @@ tasks.named( "javadoc", Javadoc ) { "implNote:a:Implementation Note:" ) } -} \ No newline at end of file +} diff --git a/buildSrc/src/main/groovy/release-process.gradle b/buildSrc/src/main/groovy/release-process.gradle index 90d84d5..d5a00d9 100644 --- a/buildSrc/src/main/groovy/release-process.gradle +++ b/buildSrc/src/main/groovy/release-process.gradle @@ -11,7 +11,7 @@ plugins { // - prepareForRelease (this script) // - publishToSonatype (io.github.gradle-nexus.publish-plugin) // - closeSonatypeStagingRepository (io.github.gradle-nexus.publish-plugin) -// - completeRelease (this script) +// - releasePerform (this script) // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def releaseVersion = project.ext.releaseVersion as String @@ -30,7 +30,7 @@ def gitBranch = determineGitBranch( project ) // Processes should execute `prepareForRelease` // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def releasePreparationTask = tasks.register( "releasePreparation" ) { +def releasePreparationTask = tasks.register( "releasePrepare" ) { doFirst { logger.lifecycle "Release version : {}", releaseVersion logger.lifecycle "Development version : {}", developmentVersion @@ -98,13 +98,12 @@ tasks.register( "prepareForRelease" ) { // - commit the version change // // -// Processes should execute `completeRelease` +// Processes should execute `releasePerform` // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def tagReleaseTask = tasks.register( "tagRelease" ) { onlyIf { - changeToReleaseVersionTask.get().didWork - && releaseVersion != developmentVersion + releaseVersion != developmentVersion } doLast { @@ -120,8 +119,7 @@ def changeToDevelopmentVersionTask = tasks.register( 'changeToDevelopmentVersion dependsOn tagReleaseTask onlyIf { - changeToReleaseVersionTask.get().didWork - && releaseVersion != developmentVersion + releaseVersion != developmentVersion } doFirst { @@ -140,8 +138,7 @@ def pushToGitTask = tasks.register( 'pushToGit' ) { dependsOn changeToDevelopmentVersionTask onlyIf { - changeToReleaseVersionTask.get().didWork - && releaseVersion != developmentVersion + releaseVersion != developmentVersion } doLast { @@ -154,7 +151,7 @@ def pushToGitTask = tasks.register( 'pushToGit' ) { } } -tasks.register( "completeRelease" ) { +tasks.register( "releasePerform" ) { dependsOn tagReleaseTask dependsOn changeToDevelopmentVersionTask dependsOn pushToGitTask @@ -224,4 +221,4 @@ static String inputStreamToString(InputStream inputStream) { } } } -} \ No newline at end of file +} diff --git a/buildSrc/src/main/groovy/signing-config.gradle b/buildSrc/src/main/groovy/signing-config.gradle deleted file mode 100644 index 030bcc5..0000000 --- a/buildSrc/src/main/groovy/signing-config.gradle +++ /dev/null @@ -1,127 +0,0 @@ -plugins { - id "signing" -} - -var signingKey = resolveSigningKey() -var signingPassword = findSigningProperty( "signingPassword" ) - -signing { - useInMemoryPgpKeys( signingKey, signingPassword ) - - sign publishing.publications.publishedArtifacts -} - -String resolveSigningKey() { - var key = findSigningProperty( "signingKey" ) - if ( key != null ) { - return key - } - - var keyFile = findSigningProperty( "signingKeyFile" ) - if ( keyFile != null ) { - return new File( keyFile ).text - } - - return null -} - -String findSigningProperty(String propName) { - if ( System.getProperty( propName ) != null ) { - return System.getProperty(propName ) - } - else if ( System.getenv().get( propName ) != null ) { - return System.getenv().get( propName ) - } - else if ( project.hasProperty( propName ) ) { - return project.hasProperty( propName ) - } - else { - return null - } -} - - -var signingTask = project.tasks.named( "signPublishedArtifactsPublication" ) { - doFirst { - if ( signingKey == null || signingPassword == null ) { - throw new GradleException( - "Cannot perform signing without GPG details. Please set the `signingKey` and `signingKeyFile` properties" - ) - } - } -} - -var signingExtension = project.getExtensions().getByType(SigningExtension) as SigningExtension - -tasks.register( "sign" ) { - dependsOn "signPublications" -} - -tasks.register( "signPublications" ) { t -> - tasks.withType( Sign ).configureEach { s -> - t.dependsOn s - } -} - - -boolean wasSigningExplicitlyRequested() { - // check whether signing task was explicitly requested when running the build - // - // NOTE: due to https://discuss.gradle.org/t/how-to-tell-if-a-task-was-explicitly-asked-for-on-the-command-line/42853/3 - // we cannot definitively know whether the task was requested. Gradle really just does not expose this information. - // so we make a convention - we check the "start parameters" object to see which task-names were requested; - // the problem is that these are the raw names directly from the command line. e.g. it is perfectly legal to - // say `gradlew signPubArtPub` in place of `gradlew signPublishedArtifactsPublication` - Gradle will simply - // "expand" the name it finds. However, it does not make that available. - // - // so the convention is that we will check for the following task names - // - // for each of: - // 1. `sign` - // 2. `signPublications` - // 3. `signPublishedArtifactsPublication` - // - // and we check both forms: - // 1. "${taskName}" - // 2. project.path + ":${taskName}" - // - // we need to check both again because of the "start parameters" discussion - - def signingTaskNames = ["sign", "signPublications", "signPublishedArtifactsPublication"] - - for ( String taskName : signingTaskNames ) { - if ( gradle.startParameter.taskNames.contains( taskName ) - || gradle.startParameter.taskNames.contains( "${project.path}:${taskName}" ) ) { - return true - } - } - - return false -} - -if ( wasSigningExplicitlyRequested() ) { - // signing was explicitly requested - signingExtension.required = true -} -else { - gradle.taskGraph.whenReady { graph -> - if ( graph.hasTask( signingTask.get() ) ) { - // signing is scheduled to happen. - // - // we know, from above if-check, that it was not explicitly requested - - // so it is triggered via task dependency. make sure we want it to happen -// var publishingTask = project.tasks.getByName( "publishPublishedArtifactsPublicationToSonatypeRepository" ) as PublishToMavenRepository -// if ( graph.hasTask( publishingTask ) ) { - if ( graph.hasTask( "publishPublishedArtifactsPublicationToSonatypeRepository" ) ) { - // we are publishing to Sonatype OSSRH - we need the signing to happen - signingExtension.required = true - } - else { - // signing was not explicitly requested and we are not publishing to OSSRH, - // so do not sign. - signingTask.get().enabled = false - } - } - - } -} \ No newline at end of file diff --git a/ci/release/Jenkinsfile b/ci/release/Jenkinsfile new file mode 100644 index 0000000..f69816c --- /dev/null +++ b/ci/release/Jenkinsfile @@ -0,0 +1,74 @@ +@Library('hibernate-jenkins-pipeline-helpers') _ + +import org.hibernate.jenkins.pipeline.helpers.version.Version + +pipeline { + agent { + label 'Release' + } + tools { + jdk 'OpenJDK 21 Latest' + } + options { + buildDiscarder logRotator(daysToKeepStr: '30', numToKeepStr: '10') + disableConcurrentBuilds(abortPrevious: false) + } + parameters { + string( + name: 'RELEASE_VERSION', + defaultValue: '', + description: 'The version to be released, e.g. 1.1.0.', + trim: true + ) + string( + name: 'DEVELOPMENT_VERSION', + defaultValue: '', + description: 'The next version to be used after the release, e.g. 1.2.0-SNAPSHOT.', + trim: true + ) + booleanParam( + name: 'RELEASE_DRY_RUN', + defaultValue: false, + description: 'If true, just simulate the release, without pushing any commits or tags, and without uploading any artifacts or documentation.' + ) + } + stages { + stage('Release') { + steps { + script { + // Check that all the necessary parameters are set + if (!params.RELEASE_VERSION) { + throw new IllegalArgumentException("Missing value for parameter RELEASE_VERSION.") + } + if (!params.DEVELOPMENT_VERSION) { + throw new IllegalArgumentException("Missing value for parameter DEVELOPMENT_VERSION.") + } + + def releaseVersion = Version.parseReleaseVersion(params.RELEASE_VERSION) + def developmentVersion = Version.parseDevelopmentVersion(params.DEVELOPMENT_VERSION) + echo "Performing full release for version ${releaseVersion.toString()}" + + configFileProvider([configFile(fileId: 'release.config.ssh', targetLocation: env.HOME + '/.ssh/config'), + configFile(fileId: 'release.config.ssh.knownhosts', targetLocation: env.HOME + '/.ssh/known_hosts')]) { + // using MAVEN_GPG_PASSPHRASE (the default env variable name for passphrase in maven gpg plugin) + withCredentials([file(credentialsId: 'release.gpg.private-key', variable: 'RELEASE_GPG_PRIVATE_KEY_PATH'), + string(credentialsId: 'release.gpg.passphrase', variable: 'JRELEASER_GPG_PASSPHRASE'), + usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'JRELEASER_NEXUS2_PASSWORD', usernameVariable: 'JRELEASER_NEXUS2_USERNAME'), + string(credentialsId: 'Hibernate-CI.github.com', variable: 'JRELEASER_GITHUB_TOKEN')]) { + + sshagent(['ed25519.Hibernate-CI.github.com']) { + sh 'cat $HOME/.ssh/config' + sh 'git clone https://github.com/hibernate/hibernate-release-scripts.git' + env.RELEASE_GPG_HOMEDIR = env.WORKSPACE_TMP + '/.gpg' + sh """ + bash -xe hibernate-release-scripts/release.sh ${params.RELEASE_DRY_RUN ? '-d' : ''} \ + models ${releaseVersion.toString()} ${developmentVersion.toString()} + """ + } + } + } + } + } + } + } +} diff --git a/jreleaser.yml b/jreleaser.yml new file mode 100644 index 0000000..d0538a1 --- /dev/null +++ b/jreleaser.yml @@ -0,0 +1,29 @@ +project: + languages: + java: + groupId: org.hibernate.models + +release: + github: + skipTag: true + skipRelease: true + tagName: '{{projectVersion}}' + +# File signing is always active +signing: + mode: COMMAND + active: ALWAYS + armored: true + +# Deploy JARs and POMs to Maven Central +deploy: + maven: + nexus2: + maven-central: + active: ALWAYS + url: https://oss.sonatype.org/service/local + snapshotUrl: https://oss.sonatype.org/content/repositories/snapshots/ + closeRepository: true + releaseRepository: true + stagingRepositories: + - build/staging-deploy/maven diff --git a/settings.gradle b/settings.gradle index b564790..1023ebb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,6 @@ pluginManagement { plugins { id "org.checkerframework" version "0.6.34" apply false - id "io.github.gradle-nexus.publish-plugin" version "2.0.0" apply false } repositories { gradlePluginPortal()