Release Strategy

This Release Strategy describes how uPortal versions are labeled, what kinds of builds are available, and a plan to move the project along a well defined path to deliver bug fixes, new features and enhancements in a timely fashion.

Version Numbering

uPortal versions are denoted using a triplet of integers: MAJOR.MINOR.PATCH. or, rarely, a quadruplet of integers: MAJOR.MINOR.PATCH.SECURITY. Each version represents improvements to prior releases in the form of bug fixes, enhancements and new features. The purpose of labeling versions this way is to communicate the kind of change that has happened between releases and some indication of the effort required to upgrade to a newer release. The four types of releases are:

  • SECURITY - a critical minimal change on a release to address a serious confirmed security issue. That is, 2.5.0.1 would be 2.5.0 with a minimal change to patch an exploit.
  • PATCH - a conservative incremental improvement that includes bug fixes, enhancements and new features and is absolutely backward compatible with previous PATCH releases of the same MINOR release. (i.e. 2.4.15 is a drop in replacement for 2.4.14, 2.4.13, 2.4.12, etc.)
  • MINOR - an evolutionary incremental improvement that includes all PATCH release improvements along with fixes and enhancements that could not be accommodated without breaking backward compatibility.
  • MAJOR - a revolutionary change accommodating sweeping architecture, approach, and implementation changes.

Upgrading to a SECURITY release is critical. All uPortal adopters are encouraged to stay current with the fixes in SECURITY releases.

Upgrading to a PATCH release is painless (e.g. 2.4.1 -> 2.4.2) and all uPortal adopters are encouraged to stay current with the latest PATCH release.

Upgrading to a MINOR release may cause some pain (e.g. 2.4.1 -> 2.5.0). Upgrading to a MINOR release may require some planning and migration effort. uPortal adopters are encouraged to move to the latest minor release as appropriate.

Upgrading to a MAJOR version may cause a lot of pain (e.g. 2.5.0 -> 3.0). Moving to a MAJOR version may require significant planning and migration efforts. uPortal adopters are encouraged to be no more than a MAJOR release behind the current release.

Builds

uPortal has three types of builds; Milestone (M), Release Candidate (RC) and General Availability (GA) Each type of build represents the state of a particular release;

  • Milestone represents a work in progress and typically contains a subset of features, bug fixes, issues, etc. targeted for a particular release. Periodic Milestone builds are useful to gauge the progress of a particular release and to get early feedback on new features and enhancements. (e.g. rel-2-4-1-M1, rel-2-4-1-M2, ...)
  • Release Candidate represents a build that is feature complete for a particular version. Release Candidates signal the end of introducing new features on a particular line of development and the beginning of a Quality Assurance cycle. (e.g. rel-2-5-0-RC1, rel-2-5-0-RC2, ...)
  • General Availability is "as good as it gets" for a particular version. A GA build is the output of a testing cycle that vetted a particular Release Candidate by passing all available tests and meeting all functional and non-functional requirements for particular version. (e.g. rel-2-5-0)

Maven Release Plugin

For the most part, the work of releasing, tagging, and maintaining version identifiers in uPortal is handled by the Maven Release Plugin.  Adopting this plugin, and the body of practices it embodies, offers some really compelling advantages:  (1) they were designed by a group of smart, talented, and experienced developers; (2) the tasks these practices describe are near completely automated by the plugin.

Additional Notes:

  • Version identifiers for revisions that fall between official releases are suffixed by -SNAPSHOT.  (e.g. 1.2.2-SNAPSHOT, which means "later than 1.2.1 but before 1.2.2")
  • The tip of development is the master branch in GitHub;  this branch always has the highest version number in it's pom.xml file(s) compared with other branches.
  • The Maven Release Plugin does several important things automatically when it cuts a release:
    1. Version identifiers in pom.xml file(s) are updated, usually to the next patch release.  (e.g. 1.2.2-SNAPSHOT becomes 1.2.3-SNAPSHOT)
    2. A tag is created for the release.  (e.g. 1.2.2)  This is the usual way a tag in uPortal is created;  tags by other means are very uncommon.
    3. A build using the non-SNAPSHOT sources gets pushed to oss.sonatype.org, on its way to Maven Central.
  • Developers will increment the major or minor release number at any appropriate (see above) time:  by directly editing the pom.xml file(s), or it can be done by the Maven Release Plugin.

Marching Towards a Release

If all goes well the progress of any line of development will follow a well-defined path that delivers increasing functionality and/or stability in the form of a General Availability release in a timely fashion.

There are generally two or more lines of development within any MAJOR release:  the HEAD, and a patches branch for each MINOR release already in existence. The HEAD (master branch in GitHub) is where the next highest numbered release is developed and labeled. The patches branch(s) accommodate changes that qualify for a PATCH releases, and are labeled for the next PATCH release in their line.

Each line of development may see a series of Milestone builds of increasing functionality/issue resolution marching towards a feature/issue-complete Release Candidate (RC1), which is followed by a series of RCs of increasing stability culminating in a final GA release, at which time the process begins again.

Each line of development will have a Release Engineer who is responsible for managing the release through the process, setting target dates for Release Candidates and building consensus for targetting issues for a particular version and cutting the final GA release.

Developers should only increment major or minor version numbers when there is actual work to commit for the next release (MAJOR or MINOR) that cannot or should not (see above) go into the current minor release.  This practice prevents some of the hassle, mistakes, and omissions inherent in merging commits across multiple branches.

At the point of a MAJOR or MINOR version number increment (and only then), a -patches branch should be created for the previous minor version.

Example

The current master branch is on version 1.2.3-SNAPSHOT. The developers need to commit new features for the 1.3.0 release that cannot be included in a 1.2.x release because they break existing configuration settings.

The developers should (in this order):

  1. Create a branch based on master called 1.2-patches
  2. Update the pom.xml file(s) in master to 1.3.0-SNAPSHOT