Release Process and Baselining
In the next version of Bndtools, we want to allow people to release bundles from either their workspace or a CI server running a headless build. At the same time, we want to be able to continuously baseline the build (in your workspace or on the CI server) and report errors and warnings as early as possible.
To illustrate this, at the Bndtools Hackathon we went through an example on the whiteboard:
Let's start at the top: In the middle column, we have our local build (workspace or CI server). On the left, we have our development repository. On the right, we have our release repository.
Note: Having a development and release repository is just a conceptual model. You can implement it either by having different physical repositories or having one repository that tags its artifacts with different "phases".
We start out with a bundle A that contains some implementation code and an exported package 'a'. The bundle has a Bundle-Version 1.0.0, the exported package a also has a version 1.0.0. From here, we can release versions into the development repository (maybe done by the CI build) and we can do that as often as we want.
After a while, we might be ready for our first release. At this point, we release A 1.0.0 into our release repository. Assuming we've enabled baselining from now on, the build will baseline each bundle against the release repository:
It will take the bundle version in your workspace and look for a bundle with the highest version, but never higher than the version in your workspace. It will compare the two and:
- Look for versions of exported packages and compare them semantically. If there are discrepancies, they will be flagged as errors (or possibly warnings, depending on your configuration).
- Look for bundle versions and compare them. Again, if there are discrepancies, they will be flagged.
For more information about semantic versioning and discrepancies, scoll down.
Now let's assume we do a bugfix on an implementation class. If that's they only thing we do, our baseline algorithm will detect that the bundle contents changed but the version did not and will flag this with an error on the Bundle-Version manifest header. The same thing will happen (you will get an error message) if you try to do a headless build on the CI server.
If we then bump the bundle version, the error we had in step 3 will go away.
Now let's add a method to some interface in package 'a'. This is a minor change (+void blah() on the whiteboard image). This now means we get an error on the packageinfo file, because we did not bump its version. We also get a warning about the bundle version, because although it was bumped compared to the baseline, it should have been bumped to 1.1.0 to reflect the biggest semantic change within the bundle. This is probably just a warning because it was bumped (if we would not even have done that, we would get an error).
If we bump the packageinfo for 'a' to 1.1, our error disappears again.
Now, if we make another minor change in a different exported package 'b', we get an error on the packageinfo for 'b'. The bundle version is still fine at 1.1.0 (or producing a warning at 1.0.1). Remember, we're still baselining against A 1.0.0 in the release repository.
If we bump the packageinfo for 'b' to 1.1, our error disappears again.
In OSGi, we version both exported packages and bundles. We should explain what these semantics mean in both cases.
- Major version: a backward incompatible change, such as removing or renaming a method.
- Minor version: a backward compatible change, such as adding a method.
- Micro version: ...
- Qualifier: ...
Versions for bundles are determined by the largest change in any of the exported packages or their implementation.
- Major version: a major bump occurred in any of the exported packages.
- Minor version: a minor bump occurred in any of the exported packages.
- Micro version: an implementation change only.
- Qualifier: ...