We want to restrict stable branches to a narrow range of allowed versions of all dependencies, to increase our chances of avoiding breaking changes in the stable branches.
This means rather than always rolling all library releases forward to the most current release, we want to start using stable releases for libraries more consistently.
We also want to express the dependency range in a way that does not require that we explicitly modify the allowed version when we produce patch releases. So we want to place a cap on the upper bound of the version range, rather than pinning to a specific version.
The Oslo team has been considering this problem for a while, but we now have more teams producing libraries, either server-support libraries or clients, so we need to bring the plan to a wider audience and apply a consistent set of procedures to all OpenStack libraries, including Oslo, project-specific clients, the SDK, middleware, and any other projects that are installed as subcomponents of the rest of OpenStack. (The applications follow a stable branch process already, so this process describes how to handle stable branches for projects that are not applications.)
All libraries should already be using the pbr version of SemVer for version numbering. This lets us express a dependency within the range of major.minor, and allow any patch release to meet the requirement. This spec discusses the process for ensuring that we have valid stable branches to work from.
When we reach the feature freeze at the end of the cycle, libraries should freeze development a little before the application freeze date (Oslo freezes 1 week prior, which should be enough time for all projects to follow these procedures). At that point, the release manager for each library should follow the steps below, substituting the release series name (for example, “kilo”) for $SERIES.
Update the global requirements list to make the current version of the library the minimum supported version, and express the requirement using the “compatible version” operator (~=) to allow for future patch releases (see the Compatible Releases section of PEP 440).
To avoid churn in the applications, we probably want to do this in one, or at least just a very few, patches, so we will need to coordinate between the release managers to get that set up.
Create a stable/$SERIES branch in each library from the same commit that was tagged, to provide a place to back-port changes for the stable branch.
The release team for each project will be responsible for this step, so we will want to automate it as much as possible.
The rest of the requirements management for the release is largely unchanged, with one final step added:
New stable releases of the library can then proceed as before, tagging new patch releases in the stable branch instead of master. Stable releases of libraries are expected to be exceptions, to support security or serious bug fixes. Trivial bug fixes will not necessarily be back-ported. As with applications stable releases of libraries should not include new features and should have a high level of backwards-compatibility.
The global requirements updates for our own libraries should be merged into the applications requirements list before their RC1 is produced to ensure that we don’t have any releases with conflicting requirements.
The next release on master for each library should use a new minimum version number to move it out of the stable release series. We will have cut the stable branch at that point, so bug fixes will have to be a back-ported anyway. Historically feature patches that didn’t make it before the freeze have merged early in the next cycle. Taking both of those factors together means it will just be simpler to always cut a release with a new minor version to avoid any issues with later back-ports or with accidentally including features in the release going to the new stable branch.
Management of the stable branches is left up to the projects to decide, but it should not be assumed that the stable maintenance team will directly handle all back-ports.
We could follow the two-step process the applications use and create a proposed/$SERIES branch before the final stable branch. However, the library code bases are smaller and tend to have fewer changes in flight at any one time than the applications, so this would be extra overhead in the process. We haven’t found many cases in the past where we need to back-port changes from master to the stable branches, so it shouldn’t be a large amount of work to do that as needed.
The branches for libraries are also created after a release, and so they are not a “proposed” release.
As mentioned above, we waited to create stable branches for some of the Oslo libraries until they were needed. This introduced extra time into the process because a back-port patch couldn’t be submitted for review until the branch existed.
We could also create branches like stable/1.2 or using some other prefix. However, this makes it more difficult to set up the test jobs using regexes against the branch names, and especially the job that tests proposed changes to stable branches of libraries will be more difficult to configure properly. Using the release name as the branch name lets all of this work “automatically” using our existing tools.
This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode