Version 51

    Release process for Hibernate (Gradle based)

     

    First, a list of resources you will need access to in order to perform a release:

    1. JBoss Nexus - only supports username/password uploads (boo!).  We have developed an "auth" plugin for Gradle however that leverages the Maven settings.xml file for reading username/password info.  Be sure to use the "id" of jboss-snapshots-repository (for SNAPSHOT) and jboss-releases-repository.
    2. JBoss doc server - SSH key.  See List of resources a dev team member needs access to
    3. SourceForge - SSH key.  There is a great wiki on SourceForge covering setting up your SSH key ( https://sourceforge.net/p/forge/documentation/SSH/ ).  You must also be added to the admin group of the Hibernate SourceForge project.
    4. Bintray (5.3+) - Uses an "api key".  Both the username (PERSONAL_BINTRAY_USER) and the api key (PERSONAL_BINTRAY_API_KEY) are needed - add them to ~/.gradle/gradle.properties.  To find your api key, go to Bintray.com > Edit Profile > API Key.
    5. Post permissions for both hibernate-dev and hibernate-announce mailing lists.  Again, see List of resources a dev team member needs access to
    6. Post permissions for both G+ and Twitter
    7. Realistically release builds can only be run on *Nix systems.  We rely on system commands for parts of the release tasks in the build script.  Specifically we use `rsync` and `ln` (for symlink creation).

     

    4.3+

    Starting in 4.3 we have added a dedicated release task that does a lot of what used to be manual processes in doing a release.  We still prefer the steps of preparing and tagging to be manual, but most other steps are scripted now:

    1. mark version released in jira
    2. bulk close all of the version's jira tickets
    3. get changelog from jira and add to changelog.txt
    4. change version (ext.hibernateTargetVersion) in build.gradle (or gradle/base-information.gradle in 5.3+) to the release version (ie: 4.3.x.Final)
    5. commit (don't push, because pushing will cause CI to upload another staging repository)
    6. Do the release
      1. prior to 5.3 - execute `./gradlew cleanAndRelease` from the project root (subsequent attempts can use `gradle release` depending on where previous attempt failed)
      2. 5.3+ - just `./gradlew release`.  This relies more on Gradle's UP-TO-DATE checks. (Note gsmet: I usually do `./gradlew clean release` to be sure - it takes a very long time, especially the bintrayPublish task can be stalled for ~30-40 minutes)
    7. "finalize" the release
      1. prior to 5.3 - log on to nexus and close + release staging repo.  See http://community.jboss.org/wiki/JBossProjectReleaseProcess
      2. make sure that the auto sync to Central from BinTray happened.  If not, manually sync (Note gsmet: it doesn't sync automatically so you have to go to the BinTray UI, click on the release number in the recent changes, go to the Maven Central tab and sync it manually - you can check the checkbox to close the repository)
    8. Create tag
    9. change version in build.gradle (or gradle/base-information.gradle for 5.3+) to next development version (ie: 4.3.x-SNAPSHOT)
    10. commit & push
    11. push tag
    12. announce (to be scripted eventually as well)
      1. blog about release on in.relation.to (see How to build and blog on in.relation.to)
      2. send email to hibernate-dev and hibernate-announce
      3. twitter
      4. google+
      5. add sticky (pinned/closed) announcement in ORM Forum
    13. Update the website ("production" branch")
      1. If this is the first release in a new family/series, some additional steps are required
        1. Add a directory _data/projects/orm/releases/${series_name} and in this directory add a file named series.yml - easiest to copy and edit a series.yml from a previous series.  E.g. for 4.3.0.Final you'd be adding _data/projects/orm/releases/4.3/series.yml
        2. Add a directory orm/releases/${series_name} and in that directory add a file named index.adoc - again its easiest to simply copy and edit a previous series' index.adoc from a previous series.  E.g. for 4.3.0.Final you'd be adding orm/releases/4.3/index.adoc
        3. Add a directory orm/documentation/${series_name} and add a file named index.adoc - again its easiest to simply copy and edit a previous series' index.adoc from a previous series.  E.g. for 4.3.0.Final you'd be adding orm/documentation/4.3/index.adoc
        4. If this new series is to support a new JPA release, also be sure to update orm/releases/index.adoc
      2. In _data/projects/orm/releases/${series_name} add a yml file for the specific release.  E.g. for 4.3.0.Final you'd add _data/projects/orm/releases/4.3/4.3.0.Final.yml

     

    4.2<=

    Follow these steps for a release:

    1. mark version released in jira

    2. bulk close all of the version's jira tickets
    3. get changelog from jira and add to changelog.txt

    4. change version in build.gradle (in the subproject section) to the release version (ie: 4.2.x.Final)

    5. commit & push

    6. ./gradlew clean test
    7. ./gradlew uploadArchives :release:buildReleaseBundles (USE JDK 6!  IIRC, there are quirks that affect formatting with 4.2's docs on JDK 7.)
    8. log on to nexus and close + release staging repo.  See http://community.jboss.org/wiki/JBossProjectReleaseProcess
    9. Create tag (e.g., git tag 4.2.20.Final)
    10. Push tag (e.g., git push origin 4.2.20.Final)
    11. change version in build.gradle to next development version (ie: 4.2.x-SNAPSHOT)

    12. commit & push

    13. upload bundles to SF (to be found in release/target/hibernate-release-<version>.[zip|tgz]).  See SourceForge SFTP page

    14. Upload documentation if needed.  See below

    15. announce
      1. blog about release on in.relation.to (How to build and blog on in.relation.to)
      2. send email to hibernate-dev and hibernate-announce
      3. twitter
      4. google+
      5. update sticky announcement in Hibernate Community • View forum - Hibernate User
    16. Update the website ("production" branch")
      1. cd hibernate.org/_data/projects/orm/releases/<branch>
      2. mv [previous version].md [new version].md
      3. edit [new version].md, commit, push

     


    Uploading Documentation

     

     

    Project documentation is hosted on the JBoss doc server at http://docs.jboss.org/hibernate.  Under there the path is {project}/{version}.  Generally, {version} is just limited to major.minor (4.0 or 4.1, for example).  For the Hibernate ORM project, the {project} path is orm.

     

    The main approach to uploading docs is through rsync (rsync requires key-based access to the doc server; obviously that access is limited).  The first step we need to perform is to consolidate documentation into a directory structure as we want it to look on the server.  For ORM, this means grabbing the output from:

    1. {projectRoot}/release/target/documentation/javadoc - contains the aggregated project javadocs
    2. {projectRoot}/documentation/target/docbook/publish/* - contains the built DocBook documentation

     

    The easiest thing is to just copy the contents of {projectRoot}/documentation/target/docbook/publish/ to {projectRoot}/release/target/documentation:

     

    cd $PROJECT_ROOT/release/target/documentation
    cp -R ../../../documentation/target/docbook/publish/* .
    
    
    
    
    
    
    

     

    And then rsync from this consolidated directory.  For example, assuming we are doing the 4.2 documentation:

     

    rsync -rv --links --protocol=28 ./* hibernate@filemgmt.jboss.org:/docs_htdocs/hibernate/orm/4.2
    
    
    
    
    
    
    

     

    Couple of notes about the above rsync command:

    1. -v specifies verbose, which is really quite verbose   Dismiss that option if you wish
    2. The protocol is required.  The doc server runs an older version of RHEL and that is the version of rsynch supported there.
    3. In this example we did not set up any symbolic links, so --links is completely unnecessary here.  Shown just for illustrative purposes, since we often do use symlinks.

     

    Eventually this step will become part of the build script itself for release...

     


    Why Release and then Tag?

     

    A common question about this process is why we do the release and then tag.  It is true that tagging first does alleviate the concern over of someone else pushing changes in the middle of this process.  The main reason this process was chosen was to help with failures or problems during the release build/process.  If we tagged and pushed that tag first, and then a problem happened with the release there is an extra step needed to re-attempt the release.  Namely we would need to make sure, again, that noone pushed changed in the intervening period since the last tag; then we could  retag and then restart the release process.  Not to mention that you now have the question of whether to force re-tagging using the same tag name (which requires a forced push) or re-tagging with a completely new tag name.

     

    Really its a matter of choice between how often you expect people to be pushing to the branch you are releasing from versus how often you expect problems to occur with the release process.  In my experience, problems executing the release process actually happen more often.  Specifically I am talking about problems that require changes to the code to rectify; for example, failing validations in the JBoss Nexus repo on upload, mis-versioning the release, etc.  All of these require changes to the project source to rectify.

     

    Another option that I perform sometimes if I expect the release to take a long time (major releases, for example, where I really want to spend a lot of time validating stuff) is to release using a special "release branch".  This is different than the long-lived back-port branches.  This is a branch whose sole purpose is to be the base of a release.  This was the purpose of the 'stable' branch.  Essentially I would start a release by making stable look exactly like the current master (assuming I am releasing from master).  Then I would start the release from there.  If anything needed to change (to fix JBoss Nexus validation issues, etc) I would fix those on stable and push (eventually those changes would get moved to master as well).  Finally I would tag from stable.  Like I said, I do this pretty infrequently.  More often I just do the release.  Sometimes I just send a quick note to the dev mailing list asking folks not to push for a bit.  But with or without asking I have never  had someone push changes while I am working on a release.  Knock on wood

     


    See also