Our strategy for managing "stable" vs. "development" branches that we used with SVN do not map well to a Git style of development. Because it is difficult to do 2-way merging between branches while ignoring certain commits, we end up with branches that contain changes that others do not.
The goal is to rework our development methodology to meet a number of goals:
- have 2 "main" branches, stable, and development
- have the ability to make known-good snapshots of those branches
- simplify creating releases
- Need to 'track' two main versions of OpenNMS: Stable and Unstable
- Need to have automated nightly and/or regular builds that contain contain approved changes so they can be tried and verified by customers and the community
- Need a way to make 'contributions' that can be approved and/or tested before making them an automatic part of the the release.
- Need a way to 'mark' something as approved that automatically moves it into the next build
- Need to have 'controls' over the "testing" build inclusion process so it is not hijacked by untested changes (Currently the pushing to 1.7 seems to have been hijacked... people do it regularly without following the typical process)
- Current strategy is 'one way' and so the 'continuing' (master/1.6-testing) branch can be missing key features because they are pushed first to the release branch.
- New strategy needs to have pushing to release but not pulling from release to 'continuing'
master - all new code goes here | +- TAG: unstable/snapshot/1.7.10/1 - These will be deleted when 1.7.10 is released | +- unstable/rc/1.7.10 | | | +- TAG: opennms-1.7.10 | +- stable/1.6 | +- TAG: stable/snapshot/1.6.10/1 | +- stable/rc/1.6.10 | +- TAG: opennms-1.6.10
Git Branch Management
To accomplish these goals, first we must rework the way we use Git. In Git, branches are incredibly cheap. As such, it is not really necessary to have parallel branches that each deal with the same set of code, one tested, and one not. Instead, it is recommended that we use a few simple naming conventions to handle "known good" builds.
Only 2 Branches: Stable and Master
First, we will have only 2 branches, stable (currently 1.6), and master. Each will contain code that is destined for a future release, either stable or unstable.
Bug fixes that could affect both stable and unstable should be committed to the stable branch, and will be merged periodically to master. Alternatively, if a change made to master is later deemed to be applicable to the stable branch, it can be cherry-picked back to stable.
Traditionally, our nightly snapshot builds are based on the "1.6" and "1.7" branches, which only contain tested changes that are hand-picked by developers. As such, they only changed rarely, and often did not get other code and bugfixes from the testing and master branches until it was almost release time. Instead of having to deal with keeping multiple branches in sync, instead we will use tags to say, "I've tested this current build, and it looks OK." The idea is to have a naming convention for tags and branches which the nightly build scripts will understand for creating nightlies.
When a developer has tested a feature or bugfix, they can create a new tag of the form "
stable/snapshot/1.6.10/1" which tells the autobuild script that that particular commit is ready for a snapshot build. Then, if a future version of the 1.6 branch is tested, another developer could create a "
stable/snapshot/1.6.10/2" which means a newer version of the code is ready for a snapshot.
One week before the targeted release date, we will create a branch for that release, in the form "
stable/rc/1.6.10". From then on, more detailed testing will commence, and no new commits will be accepted for the release unless they're tested according to our release rules:
- every change must have an associated bug
- the change must be made in the "main" applicable branch (1.x, master), and then cherry-picked back to the rc branch, direct commits to the rc branch are not allowed
If a release candidate branch is available for a given version (
stable/rc/1.6.10), it will be used by the nightly autobuild scripts instead of a snapshot tag (
Currently, automated builds are available for RPMs, the installer jar, and source tarball. This should be extended to include solaris, and debian builds as well. Additionally, the nightly build scripts should be extended to understand the snapshot/rc nomenclature described above in Git Branch Management.
What Gets Built
For a given release tree (stable, or unstable), the testing builds will always choose the highest of:
- 1.x or master branch
- snapshot/1.x.x/N tag
- rc/1.x.x branch
- opennms-1.x.x tag
Additionally, a new series of "wild west" builds will be made available, which always build the 1.x or master branch top-of-tree at the given time.
Promoting Builds (RFC)
On top of doing nightly builds, we should investigate whether it is possible to rewrite RPMs, deb packages, etc. so that an existing code build of OpenNMS can be "promoted" to an official release. This would speed up the release process immensely.
For example, if we do a nightly RPM build from the rc/1.6.10 branch, and deem it ready for release, it would be useful to be able to run a script on the built RPMs to convert a
1.6.10-0.20100217 RPM into a
1.6.10-1 RPM for official release.
This would require unpacking and repacking the RPM, removing -SNAPSHOT from the names of jars, as well as changing the
version.properties file in the webapp.
I'm not sure if this is worth looking into, since we'd need to deploy official releases anyways, but it is worth looking into, since it would take hours off of doing releases.
- Make branch of master
- Make changes
- Commit & Push to sf.net
- Add Branch to bamboo
- Repeat 2-3 as desired
- Merge to master only when code is tested and bamboo is green (Note: you can merge back to master as often as desired)
- Wild West
- check out latest stable branch and deploy to packaging repos
- check out master and deploy to packaging repos
- check out stable release tag, build and deploy to packaging
- check out unstable release tag, build and deploy to packaging
- make branch of stable or unstable
- make changes
- git commit
- git format-patch -M master
- attach to bug describing fix or enhancement