From 2a1e6f9be43fa7e8715b4aaf94dd8c3d2e50512a Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 6 Nov 2025 13:02:01 +0100 Subject: [PATCH] Update the order of release steps and simplify the ORM build script [HHH-19913] --- build.gradle | 13 - ci/release/Jenkinsfile | 38 +- documentation/documentation.gradle | 8 + gradle/published-java-module.gradle | 20 +- gradle/publishing-pom.gradle | 1 + gradle/releasable.gradle | 4 +- local-build-plugins/build.gradle | 4 - .../hibernate/orm/docs/DescriptorAccess.java | 82 ---- .../orm/docs/DocumentationPublishing.java | 95 ---- .../docs/DocumentationPublishingPlugin.java | 81 ---- .../orm/docs/GenerateDescriptorTask.java | 88 ---- .../docs/ProjectDocumentationDescriptor.java | 84 ---- .../orm/docs/PublishDescriptorTask.java | 59 --- .../orm/docs/PublishMigrationGuide.java | 71 --- .../org/hibernate/orm/docs/PublishTask.java | 71 --- .../orm/docs/ReleaseFamilyDocumentation.java | 65 --- .../ReleaseFamilyIdentifierMarshalling.java | 31 -- .../org/hibernate/orm/docs/RsyncHelper.java | 22 - release/jenkins-release-process.adoc | 4 +- release/release.gradle | 425 ++---------------- .../hibernate-gradle-plugin.gradle | 16 +- 21 files changed, 76 insertions(+), 1206 deletions(-) delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/DescriptorAccess.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishing.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishingPlugin.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/GenerateDescriptorTask.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/ProjectDocumentationDescriptor.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishDescriptorTask.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishMigrationGuide.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishTask.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyDocumentation.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyIdentifierMarshalling.java delete mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/docs/RsyncHelper.java diff --git a/build.gradle b/build.gradle index 6f2d0d805d98..7076f0f3a447 100644 --- a/build.gradle +++ b/build.gradle @@ -40,19 +40,6 @@ apply from: file( 'gradle/module.gradle' ) // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Release Task -tasks.register('release') { - description = "The task performed when we are performing a release build. Relies on " + - "the fact that subprojects will appropriately define a release task " + - "themselves if they have any release-related activities to perform" - - doFirst { - def javaVersionsInUse = jdkVersions.allVersions - if (javaVersionsInUse != [JavaLanguageVersion.of(11)].toSet()) { - throw new IllegalStateException("Please use JDK 11 to perform the release. Currently using: ${javaVersionsInUse}") - } - } -} - tasks.register('publish') { description = "The task performed when we want to just publish maven artifacts. Relies on " + "the fact that subprojects will appropriately define a release task " + diff --git a/ci/release/Jenkinsfile b/ci/release/Jenkinsfile index 07c3fc97be63..cb589804d9bb 100644 --- a/ci/release/Jenkinsfile +++ b/ci/release/Jenkinsfile @@ -182,7 +182,7 @@ pipeline { configFile(fileId: 'release.config.ssh', targetLocation: "${env.HOME}/.ssh/config"), configFile(fileId: 'release.config.ssh.knownhosts', targetLocation: "${env.HOME}/.ssh/known_hosts") ]) { - sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) { + sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate-ci.frs.sourceforge.net']) { // set release version // update changelog from JIRA // tags the version @@ -217,13 +217,21 @@ pipeline { string(credentialsId: 'release.gpg.passphrase', variable: 'JRELEASER_GPG_PASSPHRASE'), string(credentialsId: 'Hibernate-CI.github.com', variable: 'JRELEASER_GITHUB_TOKEN') ]) { - sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) { + sshagent(['ed25519.Hibernate-CI.github.com', 'jenkins.in.relation.to', 'hibernate-ci.frs.sourceforge.net']) { // performs documentation upload and Sonatype release // push to github withEnv([ "DISABLE_REMOTE_GRADLE_CACHE=true" ]) { - sh ".release/scripts/publish.sh -j ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION} ${env.GIT_BRANCH}" + def notesFiles = findFiles(glob: 'release_notes.md') + if ( notesFiles.length < 1 ) { + throw new IllegalStateException( "Could not locate `release_notes.md`" ) + } + if ( notesFiles.length > 1 ) { + throw new IllegalStateException( "Located more than 1 `release_notes.md`" ) + } + + sh ".release/scripts/publish.sh -j --notes=${notesFiles[0].path} ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION} ${env.GIT_BRANCH} " } } } @@ -254,14 +262,14 @@ pipeline { withCredentials([ 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'] ) { + sshagent( ['ed25519.Hibernate-CI.github.com'] ) { dir( '.release/hibernate.org' ) { - checkout scmGit( - branches: [[name: '*/production']], - extensions: [], - userRemoteConfigs: [[credentialsId: 'ed25519.Hibernate-CI.github.com', url: 'https://github.com/hibernate/hibernate.org.git']] - ) - sh "../scripts/website-release.sh ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION}" + checkout scmGit( + branches: [[name: '*/production']], + extensions: [], + userRemoteConfigs: [[credentialsId: 'ed25519.Hibernate-CI.github.com', url: 'https://github.com/hibernate/hibernate.org.git']] + ) + sh "../scripts/website-release.sh ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION}" } } } @@ -269,16 +277,6 @@ pipeline { } } } - stage('Create GitHub release') { - steps { - script { - checkoutReleaseScripts() - withCredentials([string(credentialsId: 'Hibernate-CI.github.com', variable: 'GITHUB_API_TOKEN')]) { - sh ".release/scripts/github-release.sh ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION}" - } - } - } - } } post { always { diff --git a/documentation/documentation.gradle b/documentation/documentation.gradle index cf9da7d91b1d..829cac6074ea 100644 --- a/documentation/documentation.gradle +++ b/documentation/documentation.gradle @@ -840,4 +840,12 @@ tasks.withType(AsciidoctorTask).configureEach { separateOutputDirs = false backends 'html5' } + // See https://docs.asciidoctor.org/gradle-plugin/latest/common-task-configuration/#choosing-an-execution-mode-for-asciidoctorj + executionMode = org.ysb33r.grolifant.api.core.jvm.ExecutionMode.JAVA_EXEC } + +tasks.withType(AsciidoctorPdfTask).configureEach { + // See https://docs.asciidoctor.org/gradle-plugin/latest/common-task-configuration/#choosing-an-execution-mode-for-asciidoctorj + executionMode = org.ysb33r.grolifant.api.core.jvm.ExecutionMode.JAVA_EXEC +} + diff --git a/gradle/published-java-module.gradle b/gradle/published-java-module.gradle index 4febb8996d26..c7e66ebfbbfa 100644 --- a/gradle/published-java-module.gradle +++ b/gradle/published-java-module.gradle @@ -9,9 +9,6 @@ apply from: rootProject.file( 'gradle/releasable.gradle' ) apply from: rootProject.file( 'gradle/java-module.gradle' ) apply from: rootProject.file( 'gradle/publishing-pom.gradle' ) -// Make sure that the publishReleaseArtifacts task of the release module runs the release task of this sub module -tasks.getByPath( ':release:publishReleaseArtifacts' ).dependsOn tasks.release - configurations { javadocSources { description 'Used to aggregate javadocs for the whole project' @@ -129,10 +126,19 @@ tasks.register('ciBuild') { tasks.release.dependsOn tasks.test -tasks.preVerifyRelease.dependsOn build -tasks.preVerifyRelease.dependsOn generateMetadataFileForPublishedArtifactsPublication -tasks.preVerifyRelease.dependsOn generatePomFileForPublishedArtifactsPublication -tasks.preVerifyRelease.dependsOn generatePomFileForRelocationPomPublication +task releasePrepare { + group 'Release' + description 'Performs release preparations on local check-out, including updating changelog' + + dependsOn build + dependsOn generateMetadataFileForPublishedArtifactsPublication + dependsOn generatePomFileForPublishedArtifactsPublication + dependsOn generatePomFileForRelocationPomPublication + dependsOn generatePomFileForRelocationPomPublication + // we depend on publishAllPublicationsToStagingRepository to make sure that the artifacts are "published" to a local staging directory + // used by JReleaser during the release process + dependsOn publishAllPublicationsToStagingRepository +} // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Ancillary tasks diff --git a/gradle/publishing-pom.gradle b/gradle/publishing-pom.gradle index cb8bfa7f72b5..0cdf48b676a6 100644 --- a/gradle/publishing-pom.gradle +++ b/gradle/publishing-pom.gradle @@ -74,3 +74,4 @@ publishing { } } + diff --git a/gradle/releasable.gradle b/gradle/releasable.gradle index eb5052d02db7..e11c1796fb0d 100644 --- a/gradle/releasable.gradle +++ b/gradle/releasable.gradle @@ -5,6 +5,6 @@ task release { enabled !project.ormVersion.isSnapshot } -task preVerifyRelease { - dependsOn ':release:preVerifyRelease' +task prepareRelease { + dependsOn ':release:prepareRelease' } diff --git a/local-build-plugins/build.gradle b/local-build-plugins/build.gradle index 70f3b7204175..fd490facce5d 100644 --- a/local-build-plugins/build.gradle +++ b/local-build-plugins/build.gradle @@ -52,10 +52,6 @@ gradlePlugin { id = 'org.hibernate.orm.build.reports' implementationClass = 'org.hibernate.orm.post.ReportGenerationPlugin' } - docPubPlugin { - id = 'org.hibernate.orm.build.doc-pub' - implementationClass = 'org.hibernate.orm.docs.DocumentationPublishingPlugin' - } envSettings { id = 'org.hibernate.orm.build.env-settings' implementationClass = 'org.hibernate.orm.env.EnvironmentSettingsPlugin' diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/DescriptorAccess.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/DescriptorAccess.java deleted file mode 100644 index 596800e7650b..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/DescriptorAccess.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; - -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; -import jakarta.json.bind.JsonbConfig; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; - -/** - * Models the published doc descriptor file - * - * @author Steve Ebersole - */ -public class DescriptorAccess { - public static final String DETAILS_URL = "https://docs.jboss.org/hibernate/_outdated-content/orm.json"; - - /** - * Load the descriptor - */ - public static ProjectDocumentationDescriptor loadProject() { - try ( final CloseableHttpClient httpClient = HttpClientBuilder.create().build() ) { - final HttpGet request = new HttpGet( DETAILS_URL ); - - try ( final CloseableHttpResponse response = httpClient.execute( request ) ) { - final HttpEntity responseEntity = response.getEntity(); - //noinspection resource - final Jsonb jsonb = JsonbBuilder.create( new JsonbConfig().withFormatting( true ) ); - return jsonb.fromJson( responseEntity.getContent(), ProjectDocumentationDescriptor.class ); - } - } - catch (IOException e) { - throw new RuntimeException( "Unable to create HttpClient", e ); - } - } - - public static void storeProject(ProjectDocumentationDescriptor project, File jsonFile) { - prepareJsonFile( jsonFile ); - - //noinspection resource - final Jsonb jsonb = JsonbBuilder.create( new JsonbConfig().withFormatting( true ) ); - - try ( final FileWriter writer = new FileWriter( jsonFile ) ) { - jsonb.toJson( project, writer ); - } - catch (IOException e) { - throw new RuntimeException( "Unable to open write for JSON file : " + jsonFile.getPath(), e ); - } - } - - private static void prepareJsonFile(File jsonFile) { - if ( jsonFile.exists() ) { - final boolean deleted = jsonFile.delete(); - assert deleted; - } - - if ( ! jsonFile.getParentFile().exists() ) { - final boolean dirsMade = jsonFile.getParentFile().mkdirs(); - assert dirsMade; - } - - try { - final boolean created = jsonFile.createNewFile(); - assert created; - } - catch (IOException e) { - throw new RuntimeException( "Unable to create JSON file : `" + jsonFile.getPath() + "`", e ); - } - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishing.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishing.java deleted file mode 100644 index 41dfc6dba5d8..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishing.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import javax.inject.Inject; - -import org.gradle.api.Project; -import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.file.RegularFile; -import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.provider.Provider; - -import org.hibernate.orm.ReleaseFamilyIdentifier; - -/** - * Gradle DSL extension for configuring documentation publishing - * - * @author Steve Ebersole - */ -public class DocumentationPublishing { - public static final String DSL_NAME = "documentationPublishing"; - - private final Project project; - - private final DirectoryProperty stagingDirectory; - private final Property docServerUrl; - - private final Property docDescriptorUploadUrl; - private final RegularFileProperty updatedJsonFile; - - private final ReleaseFamilyIdentifier releaseFamilyIdentifier; - - @Inject - public DocumentationPublishing(Project project) { - this.project = project; - - stagingDirectory = project.getObjects() - .directoryProperty() - .convention( project.getLayout().getBuildDirectory().dir( "documentation" ) ); - - docServerUrl = project.getObjects() - .property( String.class ) - .convention( "filemgmt-prod-sync.jboss.org:/docs_htdocs/hibernate/orm" ); - - docDescriptorUploadUrl = project.getObjects() - .property( String.class ) - .convention( "filemgmt-prod-sync.jboss.org:/docs_htdocs/hibernate/_outdated-content/orm.json" ); - - - updatedJsonFile = project.getObjects() - .fileProperty() - .convention( project.getLayout().getBuildDirectory().file( "doc-pub/orm.json" ) ); - - releaseFamilyIdentifier = ReleaseFamilyIdentifier.parse( project.getVersion().toString() ); - } - - public ReleaseFamilyIdentifier getReleaseFamilyIdentifier() { - return releaseFamilyIdentifier; - } - - public Property getDocServerUrl() { - return docServerUrl; - } - - public DirectoryProperty getStagingDirectory() { - return stagingDirectory; - } - - /** - * Where to upload the {@link #getUpdatedJsonFile() documentation descriptor} - */ - public Property getDocDescriptorUploadUrl() { - return docDescriptorUploadUrl; - } - - /** - * THe ORM documentation descriptor - */ - public Provider getUpdatedJsonFile() { - return updatedJsonFile; - } - - public void setUpdatedJsonFile(Object ref) { - updatedJsonFile.fileValue( project.file( ref ) ); - } - - public void updatedJsonFile(Object ref) { - updatedJsonFile.fileValue( project.file( ref ) ); - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishingPlugin.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishingPlugin.java deleted file mode 100644 index 0318221e1bb0..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/DocumentationPublishingPlugin.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.tasks.TaskProvider; - -import static org.hibernate.orm.docs.DocumentationPublishing.DSL_NAME; -import static org.hibernate.orm.docs.GenerateDescriptorTask.GEN_DESC_TASK_NAME; -import static org.hibernate.orm.docs.PublishDescriptorTask.UPLOAD_DESC_TASK_NAME; -import static org.hibernate.orm.docs.PublishTask.UPLOAD_TASK_NAME; - -/** - * Plugin for helping with publishing documentation to the doc server -
    - *
  • Publishes a config extension ({@link DocumentationPublishing}) under {@value DocumentationPublishing#DSL_NAME}
  • - *
  • Creates a task ({@value PublishTask#UPLOAD_TASK_NAME}) to upload the documentation to the doc server
  • - *
  • Creates a task ({@value GenerateDescriptorTask#GEN_DESC_TASK_NAME}) to create the "published doc descriptor" (JSON) file
  • - *
  • Creates a task ({@value PublishDescriptorTask#UPLOAD_DESC_TASK_NAME}) to upload the "published doc descriptor" (JSON) file to the doc server
  • - *
- * - * @author Steve Ebersole - */ -public class DocumentationPublishingPlugin implements Plugin { - @Override - public void apply(Project project) { - final DocumentationPublishing docPubDsl = project.getExtensions().create( DSL_NAME, DocumentationPublishing.class ); - - final boolean isSnapshot = project.getVersion().toString().endsWith( "-SNAPSHOT" ); - - final TaskProvider generateDescriptorTask = project.getTasks().register( - GEN_DESC_TASK_NAME, - GenerateDescriptorTask.class, - (task) -> { - task.getCurrentlyBuildingFamily().convention( docPubDsl.getReleaseFamilyIdentifier() ); - task.getJsonFile().convention( docPubDsl.getUpdatedJsonFile() ); - } - ); - - final TaskProvider uploadDescriptorTask = project.getTasks().register( - UPLOAD_DESC_TASK_NAME, - PublishDescriptorTask.class, - (task) -> { - task.getDocDescriptorUploadUrl().convention( docPubDsl.getDocDescriptorUploadUrl() ); - task.getJsonFile().convention( docPubDsl.getUpdatedJsonFile() ); - - task.dependsOn( generateDescriptorTask ); - task.onlyIf( (t) -> !isSnapshot && generateDescriptorTask.get().getDidWork() ); - } - ); - - //noinspection unused - final TaskProvider publishMigrationGuideTask = project.getTasks().register( - PublishMigrationGuide.NAME, - PublishMigrationGuide.class, - (task) -> { - task.getCurrentlyBuildingFamily().convention( docPubDsl.getReleaseFamilyIdentifier() ); - task.getDocServerUrl().convention( docPubDsl.getDocServerUrl() ); - task.getMigrationGuideDirectory().convention( project.getLayout().getBuildDirectory().dir( "documentation/migration-guide" ) ); - } - ); - - //noinspection unused - final TaskProvider uploadTask = project.getTasks().register( - UPLOAD_TASK_NAME, - PublishTask.class, - (task) -> { - task.getBuildingFamily().convention( docPubDsl.getReleaseFamilyIdentifier() ); - task.getDocServerUrl().convention( docPubDsl.getDocServerUrl() ); - task.getStagingDirectory().convention( docPubDsl.getStagingDirectory() ); - - task.dependsOn( uploadDescriptorTask ); - task.onlyIf( (t) -> !isSnapshot ); - } - ); - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/GenerateDescriptorTask.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/GenerateDescriptorTask.java deleted file mode 100644 index d2a52c7a6b05..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/GenerateDescriptorTask.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import java.io.File; - -import org.gradle.api.DefaultTask; -import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.OutputFile; -import org.gradle.api.tasks.TaskAction; - -import org.hibernate.orm.ReleaseFamilyIdentifier; - -/** - * @author Steve Ebersole - */ -public abstract class GenerateDescriptorTask extends DefaultTask { - public static final String GEN_DESC_TASK_NAME = "generateDocumentationDescriptor"; - private final RegularFileProperty jsonFile; - private final Property currentlyBuildingFamily; - - public GenerateDescriptorTask() { - setGroup( "documentation" ); - setDescription( "Generates the documentation publication descriptor (JSON)" ); - - jsonFile = getProject().getObjects().fileProperty(); - currentlyBuildingFamily = getProject().getObjects().property( ReleaseFamilyIdentifier.class ); - } - - @Input - public Property getCurrentlyBuildingFamily() { - return currentlyBuildingFamily; - } - - @OutputFile - public RegularFileProperty getJsonFile() { - return jsonFile; - } - - @TaskAction - public void generateDescriptor() { - final ProjectDocumentationDescriptor descriptor = DescriptorAccess.loadProject(); - - ReleaseFamilyIdentifier newest = null; - boolean foundCurrentRelease = false; - - for ( ReleaseFamilyDocumentation releaseFamily : descriptor.getReleaseFamilies() ) { - if ( newest == null - || releaseFamily.getName().newerThan( newest ) ) { - newest = releaseFamily.getName(); - } - - if ( releaseFamily.getName().equals( currentlyBuildingFamily.get() ) ) { - foundCurrentRelease = true; - } - } - - if ( ! foundCurrentRelease ) { - final ReleaseFamilyDocumentation newEntry = new ReleaseFamilyDocumentation(); - newEntry.setName( currentlyBuildingFamily.get() ); - descriptor.addReleaseFamily( newEntry ); - setDidWork( true ); - } - - // we only want to update "stable" to `currentlyBuildingFamily` when- - // 1. we are currently building a Final - // 2. currentlyBuildingFamily is the newest - - if ( currentlyBuildingFamily.get().newerThan( newest ) ) { - descriptor.setStableFamily( currentlyBuildingFamily.get() ); - setDidWork( true ); - } - - DescriptorAccess.storeProject( descriptor, jsonFile.get().getAsFile() ); - } - - public static void main(String... args) { - final File jsonFile = new File( "/home/sebersole/projects/hibernate-orm/6.0/hibernate-orm-build/target/doc-pub/orm.json" ); - final ProjectDocumentationDescriptor projectDoc = DescriptorAccess.loadProject(); - DescriptorAccess.storeProject( projectDoc, jsonFile ); - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/ProjectDocumentationDescriptor.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/ProjectDocumentationDescriptor.java deleted file mode 100644 index 5213f22e816a..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/ProjectDocumentationDescriptor.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import java.util.List; -import java.util.Map; - -import org.hibernate.orm.ReleaseFamilyIdentifier; - -import jakarta.json.bind.annotation.JsonbProperty; -import jakarta.json.bind.annotation.JsonbPropertyOrder; -import jakarta.json.bind.annotation.JsonbTypeAdapter; - -/** - * Binding for the doc-pub descriptor (JSON) file - * - * @author Steve Ebersole - */ -@JsonbPropertyOrder( {"name", "stableFamily", "singlePageDetails", "multiPageDetails", "releaseFamilies" } ) -public class ProjectDocumentationDescriptor { - @JsonbProperty( "project" ) - private String name; - - @JsonbProperty( "stable" ) - @JsonbTypeAdapter( ReleaseFamilyIdentifierMarshalling.class ) - private ReleaseFamilyIdentifier stableFamily; - - @JsonbProperty( "versions" ) - private List releaseFamilies; - - @JsonbProperty( "multi" ) - private Map multiPageDetails; - @JsonbProperty( "single" ) - private Map singlePageDetails; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ReleaseFamilyIdentifier getStableFamily() { - return stableFamily; - } - - public void setStableFamily(ReleaseFamilyIdentifier stableFamily) { - this.stableFamily = stableFamily; - } - - public List getReleaseFamilies() { - return releaseFamilies; - } - - public void setReleaseFamilies(List releaseFamilies) { - this.releaseFamilies = releaseFamilies; - } - - public void addReleaseFamily(ReleaseFamilyDocumentation familyDetails) { - // Add new entries at the top - releaseFamilies.add( 0, familyDetails ); - } - - public Map getMultiPageDetails() { - return multiPageDetails; - } - - public void setMultiPageDetails(Map multiPageDetails) { - this.multiPageDetails = multiPageDetails; - } - - public Map getSinglePageDetails() { - return singlePageDetails; - } - - public void setSinglePageDetails(Map singlePageDetails) { - this.singlePageDetails = singlePageDetails; - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishDescriptorTask.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishDescriptorTask.java deleted file mode 100644 index 13d2d354b286..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishDescriptorTask.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import org.gradle.api.DefaultTask; -import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.provider.Provider; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.SkipWhenEmpty; -import org.gradle.api.tasks.TaskAction; - -/** - * @author Steve Ebersole - */ -public abstract class PublishDescriptorTask extends DefaultTask { - public static final String UPLOAD_DESC_TASK_NAME = "uploadDocumentationDescriptor"; - - private final Provider projectVersion; - private final Property docDescriptorUploadUrl; - private final RegularFileProperty jsonFile; - - public PublishDescriptorTask() { - setGroup( "documentation" ); - setDescription( "Publishes the documentation publication descriptor (JSON)" ); - - projectVersion = getProject().provider( () -> getProject().getVersion() ); - docDescriptorUploadUrl = getProject().getObjects().property( String.class ); - jsonFile = getProject().getObjects().fileProperty(); - } - - @InputFile - @SkipWhenEmpty - public RegularFileProperty getJsonFile() { - return jsonFile; - } - - @Input - public Property getDocDescriptorUploadUrl() { - return docDescriptorUploadUrl; - } - - @Input - public Provider getProjectVersion() { - return projectVersion; - } - - - @TaskAction - public void uploadDescriptor() { - final String url = docDescriptorUploadUrl.get(); - RsyncHelper.rsync( jsonFile.get(), url, getProject() ); - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishMigrationGuide.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishMigrationGuide.java deleted file mode 100644 index b7d5cb47a03d..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishMigrationGuide.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.hibernate.orm.docs; - -import org.gradle.api.DefaultTask; -import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.provider.Provider; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputDirectory; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; -import org.gradle.api.tasks.TaskAction; - -import org.hibernate.orm.ReleaseFamilyIdentifier; - -/** - * @author Steve Ebersole - */ -public abstract class PublishMigrationGuide extends DefaultTask { - public static final String NAME = "publishMigrationGuide"; - - private final Provider projectVersion; - private final Property currentlyBuildingFamily; - private final Property docServerUrl; - private final DirectoryProperty migrationGuideDirectory; - - public PublishMigrationGuide() { - setGroup( "documentation" ); - setDescription( "Publishes the migration-guide associated with the current branch. " + - "Intended for incremental publishing of the guide for corrections, etc. without doing a full release. " + - "Note that this is not needed when doing a release as the migration-guide is published as part of that workflow." ); - - getInputs().property( "hibernate-version", getProject().getVersion() ); - - projectVersion = getProject().provider( () -> getProject().getVersion() ); - currentlyBuildingFamily = getProject().getObjects().property( ReleaseFamilyIdentifier.class ); - - docServerUrl = getProject().getObjects().property( String.class ); - migrationGuideDirectory = getProject().getObjects().directoryProperty(); - } - - @Input - public Provider getProjectVersion() { - return projectVersion; - } - - @InputDirectory - @PathSensitive(PathSensitivity.RELATIVE) - public DirectoryProperty getMigrationGuideDirectory() { - return migrationGuideDirectory; - } - - @Input - public Property getDocServerUrl() { - return docServerUrl; - } - - - @Input - public Property getCurrentlyBuildingFamily() { - return currentlyBuildingFamily; - } - - @TaskAction - public void uploadMigrationGuide() { - final String base = docServerUrl.get(); - final String normalizedBase = base.endsWith( "/" ) ? base : base + "/"; - final String url = normalizedBase + currentlyBuildingFamily.get().toExternalForm() + "/migration-guide/"; - - RsyncHelper.rsync( migrationGuideDirectory.get(), url, getProject() ); - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishTask.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishTask.java deleted file mode 100644 index 77e48c154799..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/PublishTask.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import org.gradle.api.DefaultTask; -import org.gradle.api.file.Directory; -import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputDirectory; -import org.gradle.api.tasks.TaskAction; -import org.gradle.process.ExecResult; - -import org.hibernate.orm.ReleaseFamilyIdentifier; - -/** - * @author Steve Ebersole - */ -public abstract class PublishTask extends DefaultTask { - public static final String UPLOAD_TASK_NAME = "uploadDocumentation"; - - private final Property buildingFamily; - private final Property docServerUrl; - private final DirectoryProperty stagingDirectory; - - public PublishTask() { - setGroup( "documentation" ); - setDescription( "Publish documentation to the doc server" ); - - buildingFamily = getProject().getObjects().property( ReleaseFamilyIdentifier.class ); - docServerUrl = getProject().getObjects().property( String.class ); - stagingDirectory = getProject().getObjects().directoryProperty(); - } - - @Input - public Property getDocServerUrl() { - return docServerUrl; - } - - @Input - public Property getBuildingFamily() { - return buildingFamily; - } - - @InputDirectory - public Property getStagingDirectory() { - return stagingDirectory; - } - - @TaskAction - public void uploadDocumentation() { - final String releaseFamily = buildingFamily.get().toExternalForm(); - final String base = docServerUrl.get(); - final String normalizedBase = base.endsWith( "/" ) ? base : base + "/"; - final String url = normalizedBase + releaseFamily; - - final String stagingDirPath = stagingDirectory.get().getAsFile().getAbsolutePath(); - final String stagingDirPathContent = stagingDirPath.endsWith( "/" ) ? stagingDirPath : stagingDirPath + "/"; - - getProject().getLogger().lifecycle( "Uploading documentation `{}` -> `{}`", stagingDirPath, url ); - final ExecResult result = getProject().exec( (exec) -> { - exec.executable( "rsync" ); - exec.args("--port=2222", "-avz", "--links", "--delete", stagingDirPathContent, url ); - } ); - getProject().getLogger().lifecycle( "Done uploading documentation - {}", result.getExitValue() == 0 ? "success" : "failure" ); - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyDocumentation.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyDocumentation.java deleted file mode 100644 index 96e71c5ad560..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyDocumentation.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import java.util.HashMap; -import java.util.Map; - -import org.hibernate.orm.ReleaseFamilyIdentifier; - -import jakarta.json.bind.annotation.JsonbProperty; -import jakarta.json.bind.annotation.JsonbPropertyOrder; -import jakarta.json.bind.annotation.JsonbTypeAdapter; - -/** - * Binding for the doc-pub descriptor (JSON) related to a specific release family. - * - * @see ProjectDocumentationDescriptor - * - * @author Steve Ebersole - */ -@JsonbPropertyOrder( { "name", "redirects" } ) -public class ReleaseFamilyDocumentation { - @JsonbProperty( "version" ) - @JsonbTypeAdapter( ReleaseFamilyIdentifierMarshalling.class ) - private ReleaseFamilyIdentifier name; - private Map redirects; - - public ReleaseFamilyDocumentation() { - } - - /** - * The release family, e.g. `6.0` or `5.6` - */ - public ReleaseFamilyIdentifier getName() { - return name; - } - - public void setName(ReleaseFamilyIdentifier name) { - this.name = name; - } - - public Map getRedirects() { - return redirects; - } - - public void setRedirects(Map redirects) { - this.redirects = redirects; - } - - public void redirect(String from, String to) { - if ( redirects == null ) { - redirects = new HashMap<>(); - } - redirects.put( from, to ); - } - - @Override - public String toString() { - return "ReleaseFamilyDocumentation( " + name + ")"; - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyIdentifierMarshalling.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyIdentifierMarshalling.java deleted file mode 100644 index f2e9d17cddaa..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/ReleaseFamilyIdentifierMarshalling.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.docs; - -import org.hibernate.orm.ReleaseFamilyIdentifier; - -import jakarta.json.Json; -import jakarta.json.JsonString; -import jakarta.json.JsonValue; -import jakarta.json.bind.adapter.JsonbAdapter; - -/** - * @author Steve Ebersole - */ -public class ReleaseFamilyIdentifierMarshalling implements JsonbAdapter { - @Override - public JsonValue adaptToJson(ReleaseFamilyIdentifier obj) throws Exception { - return Json.createValue( obj.toExternalForm() ); - } - - @Override - public ReleaseFamilyIdentifier adaptFromJson(JsonValue obj) throws Exception { - assert obj.getValueType() == JsonValue.ValueType.STRING; - final JsonString jsonString = (JsonString) obj; - return ReleaseFamilyIdentifier.parse( jsonString.getString() ); - } -} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/docs/RsyncHelper.java b/local-build-plugins/src/main/java/org/hibernate/orm/docs/RsyncHelper.java deleted file mode 100644 index 2cc8a0b52eac..000000000000 --- a/local-build-plugins/src/main/java/org/hibernate/orm/docs/RsyncHelper.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.hibernate.orm.docs; - -import org.gradle.api.Project; -import org.gradle.api.file.FileSystemLocation; - -/** - * Helper for performing rsync system commands, mainly used to centralize - * the command options - * - * @author Steve Ebersole - */ -public class RsyncHelper { - public static void rsync( - FileSystemLocation source, - String targetUrl, - Project project) { - project.exec( (exec) -> { - exec.executable( "rsync" ); - exec.args( "--port=2222", "-avz", source.getAsFile().getAbsolutePath(), targetUrl ); - } ); - } -} diff --git a/release/jenkins-release-process.adoc b/release/jenkins-release-process.adoc index bc050ee2d1ca..c1164a98adcc 100644 --- a/release/jenkins-release-process.adoc +++ b/release/jenkins-release-process.adoc @@ -15,7 +15,7 @@ First, a list of resources you will need access to in order to perform a release == Steps -1. Perform `./gradlew preVerifyRelease` locally (after pulling all upstream changes). The Jenkins job does only the release steps, and we need to make sure tests and checkstyle especially are ok +1. Perform `./gradlew prepareRelease` locally (after pulling all upstream changes). The Jenkins job does only the release steps, and we need to make sure tests and checkstyle especially are ok 2. Mark the version as released in Jira 3. Close all issues associated with the version as closed. Be sure to remove the version from any issues that are not resolved (e.g. rejected) - the Jira "release notes" mechanism includes all issues with that version as the fix-for regardless of the resolution 4. Start the https://ci.hibernate.org/view/ORM/job/hibernate-orm-release/[Jenkins job]. It is a parameterized build - Jenkins will prompt user for needed information: @@ -34,4 +34,4 @@ The Jenkins job performs the following tasks: == Post-release steps -See <<./post-release-steps.adoc>> \ No newline at end of file +See <<./post-release-steps.adoc>> diff --git a/release/release.gradle b/release/release.gradle index 9e152f335f5b..37437a7e6658 100644 --- a/release/release.gradle +++ b/release/release.gradle @@ -11,7 +11,6 @@ import groovy.json.JsonSlurper */ apply from: rootProject.file( 'gradle/module.gradle' ) -apply plugin: 'org.hibernate.orm.build.doc-pub' apply plugin: 'org.hibernate.orm.build.jdks' apply plugin: 'idea' @@ -28,7 +27,7 @@ def stageIntegrationGuideTask = tasks.register( "stageIntegrationGuide", Copy ) dependsOn ":documentation:renderIntegrationGuides" from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/integrationguide" ) } - into layout.buildDirectory.dir( "documentation/integrationguide" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/integrationguide") } def stageQuickstartTask = tasks.register( "stageQuickstart", Copy ) { @@ -37,7 +36,7 @@ def stageQuickstartTask = tasks.register( "stageQuickstart", Copy ) { dependsOn ':documentation:renderGettingStartedGuides' from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/quickstart" ) } - into layout.buildDirectory.dir( "documentation/quickstart" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/quickstart") } def stageTopicalGuideTask = tasks.register( "stageTopicalGuide", Copy ) { @@ -46,8 +45,7 @@ def stageTopicalGuideTask = tasks.register( "stageTopicalGuide", Copy ) { dependsOn ':documentation:renderTopicalGuides' from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/topical" ) } - into layout.buildDirectory.dir( "documentation/topical" ) - + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/topical") } def stageIntroductionGuideTask = tasks.register( "stageIntroductionGuide", Copy ) { @@ -56,7 +54,7 @@ def stageIntroductionGuideTask = tasks.register( "stageIntroductionGuide", Copy dependsOn ':documentation:renderIntroductionGuides' from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/introduction" ) } - into layout.buildDirectory.dir( "documentation/introduction" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/introduction") } def stageQueryGuideTasks = tasks.register( "stageQueryGuide", Copy ) { @@ -67,7 +65,16 @@ def stageQueryGuideTasks = tasks.register( "stageQueryGuide", Copy ) { dependsOn ':documentation:renderQueryLanguageGuides' from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/querylanguage" ) } - into layout.buildDirectory.dir( "documentation/querylanguage" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/querylanguage") +} + +def stageRepositoriesGuideTask = tasks.register( "stageRepositoriesGuide", Copy ) { + group 'documentation' + description "Stages the Repositories Guide as part of preparing for release" + dependsOn ':documentation:renderRepositories' + + from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/repositories" ) } + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/repositories") } def stageUserGuideTask = tasks.register( "stageUserGuide", Copy ) { @@ -78,7 +85,7 @@ def stageUserGuideTask = tasks.register( "stageUserGuide", Copy ) { dependsOn ':documentation:renderUserGuides' from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/userguide" ) } - into layout.buildDirectory.dir( "documentation/userguide" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/userguide") } @@ -88,11 +95,7 @@ def stageMigrationGuideTask = tasks.register( "stageMigrationGuide", Copy ) { dependsOn ':documentation:renderMigrationGuide' from project.provider { project( ":documentation" ).layout.buildDirectory.dir( "asciidoc/migration-guide" ) } - into layout.buildDirectory.dir( "documentation/migration-guide" ) -} - -tasks.named( "publishMigrationGuide" ).configure { - dependsOn stageMigrationGuide + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/migration-guide") } def stageIncubationReportTask = tasks.register( "stageIncubationReport", Copy ) { task -> @@ -103,7 +106,7 @@ def stageIncubationReportTask = tasks.register( "stageIncubationReport", Copy ) tasks.stageOrmReports.dependsOn task from project( ":documentation" ).tasks.generateIncubationReport - into layout.buildDirectory.dir( "documentation/incubating" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/incubating") } def stageInternalsReportTask = tasks.register( "stageInternalsReport", Copy ) { task -> @@ -112,7 +115,7 @@ def stageInternalsReportTask = tasks.register( "stageInternalsReport", Copy ) { dependsOn ':documentation:generateInternalsReport' from project( ":documentation" ).tasks.generateInternalsReport - into layout.buildDirectory.dir( "documentation/internals" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/internals") } def stageDeprecationReportTask = tasks.register( "stageDeprecationReport", Copy ) { @@ -122,7 +125,7 @@ def stageDeprecationReportTask = tasks.register( "stageDeprecationReport", Copy dependsOn ':documentation:generateDeprecationReport' from project( ":documentation" ).tasks.generateDeprecationReport - into layout.buildDirectory.dir( "documentation/deprecated" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/deprecated") } def stageLoggingReportTask = tasks.register( "stageLoggingReport", Copy ) { task -> @@ -132,7 +135,7 @@ def stageLoggingReportTask = tasks.register( "stageLoggingReport", Copy ) { task dependsOn ':documentation:renderLoggingReport' from project( ":documentation" ).tasks.renderLoggingReport - into layout.buildDirectory.dir( "documentation/logging" ) + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/logging") } def stageDialectReportTask = tasks.register( "stageDialectReport", Copy ) { task -> @@ -141,7 +144,7 @@ def stageDialectReportTask = tasks.register( "stageDialectReport", Copy ) { task dependsOn ':documentation:renderDialectReport' from project( ":documentation" ).tasks.renderDialectReport - into "${buildDir}/documentation/dialect" + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/dialect") } def stageOrmReportsTask = tasks.register( "stageOrmReports" ) { @@ -162,7 +165,7 @@ def stageJavadocsTask = tasks.register( "stageJavadocs", Copy ) { dependsOn ':documentation:javadoc' from project( ":documentation" ).tasks.javadoc - into "${buildDir}/documentation/javadocs" + into rootProject.layout.buildDirectory.dir("staging-deploy/documentation/javadocs") } /** @@ -172,7 +175,7 @@ def stageJavadocsTask = tasks.register( "stageJavadocs", Copy ) { */ def assembleDocumentationTask = tasks.register( "assembleDocumentation" ) { group 'documentation' - description 'Assembles all documentation into the {buildDir}/documentation directory' + description 'Assembles all documentation into the {buildDir}/staging-deploy/documentation directory' dependsOn ':documentation:buildDocsForPublishing' dependsOn stageJavadocsTask @@ -186,388 +189,10 @@ def assembleDocumentationTask = tasks.register( "assembleDocumentation" ) { dependsOn stageOrmReportsTask } -tasks.named( "uploadDocumentation" ) { - group = "documentation" - description = "Uploads assembled documentation to the doc server" - dependsOn assembleDocumentationTask - - doFirst { - if ( rootProject.ormVersion.isSnapshot ) { - logger.error( "Cannot perform upload of SNAPSHOT documentation" ); - throw new RuntimeException( "Cannot perform upload of SNAPSHOT documentation" ); - } - else { - logger.lifecycle( "Uploading documentation ..." ) - } - } - - doLast { - logger.lifecycle( 'Done uploading documentation' ) - } -} - -def releaseChecksTask = tasks.register( "releaseChecks" ) { - group 'Release' - description 'Checks and preparation for release' - - doFirst { - logger.lifecycle("Checking that the working tree is clean...") - String uncommittedFiles = executeGitCommand('status', '--porcelain') - if (!uncommittedFiles.isEmpty()) { - throw new GradleException( - "Cannot release because there are uncommitted or untracked files in the working tree.\n" + - "Commit or stash your changes first.\n" + - "Uncommitted files:\n " + - uncommittedFiles - ); - } - - String gitBranchLocal - String gitRemoteLocal - - if (project.hasProperty('gitBranch') && !project.property('gitBranch').isEmpty()) { - gitBranchLocal = project.property('gitBranch') - } - else { - gitBranchLocal = executeGitCommand( 'branch', '--show-current' ).trim() - } - - if (project.hasProperty('gitRemote') && !project.property('gitRemote').isEmpty()) { - gitRemoteLocal = project.property('gitRemote') - } - else { - final String remotes = executeGitCommand( 'remote', 'show' ).trim() - final List tokens = remotes.tokenize() - if ( tokens.size() != 1 ) { - throw new GradleException( "Could not determine `gitRemote` property for `releaseChecks` tasks." ) - } - gitRemoteLocal = tokens.get( 0 ) - } - - project.ext { - gitBranch = gitBranchLocal - gitRemote = gitRemoteLocal - } - - logger.lifecycle("Switching to branch '${project.gitBranch}'...") - executeGitCommand('checkout', project.gitBranch) - - logger.lifecycle("Checking that all commits are pushed...") - String diffWithUpstream = executeGitCommand('diff', '@{u}') - if (!diffWithUpstream.isEmpty()) { - throw new GradleException( - "Cannot perform `ciRelease` tasks because there are un-pushed local commits .\n" + - "Push your commits first." - ); - } - } -} - -def preVerifyReleaseTask = tasks.register( "preVerifyRelease" ) { - group 'Release' - description 'Pre-verifies a release job execution (Run locally before a CI release)' - - dependsOn tasks.clean - dependsOn assembleDocumentationTask -} - -def changeLogFileTask = tasks.register( "changeLogFile" ) { - group 'Release' - description 'Updates the changelog.txt file based on the change-log report from Jira' - dependsOn releaseChecksTask - - doFirst { - logger.lifecycle( "Appending version `${project.releaseVersion}` to changelog..." ) - ChangeLogFile.update( ormVersion.fullName ); - } -} - -def changeToReleaseVersionTask = tasks.register( "changeToReleaseVersion" ) { - group 'Release' - description 'Updates `gradle/version.properties` file to the specified release-version' - - dependsOn releaseChecksTask - - doFirst { - logger.lifecycle( "Updating version-file to release-version : `${project.releaseVersion}`" ) - updateVersionFile( project.releaseVersion ) - } -} - -def gitPreparationForReleaseTask = tasks.register( 'gitPreparationForRelease' ) { - dependsOn releaseChecksTask - dependsOn changeLogFileTask - dependsOn changeToReleaseVersionTask - - doLast { - logger.lifecycle( "Performing pre-steps Git commit : `${project.releaseVersion}`" ) - executeGitCommand( 'add', '.' ) - executeGitCommand( 'commit', '-m', "Pre-steps for release : `${project.ormVersion.fullName}`" ) - } -} - -def changeToDevelopmentVersionTask = tasks.register( 'changeToDevelopmentVersion' ) { - group 'Release' - description 'Updates `gradle/version.properties` file to the specified development-version' - - dependsOn releaseChecksTask - - doFirst { - logger.lifecycle( "Updating version-file to development-version : `${project.developmentVersion}`" ) - updateVersionFile( project.developmentVersion ) - } -} - -def releasePreparePostGitTask = tasks.register( 'gitTasksAfterRelease' ) { - dependsOn changeToDevelopmentVersionTask - - doLast { - if ( project.createTag ) { - logger.lifecycle( "Tagging release : `${project.releaseTag}`..." ) - executeGitCommand( 'tag', '-a', project.releaseTag, '-m', "Release $project.ormVersion.fullName" ) - } - - logger.lifecycle( "Performing post-steps Git commit : `${project.releaseVersion}`" ) - executeGitCommand( 'add', '.' ) - executeGitCommand( 'commit', '-m', "Post-steps for release : `${project.ormVersion.fullName}`" ) - } -} - -void updateVersionFile(String version) { - logger.lifecycle( "Updating `gradle/version.properties` version to `${version}`" ) - project.ormVersionFile.text = "hibernateVersion=${version}" -} - -def publishReleaseArtifactsTask = tasks.register( 'publishReleaseArtifacts' ) { - mustRunAfter gitPreparationForReleaseTask - - dependsOn uploadDocumentation - dependsOn uploadDocumentationDescriptor -} - -def releasePerformPostGitTask = tasks.register( 'gitTasksAfterReleasePerform' ) { - - doLast { - if ( project.createTag ) { - logger.lifecycle( "Pushing branch and tag to remote `${project.gitRemote}`..." ) - executeGitCommand( 'push', '--atomic', project.gitRemote, project.gitBranch, project.releaseTag ) - } - else { - logger.lifecycle( "Pushing branch to remote `${project.gitRemote}`..." ) - executeGitCommand( 'push', project.gitRemote, project.gitBranch ) - } - } -} - def releasePrepareTask = tasks.register( 'releasePrepare' ) { group 'Release' description 'Performs release preparations on local check-out, including updating changelog' - dependsOn gitPreparationForReleaseTask - - finalizedBy releasePreparePostGitTask -} - -def releasePerformTask = tasks.register( 'releasePerform' ) { - group 'Release' - description 'Performs a release on local check-out, including updating changelog and ' - - dependsOn publishReleaseArtifactsTask - - finalizedBy releasePerformPostGitTask -} - -def releaseTask = tasks.register( 'release' ) { - group 'Release' - description 'Performs a release on local check-out, including updating changelog and ' - - dependsOn releasePrepareTask - dependsOn releasePerformTask -} - -def ciReleaseTask = tasks.register( 'ciRelease' ) { - group 'Release' - description 'Performs a release: the hibernate version is set and the changelog.txt file updated, the changes are pushed to github, then the release is performed, tagged and the hibernate version is set to the development one.' - - dependsOn releaseTask -} - -static String executeGitCommand(Object ... subcommand){ - List command = ['git'] - Collections.addAll( command, subcommand ) - def proc = command.execute() - def code = proc.waitFor() - def stdout = inputStreamToString( proc.getInputStream() ) - def stderr = inputStreamToString( proc.getErrorStream() ) - if ( code != 0 ) { - throw new GradleException( "An error occurred while executing " + command + "\n\nstdout:\n" + stdout + "\n\nstderr:\n" + stderr ) - } - return stdout -} - -static String inputStreamToString(InputStream inputStream) { - inputStream.withCloseable { ins -> - new BufferedInputStream(ins).withCloseable { bis -> - new ByteArrayOutputStream().withCloseable { buf -> - int result = bis.read(); - while (result != -1) { - buf.write((byte) result); - result = bis.read(); - } - return buf.toString( StandardCharsets.UTF_8.name()); - } - } - } -} - -class ChangeLogFile { - - // Get the Release Notes from Jira and add them to the Hibernate changelog.txt file - static void update(String releaseVersion) { - def text = "" - File changelog = new File( "changelog.txt" ) - def newReleaseNoteBlock = getNewReleaseNoteBlock(releaseVersion) - changelog.eachLine { - line -> - if ( line.startsWith( "Note:" ) ) { - text += line + System.lineSeparator() + System.lineSeparator() + newReleaseNoteBlock - } - else { - text += line + System.lineSeparator() - } - } - changelog.text = text - } - - // Get the Release Notes from Jira - static String getNewReleaseNoteBlock(String releaseVersion) { - def restReleaseVersion; - if ( releaseVersion.endsWith( ".Final" ) ) { - restReleaseVersion = releaseVersion.replace( ".Final", "" ) - } - else { - restReleaseVersion = releaseVersion - } - def apiString = "https://hibernate.atlassian.net/rest/api/2/search/?jql=project=HHH%20AND%20fixVersion=${restReleaseVersion}%20order%20by%20issuetype%20ASC" - def apiUrl = new URL( apiString ) - def jsonReleaseNotes = new JsonSlurper().parse( apiUrl ) - def releaseDate = new Date().format( 'MMMM dd, YYYY' ) - def versionId = getVersionId( jsonReleaseNotes, restReleaseVersion ) - - ReleaseNote releaseNotes = new ReleaseNote( releaseVersion, releaseDate, versionId ) - - def issuetype - jsonReleaseNotes.issues.each { - issue -> - if ( issuetype != issue.fields.issuetype.name ) { - issuetype = issue.fields.issuetype.name - releaseNotes.addEmptyLine(); - releaseNotes.addLine( "** ${issue.fields.issuetype.name}" ) - } - releaseNotes.addLine( " * [" + issue.key + "] - " + issue.fields.summary ) - } - releaseNotes.addEmptyLine() - return releaseNotes.notes - } - - private static getVersionId(jsonReleaseNotes, String restReleaseVersion) { - def fixVersions = jsonReleaseNotes.issues.get( 0 ).fields.fixVersions - - for ( def fixVersion : fixVersions ) { - if ( fixVersion.name.equals( restReleaseVersion ) ) { - return fixVersion.id - } - } - throw new GradleException( "Unable to determine the version id of the current release." ) - } -} - -class ReleaseNote { - String notes; - String notesHeaderSeparator = "------------------------------------------------------------------------------------------------------------------------" - - ReleaseNote(String releaseVersion, String releaseDate, String versionId) { - notes = "Changes in ${releaseVersion} (${releaseDate})" + System.lineSeparator() - addHeaderSeparator() - addEmptyLine() - addLine( "https://hibernate.atlassian.net/projects/HHH/versions/${versionId}" ) - } - - void addLine(String text) { - notes += text + System.lineSeparator() - } - - void addHeaderSeparator() { - addLine( notesHeaderSeparator ) - } - - void addEmptyLine() { - notes += System.lineSeparator() - } - - void addEmptyLines(int numberOfLines) { - for ( i in 1..numberOfLines ) { - notes += System.lineSeparator() - } - } -} - - -gradle.getTaskGraph().whenReady {tg-> - - if ( ( tg.hasTask( project.tasks.releasePrepare ) || tg.hasTask( project.tasks.releasePerform ) ) - && ! project.getGradle().getStartParameter().isDryRun() ) { - String releaseVersionLocal - String developmentVersionLocal - - def console = tg.hasTask( project.tasks.release ) && !tg.hasTask( project.tasks.ciRelease ) - ? System.console() - : null - - if (project.hasProperty('releaseVersion')) { - releaseVersionLocal = project.property('releaseVersion') - } - else { - if (console) { - // prompt for `releaseVersion` - releaseVersionLocal = console.readLine('> Enter the release version: ') - } - else { - throw new GradleException( - "`release`-related tasks require the following properties: 'releaseVersion', 'developmentVersion'" - ) - } - } - - if (project.hasProperty('developmentVersion')) { - developmentVersionLocal = project.property('developmentVersion') - } - else { - if (console) { - // prompt for `developmentVersion` - developmentVersionLocal = console.readLine('> Enter the next development version: ') - } - else { - throw new GradleException( - "`release`-related tasks require the following properties: 'releaseVersion', 'developmentVersion'" - ) - } - } - - assert releaseVersionLocal != null && developmentVersionLocal != null; - - // set up information for the release-related tasks - project.ext { - releaseVersion = releaseVersionLocal; - developmentVersion = developmentVersionLocal; - createTag = !project.hasProperty('noTag') - releaseTag = project.createTag ? determineReleaseTag(releaseVersionLocal) : '' - } - } -} - -static String determineReleaseTag(String releaseVersion) { - return releaseVersion.endsWith( '.Final' ) - ? releaseVersion.replace( ".Final", "" ) - : releaseVersion; + // we want to assemble the docs here so that we catch problems early (and even during "dry run" for CI releases) + dependsOn assembleDocumentationTask } diff --git a/tooling/hibernate-gradle-plugin/hibernate-gradle-plugin.gradle b/tooling/hibernate-gradle-plugin/hibernate-gradle-plugin.gradle index 9ce28b673df5..62b5b651fe07 100644 --- a/tooling/hibernate-gradle-plugin/hibernate-gradle-plugin.gradle +++ b/tooling/hibernate-gradle-plugin/hibernate-gradle-plugin.gradle @@ -81,15 +81,6 @@ test { useJUnitPlatform() } -// Publish to the Gradle Plugin Portal -tasks.release.dependsOn tasks.publishPlugins - -// local publishing (SNAPSHOT testing) -tasks.publish.dependsOn tasks.publishPlugins - -// Make sure that the publishReleaseArtifacts task of the release module runs the release task of this sub module -tasks.getByPath( ':release:publishReleaseArtifacts' ).dependsOn tasks.release - // local publishing (SNAPSHOT testing) publishing { repositories { @@ -173,3 +164,10 @@ gradle.taskGraph.whenReady { tg -> } } } + +task releaseGradlePluginPerform { + group "release-perform" + description "An explicit task for publishing Gradle Plugins to the Plugin Portal" + + dependsOn tasks.publishPlugins +}