When is something a good candidate for the Java Common Libraries?
- If it does not (or does not have to) tie into any project specific business logic
- If it can be useful in other projects
- Code that is already being used - often duplicated - among multiple projects is a no-brainer here
- If it can be explained in such a way that other developers can understand how to use it
Care should also be taken with regards to the dependencies a module might introduce, the number of dependencies of common should be as
Useful locations
GIT repository | http://stash.foreach.be/projects/FE/repos/java-common-libraries/browse |
Bamboo | http://bamboo.projects.foreach.be/browse/FE |
Sonar | http://sonar.projects.foreach.be/dashboard/index/1863 |
Using the libraries in other projects
Avoid linking to SNAPSHOT versions. When you link to a SNAPSHOT version for a longer time, you risk of inadvertently pulling in changes because the snapshot can be updated at any point in time in the repository.
Non-snapshot versions are safe to use for a longer time.
Updating the libraries and integrating on the fly with your projects
The only time it's good to use a snapshot version is if you create a new release of the libraries in which you want to add a feature. Create a new release, build and upload snapshot, modify your project to link to the snapshot.
Always make sure you limit the time you link another project to a SNAPSHOT version. It is better to have many small releases than long-time dependencies on snapshots. However, a realase should always be stable and good quality code.
Conventions & guidelines
- Make sure to design the code for reuse: refactor the version for the common library to be specific project agnostic, modify the specific projects to use the common version
- Merge all your code to the develop branch
- A snapshot will automatically be built by the CI server - if all tests succeed
- Fix Sonar violations
- Review and minimize the Maven dependencies. Where possible, use a version range or specify the correct dependency scope.
- Update 01 - Roadmap for changes you're planning and the snapshot (development) release notes for changes you have merged to the develop branch
- Update documentation when useful
- Add high-level documentation (overview of what's available) to Confluence
- Ensure all classes are pretty much Javadoc complete, use the class-level javadoc for adding how-to's
Branching & release approach
Code can be committed on any branch, however there are some conventions to follow when creating branches:
Branch | Description |
---|---|
master | Contains the last released version. |
develop | Contains the snapshot for the next major release. |
release-* | Contains the snapshot for the an upcoming release that is not the next major (eg. next minor release) |
feature-* | Use this naming convention for developments meant to be merged to one of the upcoming release branches (including develop). |
All releases are available as tag branches of the form common-projects-X, eg common-projects-0.7.
Code can be committed on any branch except master, only authorized users can merge to the master branch.
Once code is committed on any branch, the CI server will automatically:
- build code
- run unit tests
When it is a release-* branch or the develop branch
- run Sonar analysis
- every release branch is a different project in Sonar
- deploy the snapshot to Nexus if the stage is selected in Bamboo
- upload snapshot of module/javadoc/sources to the Nexus repository
- upload the snapshot javadoc to the javadoc location
The two related Bamboo plans:
- http://bamboo.projects.foreach.be/browse/FE-CPRUT
- http://bamboo.projects.foreach.be/browse/FE-TCL
- Contains the manual "Deploy snapshot" stage to upload an artifact to Nexus
Once a new snapshot is uploaded to Nexus, other projects will pull it in. If you want to force an update of dependencies, use mvn -U.
Development workflow step-by-step
Minor versions can add or modify features, but should avoid breaking compatibility at all costs. If changes will require major refactoring in existing projects using them, you should consider developing them in the new major version. When in doubt, contact Arne Vandamme.
Case
The current released version is 0.7, the next major version being developed is 0.8-SNAPSHOT (on develop branch). I want to add a single new feature and use it in my projects as soon as possible, without having the risk of the additional unfinished features in the next major release.
Step-by-step
- Checkout common-projects-0.7 (checkout common-projects-0.7)
- Create a new branch release-0.7.1 based on that release branch (checkout -b release-0.7.1)
- Modify the pom.xml files in your new branch (replace <version>0.7</version> with <version>0.7.1-SNAPSHOT</version>)
- Commit your code on the new branch
- Push your branch to origin
- Check that Bamboo build unit tests succeed, if it does, you should see that Build snapshot runs automatically
- Check that Bamboo build snapshot for your branch succeeded, check the Sonar for your branch
- If ready, execute the Deploy snapshot stage of the last build
- When finished, modify your project to reference the new snapshot version
- Update the project dependencies, you should now have the snapshot you want
Modifying the pom.xml to the correct snapshot version you want to use is probably the single most important thing to make this work!
When your snapshot is ready to be released
- Make sure you have created a release notes page in Confluence
- Verify the Javadoc is correct and uptodate
- Launch a pull request from release-0.7.1 to master and add Arne Vandamme as reviewer
You will be notified when a new final release has been built, in which case you should switch back from using the snapshot to the specific released version.
Special cases
- If you are updating an older version, launch a pull request to develop instead or just send a mail when ready for release
- example: creating 0.6.1 while previous release was 0.7
- If there is already a 0.7.1 being developed, you should contact the owner of that branch (Confluence or see Stash commits) and decide what the best development approach is.
- You could create a separate feature branch and merge it into 0.7.1 when you need the snapshot updated (or work on 0.7.1 directly)
- You could create 0.7.2
- This would allow you to develop your single feature on your own snapshot, however, 0.7.2 could not be released before 0.7.1 as subsequent versions should always have the previous changes.
- If the latter is a problem, then it is also acceptable to turn the flow around: skip releasing 0.7.1, release 0.7.2 and later on release 0.7.1 as 0.7.3 with the changes of 0.7.1 merged in. This would simply require the poms to be changed a second time in 0.7.1.