Creating Releases
This is a how to document for creating Apache Jackrabbit releases. It documents the current release process and needs to be updated as we move forward.
This applies to both Jackrabbit 2.x as well as Jackrabbit Oak releases. For Jackrabbit FileVault please use the specific documentation at https://jackrabbit.apache.org/filevault/howto_release.html and https://jackrabbit.apache.org/filevault-package-maven-plugin/howto_release.html respectively.
Release planning
Jackrabbit releases are created based on user demand and the availability of fixes and other requested changes. Any committer can declare their plan to cut a release by sending a “Apache Jackrabbit x.y.z release plan” message to the dev@ list. The plan should refer to Jira for the list of fixes to be included in the release and give a rough estimate of the release schedule. It's OK to revise the plan if needed. Optimally, link to the candidate release notes.
If you're not a committer, you can send a message to the mailing list asking for a new release to be made. Including the list of specific fixes you need and a short rationale of why you need the release.
Prerequisites for release managers
You need to be a Jackrabbit committer to prepare and perform a release, but anyone is welcome to help test the release candidates and comment on the release plans.
You should have a code signing key that is included in the Jackrabbit KEYS file. See Appendix A at the end of this page for more details.
You also need to tell Maven your Apache LDAP credentials needed for deploying artifacts to the Nexus server at https://repository.apache.org/. See Appendix B for the required settings.
Release management tasks
Part I: up to the release vote
-
Check the CI status of the project (Jackrabbit Jenkins)
-
Consider checking the CVE database for vulnerabilities in dependencies, using
mvn org.owasp:dependency-check-maven:9.0.9:aggregate
(first run will be slow because CVE databases are downloaded and parsed). If dependencies need action, open tickets and make sure they are marked as candidate backports where applicable. -
Make sure that an appropriate version for the release is entered in Jira (Jackrabbit Jira, Oak Jira) and that all the related issues have been resolved.
-
Create a new version in JIRA for the next release.
-
Check for issues that have been resolved but do not have “fixVersion” set - these may need to be updated before creating the release notes (Jackrabbit Jira, Oak Jira).
-
Create a
RELEASE-NOTES.txt
file in the root folder of the project to be released. If such a file already exists, update it for the release. See a previous release notes for examples of what to include. The release note report in Jira is a useful source of required information: Open the Jackrabbit Jira or Oak Jira page, click on the release, then on the “Release Notes” link on the top. Double-check that all version numbers in the updated Release Notes are accurate. If the project release has aproject.build.outputTimestamp
variable defined in the parent pom, and the release plugin in use does not yet support adjusting it upon release, do so now. When done, commit the file(s). -
Jackrabbit: If the branch is one that supports Java 8 or newer, make sure that the API docs can indeed be built with Java 8, using both
javadoc:javadoc
andjavadoc:aggregate
. If the branch supports Java 11 or newer, repeat this with Java 11. -
Make sure that the build succeeds with all Java versions it is supposed to support (trying with the earliest and latest is ok).
-
When releasing a Jackrabbit version that will be used in Oak, make sure it doesn't break Oak.
- Check by building the applicable Oak version using
mvn clean install -PintegrationTesting -Djackrabbit.version=2.x.y-SNAPSHOT
- If the update does require changes in Oak, open JIRA tickets and link them to the JIRA tickets tracking the release activity.
- Check by building the applicable Oak version using
-
If this is a stable branch, review changes to export versions which should be avoided (see OAK-6346 for context). If there are indeed changes (as in the example below), see Appendix E.
# Oak 1.8 as of November 2018 git diff jackrabbit-oak-1.8.0 | grep -i "@Version" -B 6 -@Version("1.5.0") +@Version("1.6.0")
-
On the other hand, if this is a release from trunk, carefully review all export versions and check that no change introduces new dependencies on Guava (see OAK-7182).
-
For Oak releases that support a range of Guava versions (right now 1.22), make sure the system builds and tests with the highest version in the range as well (see
guava.osgi.import
property inoak-parent/pom.xml
) - right now that is 20.0. Use-Pguava-latest
for the tests. (This step can likely be removed soon, as Oak 1.22 will stay on the old release of Guava due to compatibility issues) -
When doing “stable” release (even-numbered), check that we do not have dependencies to unstable releases. In particular, stable releases of Oak should not reference unstable Jackrabbit releases (if this is the case, a new stable Jackrabbit release might be required in order to proceed).
-
If the project (parent) POM has a
project.build.outputTimestamp
property, make sure it is set to a current timestamp (otherwise Javadoc will be generated with an incorrect copyright date). -
Build and deploy the release artifacts with Maven. See below for the exact steps.
-
Mark the version as released in Jira: Jackrabbit Jira, Oak Jira. You'll see all the defined project versions. From the settings menu, choose ‘Release’ on the version.
-
Do a sanity check that the staged repository on repository.apache.org contains all artifacts (~19 projects for Jackrabbit).
-
Close the staged repository, giving it a meaningful name, such as “Apache Jackrabbit 2.x.y RC”
-
Upload the artifacts to https://dist.apache.org/repos/dist/dev/jackrabbit/ as follows:
# TARGET - where https://dist.apache.org/repos/dist/dev/jackrabbit/ is checked out # SOURCE - where the release was built
For Jackrabbit:
cd $TARGET scp -r $SOURCE/target/checkout/target/$version $version svn add $version svn commit -m "Apache Jackrabbit $version release candidate" $version
For Oak:
cd $TARGET scp -r $SOURCE/target/checkout/target/$version oak/$version svn add oak/$version svn commit -m "Apache Jackrabbit Oak $version release candidate" oak/$version
-
Find the vote template (
./target/checkout/target/vote.txt
) generated by the Maven build and follow the instructions to verify the build yourself -
Start the vote thread by emailing the applicable mailing list (Jackrabbit, Oak)
-
Wait 72 hours (we usually allow three business days, so be careful when a weekend is ahead)
Part II: after the release vote
If the vote fails (easy case first):
- remove the tag from source control,
- drop the staged repository,
- revert the version release in Jira,
- check for JIRA issues that in the mean time have been resolved for the “next” version, and set that version to “this” version,
- and announce that the vote has failed by replying to the vote email.
Otherwise:
-
Close the vote by publishing the results, replying to the original vote mail with a subject line of “[RESULT] [VOTE] Release Apache Jackrabbit …”.
-
Copy the release candidate from dev/jackrabbit to release/jackrabbit in https://dist.apache.org/repos/dist/ (for Jackrabbit,
version
is just the version number, for Oak it is prefixed withoak/
, reflecting the directory structure) – be careful to properly set the version variable!!![ "x$version" = "x" ] || svn move -m "Apache Jackrabbit $version" \ https://dist.apache.org/repos/dist/dev/jackrabbit/$version \ https://dist.apache.org/repos/dist/release/jackrabbit/$version
-
Delete any older releases from the same branch (they're automatically archived)
-
Release the staged repository for synchronization to Maven central.
- make sure this step actually succeeded (we have seen a case where it failed and a retry was needed)
-
Close all the issues included in the release: Jackrabbit Jira or Oak Jira -> Choose the released version -> select “View in Issue Navigator”. From the issue list you have the option to bulk update all of the included issues. Just ‘Transition Issues’ from ‘Resolved’ to ‘Closed’ and you are done!
-
Update the Jackrabbit web site to point to the new release (GIT) (the date should be the day when the release was finished).
-
Jackrabbit: If the release was a Jackrabbit release used in Oak, make sure to also update the dependency (and potentially the Javadoc link) in oak-parent/pom.xml (example: OAK-4743 - the current mapping is Jackrabbit 2.22 -> Oak trunk, Jackrabbit 2.10 -> Oak 1.22)
-
Oak: If the release was an Oak release used in Jackrabbit (for jackrabbit-api), make sure to also update the dependency in jackrabbit-parent/pom.xml (example: JCR-4492 - the current mapping is Oak latest stable -> Jackrabbit trunk and 2.22)
-
Jackrabbit: consider updating the live site (https://svn.apache.org/repos/asf/jackrabbit/site/live/ - when producing the API docs, use a checkout of the actual release, specify an English locale (-Dlocale=en) and try to pick the right JDK version to minimize changes over the previously checked in docs).
-
Jackrabbit: If the release was a stable release that is used for the baseline check in trunk (right now: Jackrabbit 2.22), update trunk accordingly (example: JCR-4312)
-
Oak: check that all subprojects now have the correct version; if not, fix them (for instance, oak-doc and oak-doc-railroad-macro are not in the reactor pom and therefore not updated)
-
Send a release announcement to the applicable mailing lists once the web site and download mirrors have been synced (template generated in
./target/checkout/target/announcement.txt
– note that mirrors may need up to 12 hours!). Please note the announce mails needs to be sent from an @apache.org address. In case you are using a mailbox other than apache mailbox (such as gmail) to send mails for your apache address, make sure to send them in plain text format. (Warning: sending the announcement too early may cause it to be rejected for announce@apache.org)
Steps to build the release artifacts
The release is built using the Maven release plugin (if your platform is Windows with Cygwin, see Appendix C). See the Performing a Maven Project Release guide for more details. Make sure you have added the pgp key information in you maven settings file, especially if you have more than one key installed locally. See Appendix B for the details.
In case you don't feel comfortable to keep the passwords in the file ~/.m2/settings.xml
forever, you need to set it now temporarily.
There have been some problems with certain combinations of Java and Maven versions. A known combinations where releasing was successful is Java 7 with Maven 3.2.2. In case you get an exception “Proxy Error” in the release:perform
, see the Apache Services Status Page, however it has been reported that the status page is not always accurate. In case you get an error with respect to API incompatibilities, try with an older Maven version or enforce use of a newer release plugin, such as with mvn org.apache.maven.plugins:maven-release-plugin:2.5.3:prepare
.
Note that preparing the release requires a tagging operation in the source
repository. Make sure upfront that non-interactive commits work
(like svn commit -m 'commit message'
or git push
) without prompting for credentials, otherwise
the tagging step will fail.
- Execute mvn
release:prepare
. This will update the POM files and tag the release in svn (see Appendix F for how version numbers change). - Execute mvn
release:perform
. This will build the tagged release and deploy the artifacts to a staging repository on repository.apache.org. The non-Maven release artifacts are automatically deployed to your home directory on people.apache.org. You only need to add the keyname if you have multiple keys and the code signing keys is not your default key.
After this is done, you can remove the passwords from the file ~/.m2/settings.xml
if you don't want to keep it there.
Creating Markdown for Downloads Page
A shell script is available for generating the downloads links for the mark down source, to be run in a checkout of the release folder. Usage:
$ cd path-of-jackrabbit-releases
For Jackrabbit:
$ sh create-download-md.sh version
such as:
$ sh create-download-md.sh 2.14.4
For Oak:
$ sh create-download-md.sh oak/version
such as:
$ sh create-download-md.sh oak/1.6.6
Related Links
Appendix A: Create and add your key to the Jackrabbit KEYS file
Follow these instructions to generate your code signing key and to add it to the Jackrabbit KEYS file.
-
Generate a code signing key using your @apache.org address as the email and “CODE SIGNING KEY” as the comment. Also make sure it has been sent to a public key server.
-
The Jackrabbit KEYS file is managed in https://dist.apache.org/repos/dist/release/jackrabbit/KEYS. To modify the file, first checkout the dist directory:
svn checkout https://dist.apache.org/repos/dist/release/jackrabbit
-
See instructions on how to append your key to the file (or, as an alternative, the beginning of the KEYS file).
-
Commit the change using:
svn commit -m "Add code signing key" KEYS
-
See the changes on http://www.apache.org/dist/jackrabbit/KEYS (you may need to wait a few minutes).
You can (but don't need to) get your key linked to the Apache web of trust. Once other people have signed your key, you can update the KEYS file with the signatures you've received.
Appendix B: Maven settings
You need to change the ~/.m2/settings.xml
file as follows. PGP key id: this is the second part of your key in the KEYS file. For example, this is “F07CA77B” if the first line of your key in the KEYS file is “pub 4096R/F07CA77B 2014-07-31”. In case you are not comfortable to keep passwords and key passphrases in human readable files, you can add them just before doing the release, and remove them just after the release. Instead of using the “gpg.passphrase” tag, you can try using <gpg.executable>gpg2</gpg.executable>
(this should prompt you for the passphrase). For the ASF Maven repository passwords, you could use the Maven password encryption.
<settings>
<profiles>
<profile>
<id>apache-release</id>
<properties>
<gpg.keyname><!-- PGP key id, see above --></gpg.keyname>
<gpg.passphrase><!-- PGP key passphrase --></gpg.passphrase>
</properties>
</profile>
...
</profiles>
<servers>
<!-- To deploy a Jackrabbit snapshot -->
<server>
<id>apache.snapshots.https</id>
<username><!-- Apache LDAP user name --></username>
<password><!-- Apache LDAP password --></password>
</server>
<!-- To stage a Jackrabbit release -->
<server>
<id>apache.releases.https</id>
<username><!-- Apache LDAP user name --></username>
<password><!-- Apache LDAP password --></password>
</server>
<!-- To tag/checkout/checkin -->
<server>
<id>svn.apache.org</id>
<username><!-- Apache LDAP user name --></username>
<password><!-- Apache LDAP password --></password>
</server>
...
</servers>
</settings>
Appendix C: Cygwin
The Subversion and Git support in the release plugin assumes platform-specific path delimiters, and thus does not work properly if the “git” or “svn” executable is the Cygwin version. The easiest workaround for this problem is to install a Windows-native GIT or SVN version as well, and to modify the PATH variable for the git/mvn invocation so that it's found instead of the Cygwin variant.
Appendix D: Branching
The following notes were collected while branching Jackrabbit 2.16:
Create a JIRA ticket for branching and the subsequent releases of new the branch and trunk; example: JCR-4216.
Create the branch:
mvn release:branch -DbranchName=2.16 -DdevelopmentVersion=2.17.0-SNAPSHOT
Set the development version on the new branch:
cd path-to-branch-checkout
mvn release:update-versions -DautoVersionSubmodules=true -DdevelopmentVersion=2.16.0-SNAPSHOT
Open a ticket so that once the first release for the branch is made, the comparisonVersion
for the bundle:baseline
check is updated both in the branch and on trunk; example: JCR-4218.
Create release notes to include all of the changes accumulated - for 2.16.0 this means including all changes labeled with fixVersion
set to 2.16
. Note that any change labeled with fixVersion
set to any 2.15.* release should have fixVersion: 2.16
as well, unless the change is irrelevant for the release notes.
Appendix E: Version Changes
HERE BE DRAGONS
In general, changes in stable branches should not change export versions, in order to avoid version conflicts with the ongoing development on the unstable branch. So avoid, avoid, avoid!
If the version change really is required, then it is mandatory to check that the new API is identical with the API in other release branches with the same version number.
To check, for example for a version change in Oak 1.6.13-SNAPSHOT:
-
Checkout Oak 1.8.
-
Edit the parent pom to use a comparisonVersion of “1.6.3-SNAPSHOT”. Release branches normally use the default, so the property needs to be added to the maven bundle plugin configuration.
-
Build and watch for baseline plugin errors.
…then repeat the above steps with subsequent branches and trunk.
Also, check with the “dev” mailing list to confirm that this change is ok.
Appendix F: Version Numbers
Jackrabbit
Classic Jackrabbit uses even minor version numbers for stable releases, and uneven numbers for unstable releases. For instance, as of September 2019, the latest stable release was “2.18.3”, and the latest unstable release was “2.19.4”.
Stable releases are cut from a branch, where the branch name is based on major and minor version number (here: “2.18”). Unstable releases are built from trunk.
Creating a new major release implies creating a new branch (next would be “2.20”), see Appendix D.
For creating releases, the default version numbers proposed by mvn release:prepare
work out of the box.
Oak
Oak historically used the same scheme, and moved away from that with “1.10.0” in Spring 2019.
Rather than creating unstable releases from trunk, we now create a stable release every time. These keep the even minor numbers, so as of September 2019, the sequence of releases since the change was: “1.12.0”, “1.14.0”, “1.16.0”, and “1.18.0”.
Creating releases from branches continues to work just like for classic Jackrabbit.
However, when cutting a new stable release from trunk, the default version numbers
suggested by mvn release:prepare
need to be overridden.
For instance, when cutting “1.20.0”, the next development release will be “1.21-SNAPSHOT”, not “1.22-SNAPSHOT”. The following stable release would then be “1.22.0”.