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 tool 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 feature development
All new features 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 features should be applied to. There may be rare cases where a new feature 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.
- if we want to relieve the burden from people working then are we going to have a release manager assigned to do the merges. we just need to ensure that the changes get to the branches from the trunk. if we keep track of the revision markers then this should be easy to do
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
- Make sure that everyone has 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:
No Format |
---|
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 |
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.
No Format |
---|
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 should be tagged and a standard release using the release plugin should follow.
- need to sort out how they will be named, but i think they should be named rc1, rc2, etc. but this might make releasing a pita
- we also need to sort out what to do with the rc that is release quality? just rebuild, or rename somehow (i don't think we could easily do this right now)
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:
No Format |
---|
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 |
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 immediately be applied to the release branch.
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:
No Format |
---|
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 |
How to integrate bug fixes into a release branch
If bugs are found in the release, then the fixes should be applied to the trunk and then immediately be applied to 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
some things I have written (jesse) general notes on subversion, branching and tagging, dumped here at the behest of jason...cut and copy up as needed..
A little bit about subversion. Tags and branches are functionally the same, and are merely symbolic. making a branch or a tag is not earmarking the file in the repository with a little indicator like it is in cvs, it is logically a copy of the file at that particular revision. with that in mind, tagging is no longer a seperate process from merging...they are no different. The act of tagging doesn't exist. Instead you merge a given changeset from one location to another. svn maintains some amount of knowledge of the file that it was copied from, but not what given changeset was merged into it when.
Common development will take place on the trunk. Work that embody any kind of size or impacts a large array of objects should be done on a special development branch pulled by the developer/s. A note on these branches, I really don't think they should be worked out outside of a couple of weeks...the longer that people spend working on and committing on a branch and not merging that work back onto the trunk the more annoying it will get to finally do the merge. Especially in the infancy of people actually working with branching and merging....it is critical to not let development branches like this get out of hand. If something is going to take over two weeks of development I would consider breaking that development up into multiple phases which each phase being something that can be merged back to the trunk. If API's are going to change, get them changed sooner then later.
There are a number of fundamental things that we need to manage ourselves as developers.
1. my work tramples your previous work
2. my work is getting pushed up the release chain before yours
3. your in a heap of trouble if promoting your changes carries sometime along with it that it shouldn't
first off, work is getting done on the trunk, my commits for project X are getting committed as we go along as I development it on my personal development instance. I feel (or am told perhaps) that it is time to get my stuff moved to QA. Like a good developer I have maintained a list of the changesets that embody my project X, say r100, r105, r106, r109, and r140.
I checkout the release branch and begin merging the changesets from the trunk...all the change sets get shoved into my release branch instance at the same time. I now commit these change sets to the release branch and get me a new r#, say r200 for this instance. I have now aggregated the 5 commits I had made on the trunk into 1 changeset on the release branch. I edit a file called MERGE on the release branch and note that changeset number, the project, and hopefully the jira issue that relates to it. The work is then built and snapshotted and tested... perhaps I have a bugfix or 2 or 3...that get merged to the release branch and added to the MERGE file as changesets representing that Project X of work.
This approach has benefits since it really represents the aggregation of work into larger changesets to deployment. The only side effect it really has is that it doesn't solve the 'my work effects yours, but mine is going first'...but nothing so far addresses that, and if the MERGE file is consistently up to date it can be mined by an external process to protect us I believe. an external process be told what changesets are wanted to be moved from qa to staging and interrogate svn to determine if the changeset for project X masks any files from another changeset being monitored in that same file....this lets us monitor subproject dependencies programattically which would rock.
Pros:
- potential merging of changed code only between developer branches and the trunk
- merging is between trunk and release branches, never between release branch to release branch
- jira tasks for things like javadoc additions and maintanence tasks can be grep'd out of these files, piped through cut, sort and diff to automagically give you changesets to merge to a release tag using xargs
- SIMPLE! if developers keep to the process then releases should be quite simple, just a matter of applying a set of changesets
Cons:
- someone might forget to mark a changeset in the MERGE file, beatings can minimize this though
- same con as everything else, you if changeset X touchs things that changeset Y did...Y has to go forward first, or both have to go...but no system addresses that
another potential mechanism...or naming convention, kicked around a couple of weeks ago.
-SNAPSHOT development suffix for version tags.
-STABLE bugfix suffix for released versions
-RELEASE tag suffix for a released versions
so 2.0-RELEASE is a svn tag that is immutable, it is set once for a set of code, 2.0-STABLE becomes the bugfix branch for the 2.0-RELEASE...and people can track that -STABLE release for something they are assured to be solid and stable...2.1-SNAPSHOT would be development code, released periodically as per whatever rules govern development code release, as needed perhaps
Notes from Garrett Rooney (an svn committer)
<jason_> any svn users who are familiar with the fly fishing technique?
<jason_> just looking for a little advice on working with branches
<chipig> fly fishing and branches?
<rooneg> i can give advice on working with branches, but i have no clue what you mean by "fly fishing technique" in that context
<jason_> http://cvsbook.red-bean.com/cvsbook.html#Going%20Out%20On%20A%20Limb%20(How%20To%20Work%20With%20Branches%20And%20Survive)
<jason_> rooneg, do you typically work on trunk and merge into the branch periodically or right away?
<rooneg> well, it depends what kind of branch you're talking about. is it a release branch? a maintenance branch? a feature branch?
<jason_> in this case a release branch
<jason_> well, we release from this branch
<rooneg> well, for subversion itself we use a technique like this. when we're ready to start preparing for a release we branch off of the trunk.
<jason_> http://svn.apache.org/viewcvs.cgi/maven/components/branches/maven-2.0.x/
<rooneg> any last minute modifications to the branch happen there (updating change lists, version numbers, etc), then we cut a release candidate.
<rooneg> at this point trunk development continues as usual
<rooneg> there is now a soak period, where the RC is tested. if bugs are found they are fixed on the trunk and then proposed for merging back to the branch.
<rooneg> when we've got enough fixes merged in that a new RC is justified we roll a new RC off the release branch
<rooneg> (rolling an RC means tagging it as well, FWIW)
--> jesse (n=jesse@216-161-72-109.omah.qwest.net) has joined #asf
<rooneg> eventualy one of our RCs is declared final, and we roll the final release with only a version number change relative to the last RC
<rooneg> the release branch (i.e. branches/1.2.x or branches/1.3.x) sticks around and we do basically the same thing for the next release.
<rooneg> 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
<jason_> cool, that's what i wanted to hear
<jason_> thx for the advice
<jason_> what's your name btw? just so i remember
<rooneg> no problem
<rooneg> Garrett Rooney
More notes from Garrett and Paul Querna
<jason_> rooneg, do you use anything like that svnmerge.py script?
<jason_> is that a useful script, i just saw it in the svn contrib section
<rooneg> jason_: personally, no, i've never used it, but some svn developers do
<rooneg> it's really more useful for things like feature branches, where you intend to merge all changes from one branch into another.
<rooneg> so if i created a branch to work on a new feature, and i want to periodically merge the changes from trunk into it, to keep me up to date, svnmerge.py would help a lot
<rooneg> not sure how well it deals with cherry picking individual revisions though, like we do for release branches.
<jason_> are there many cases where changes would originate in a branch?
<jason_> does that ever happen much?
<chipig> not for release branches
<chipig> only if for whatever reason, the code in the release branch, doesn't exist in the trunk. IE with a depricated module.
<jason_> so from trunk to branch is the general rule, cool
<jason_> chipig: what's your name?
<rooneg> yeah, that's the general idea, it simplifies things, and ensures that you never accidentally fix a bug in an older version but not in a newer one
<rooneg> of course, development branches (like a branch to implement a particular feature) are diffeent, the whole point there is to implement some new feature, then merge it back to trunk later.
<quasi> jason_: there's this cool feature in irc clients - /whois
<jason_> well, you learn something new every day!
<jason_> well, i might guess it's mads toftum because your name has popped up on mailing lists but that result returned still isn't all that clear
<chipig> jason_: paul querna...
<jason_> chipig's came up with a full name
<quasi> jason_: correct
<jason_> cool, thanks for the advice. will go directly into maven development process doco.
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