Development Process
This document serves as the touchstone for the development process that is used by the Maven project to manage branches and the trunk during the development leading up to releases.
In particular the following will be addressed:
- New features development
- Releases
- Creating a release branch
- Working on a release branch
- Creating release candidates (RCs) from a release branch
- Soak period for RCs
- How to integrate bug fixes into an RC
- Generating an official release
- How to integrate bug fixes into a release branch
- Experimental, complex bug fix, and high-risk change branches
The terminology used here is somewhat SVN specific as that is the SCM the Maven project uses. At some point we would like to generalize these strategies for all SCMs and integrate these strategies into general tools where Maven SCM can deal with the operations outlined here in an SCM independent fashion.
New development
All new development, whether new features or general improvements, should be integrated into the latest revision or the trunk. Once a new feature is implemented and integrated into the trunk it can then be decided which branches the new development should be applied to. There may be rare cases where a new development only applies to a particular branch but in general all new features go to the trunk first and disseminated from there. The important thing is that all changes go into the trunk first, then get merged into the release branch as needed, so no changes ever get dropped by mistake. Changes should be kept in sync at all times where possible and this is the responsbility of the release manager. So developers can focus on improvements in the trunk and the burden of merging will be the task of the release manager. New features or improvements should never originate from a branch
The responsibility of merging changes from the trunk to the various branches is the responsbility of the release manager for the branch in question. To be clear if you are committing changes to trunk do not merge your changes into any of the release branches.
Things to think about
I really support this approach, I think it makes the most sense of any of the strategies out there, however the downside of this approach is how it scales over time. As time goes on and the deviation between the functionalities implemented on the trunk and when they are released increases, the chances of multiple desired functionalities overlapping in some part of the code increases...eventually causing the premature partial release of some functionality. Use of something like that svnmerge.py script that uses svn properties to note what has been merged where and when will address this to some degree, but some system were we know that F(A) references X files and F(B) references Y files...and when we are looking to promote F(B) but not F(A) we can doublecheck that we are not partially promoting F(A)...since svn merges will not pull out the F(A) changes if they are in the same file as F(B).
Releases
Creating a release branch
- A release branch should be made well in advance of the release to allow for stabilzation of the release and the preparation of RCs. A release branch is a long-lived branch from which all the releases for a non-API breaking versions are made. So you would release 2.0, 2.0.1, 2.0.2 of a project from a 2.0.x branch and likewise you would release 2.1, 2.1.1, 2.1.2 from a 2.1.x branch.
- Make sure that all developers checked in their local modifications before the branch is created.
- Copy using URLs as everything will occur on the server and be faster.
To create a branch to prepare for a release us the following command:
svn copy -m "Create Maven 2.0.x branch" svn://svn.apache.org/repos/asf/maven/components/trunk svn://svn.apache.org/repos/asf/maven/components/branches/maven-2.0.x
mvn release:prepare ... mvn release:perform ...
Working on a release branch
To work on a release branch you can either checkout the branch or switch and existing working copy to the branch. It is probably easier to checkout the branch in a different directory so that you can work on the trunk and branch at the same time.
svn co svn://svn.apache.org/repos/asf/maven/components/branches/maven-2.0.x
Creating release candidates (RCs) from a release branch
RCs should be made available in succession until the community is satisfied that the RC in question is of release quality. The RC that finally makes the cut as the release should be used as it was originally built so the RCs will be named as if they were the final release. This means that we have a few technical issues to resolve:
- TODO We need a staging artifact repository where the RCs can be placed so that failed RC attempts don't pollute a release artifact repository
- TODO We need a reliable way of moving the successful RC from the staging repository to the release repository. This is an intended feature for the Repository Manager but we may need a stop-gap solution until the Repository Manager is ready for production use.
- TODO We need to ensure that the RC that gets promoted as the release is not rebuilt. At the same time we need to provide a way to identify what version a user is running (be it a RC1, RC2, etc). One solution is to use a build# so that a maven2 version is always made of both a Version + a build number. For example you would have "Maven 2.1 Build # 1353" which would be RC1 and then "Maven 2.1 Build # 1450" which would be RC2 which gets promoted as the 2.1 release.
Soak period for RCs
RCs should be circulated for no less then three days so that we can accurately determine if there are any defects present. When you are ready to release the RC create the tag and then release with the release plug-in:
svn copy -m "Tag release 2.0.3" svn://svn.apache.org/repos/asf/maven/components/branches/maven-2.0.x svn://svn.apache.org/repos/asf/maven/components/tags/maven-2.0.3-rc1
mvn release:prepare ... mvn release:perform ...
- TODO We need to figure out the process of how we tag the RCs, probably don't need to keep them. Maybe just roll over the previous one until the RC is good enough to release.
How to integrate bug fixes into an RC
If bugs are found in the RCs, then the fixes should be applied to the trunk and then it will be up to the release manager to integrate the fixes into the release branch.
- TODO Some tag in the SCM message might be useful to give a hint to the release manager, or a tool, as to which revisions need to be merged.
Generating an official release
When you are ready to create a release you need to create a tag and release with the release plug-in:
svn copy -m "Tag release 2.0.3" svn://svn.apache.org/repos/asf/maven/XXX/branches/maven-2.0.x svn://svn.apache.org/repos/asf/maven/components/tags/maven-2.0.3
mvn release:prepare ... mvn release:perform ...
How to integrate bug fixes into a release branch
If bugs are found in the release then the fixes should be applied to trunk and then it will be up to the release manager to integrate the fixes into the release branch. The only time this would no apply is when there are features in the branch that are not present in the trunk i.e. deprecated features.
- moving into a API breaking version there will be alphas, betas i.e. 2.1-alpha-1
- we need to set up multiple CI processes
- possibility of a merge file
Experimental, complex bug fix, and high-risk change branches
TODO
The use of the svnmerge script to help pick off the revisions to merge.
Useful links
http://www.asterisk.org/developers/svn-branching-merging
http://www.reactos.org/wiki/index.php/Best_practices_for_working_with_branches
http://svn.apache.org/repos/asf/httpd/httpd/trunk/VERSIONING
http://svn.collab.net/viewcvs/svn/trunk/contrib/client-side/
http://www.freebsd.org/doc/en_US.ISO8859-1/articles/releng/index.html