I have a theoritical question : I have a project that has versions, for example :
0.1 : alpha
1.0 : first release
2.0 : breaking changes
And I have a task management system (Redmine, but it's the same for trac or anything else...).
In which version do I put the task that will make the application work (currently it doesn't work) ? Is that in 0.1 (once 0.1 is finished, then 1.0 works) or is that in 1.0 (once 1.0 is finished, then 1.0 works).
Another way to ask is : Is a task of version 1.0 a task that helps making the 1.0 version, or a task that extends/fixes the fully working 1.0 version.
I am confused, because a task can
precede the release of a version (i.e. working on the release)
follow the release of a version (i.e. the release is out, we need to fix bugs and extend it)
So which tasks do I put in a version ?
I don't know how to manage tasks and versions, can you help me ! How does it works in Open Source coding ?
Thank you !
PS : please let me know if that is not clear enough
You need to separate tasks and versions in your mind before you can come back and apply them.
Tasks are work you do on your code.
Versions (and I'm lumping in all point releases here) are releases of your code.
You to work, tasks, on your code with the objective of making a release. That release, depending on the scope of the work you are doing may be a full version 1.x.x, 2.x.x, etc., or a point release 1.1.x, 1.2.x, 1.3.x or it may be a minor point release/bugfix/whatever you want to call it, 1.0.1, 1.0.2, 1.0.3.
The tasks could be bug fixes, features, changes, refactoring, whatever. In the scope of a full application development you may that your organisation bundles groups of tasks in to the work needed to make the next release or you may have releases date-bound, i.e. you'll release version 2.0.0 on 25-Feb-2011 regardless of the tasks completed (although normally there's a subset that must be complete for the release to happen).
Version releases tend to follow major updates, upgrades, feature additions.
Point releases tend to follow moderate improvements, and major bug fixing.
Minor point releases to be the result of bug fixes.
Every where you turn you will find different approaches to this process and you just need to either understand that used by your company or if you have the opportunity, to find one that makes sense to you and then apply it consistently.
Related
Ours a complex enterprise app and we use one third party library which we would like upgrade.But we do want to maintain two versions atleast for couple of releases till we are good with the newer version and switch which version to use by a configuration property.
We are trying maven shading for the same.
However the problem we are facing is like this. The changes between the two releases are very drastic. For example A is a class in version 1.0 and is now an interface in version 2.0
So let us say for example in the existing client code we say
A a = new A();
This would have to be changed to some other call in the new version.
Are there any ideas on how to make the client code compatible with both the versions?
I don't believe there is a way to write code compatible with both the versions.
Keeping multiple versions of same jar may create maintenance nightmares.
I suggest to create/maintain separate SVN branches for each version of this jar.
You can decide which SVN branch should go into production based on maturity of that branch.
You can simply replace the war from other branch, if any issue during deployment/in production.
I expect this is a common issue, but one I am not aware of a sensible solution to.
We have adopted the procedure where all local dependent modules are moved straight back to SNAPSHOT once the release has been done. Time passes and we come to do a new release.
When we come to release we need to make a decision on whether a particular module has had any changes or not. If not, we dont need to update release the dependent snapshot and we can simply build against the previous release version as nothing has changed.
The difficulty in this process is establishing whether anything has actually changed since the last release or not. The only way I can imagine establishing this is to look in the subversion logs to see if any significant change has been checked in since the last release, and if it has then we need to release the dependent module. If it hasnt, we are ok to use the previous released version. This seems very labour intensive to me.
Is there a plugin or a better way to achieve this?
There are multiple modules in our applications and each of them have their separate version and depend on other modules(external to our organization). They all have a parent POM which has it's own version, independent from the children's version.
When one of those modules change, they're converted to snapshots.
For the following example:
Parent v14.0
- module1 v1.5.0
- dependency1(module2 v15.0.0)
- dependency2(external-jar v12.0.1)
- module2 v15.0.0
- module3 v3.1.0
If there would be a change in module2, then module2's version would become v15.0-SNAPSHOT, then module1 becomes v1.5-SNAPSHOT. The parent remains the same.
The purpose for not having the same version on parent+modules, is that we want to localize the updates made to some modules and not affect the others' versions.
This has been designed like this a long time ago and there are several bash scripts to support the updates, although they're not handling all the cases. In any case, we don't have a one-click release process and we feel we are quite far from it with this approach.
We don't know how to convince the management towards a single version approach on all modules. How do you feel about the above? Did you ever encountered a project using the above structure and how well did it go?
Thank you!
I've had to deal with such situations before. There is an actual benefit from having decentralized versions, especially in cases where your product is made out of a large number of modules and this is because of the following facts:
You don't have to release all of them as a whole, if only a handful have been changed (which, from my observation is almost always the case).
You don't have to create unnecessary tags in your version control for code which hasn't changed since the previous release.
You don't have to waste an excessive amount of time releasing modules which don't need to be released.
You know with certainty which modules have changed in a release, which helps a lot when you need to investigate a complex bug, which seems to be dating back a while.
You can actually release certain modules/aggregators before the actual release date of the complete product, allowing for more testing time and a feeling of completeness for a given part of the product.
You can make feature branch releases much easier and implement a continuous delivery in a better way.
You can re-use the same code across multiple development branches without wondering if that branched version matches the one for your branch (or at least with less confusion).
What we ended up doing was:
Extract a parent or set of parents (with no sub-modules).
Try to use fixed versions for parents as much as possible. This is a bit of a caveat, as you must change all modules that inherit it, but in the end it improves the stability.
Extract each of the modules whose versions are independent of the rest to separate modules.
Extract sets of modules whose versions must always move along together into aggregators.
Create jobs in your CI server that can do releases or manually release these modules.
Use the versions-maven-plugin.
I think it's a lot more mature of a project and company's development principles to use decentralized versions and I must admit that in the beginning I was very reluctant to this approach. You might not realize or understand the benefits immediately, but with some practice and a proper setup, you will start seeing the upsides. I'm not saying there aren't caveats like... for example bumping the version of a parent, or having to know in which modules to bump the version of one of your modules.
From my experience, this module actually works better in the end, once you've become used to working with it.
From my experience: Everywhere we tried this, it eventually failed.
Although Maven supports this approach it is not advisable because of the additional effort.
I try to use the following criteria when choosing whether to use distinct projects or a multimodule structure:
If all projects have the same release cycle, I put them in a common multi module structure. In that case, I give them all the same version and release them together.
If a part of the project is used by different other projects (organizational projects), I always split them of and give them a separate lifecycle and a separate version.
If one part of my project stabilizes, I split it off, and give it a separate lifecycle (Maven refactoring)
To do it different alway results in homebrew solutions that neither scale well, nor are easy to maintain.
Hope that helps.
Let's suppose I have a project called myLib-1.1.0. This project has a dependency on lib-dependency-1.2.3.
If there's a new version for this dependency and I need to use it, should I change my project version as well? No other modifications are made to myLib.
At the same time myLib is a dependency for various other projects. My main concern is the impact of a small change in a dependency might have upstream.
Yes. In maven, released versions are immutable. If you release 1.1.0 with a dependency to lib-dependency-1.2.3 then that's it.
If you change to depend on lib-dependency-1.2.4 then that's a new version. You should not redeploy 1.1.0 since some people might have already pulled that (supposedly immutable) 1.1.0.
So that means you need a different version, even if it's a just a new qualifier (myLib-1.1.0-RC-2 for example, but better just 1.1.1)
Maven doesn't recheck remote repos for release versions once it has it in the local repo, so if someone has 1.1.0 already locally, they will not get the new, fixed 1.1.0.
And about your rippling problem. Upstream projects should depend on the lowest acceptable released version. i.e. if the upstream project itself is ok with myLib-1.1.0 because it doesn't need (indirectly) lib-dependency-1.2.4 then it should stay with 1.1.0
Any code change that potentially affects the behavior should be given a new version number, in other words: anything that's not an absolute trivial change should be given a new version number. A changed dependency would definitely qualify for that because, unless you do a thorough code inspection of the dependency, you have no reason to assume that they only made absolute trivial changes.
Changes are often advertised as "small" (similar to being absolutely trivial as I call it above), but they hardly ever are. They may be negligible in someone's use case, but not in someone else's use case. I've even seen circumstances where there were only changes to Javadocs in a project that would break things down the line. (You could argue about how smart it is for someone to depend that strongly on Javadoc, but that's besides the point, isn't it?)
That is not to say that you can't accumulate changes and release a bunch of them as a single release. While accumulating, your project is in flux, and should have a ...-SNAPSHOT version. There should be no two versions of myLib-1.1.0 (without the -SNAPSHOT) that have even the least little change.
The fact that you're re-releasing your project also makes explicit the fact that regression testing and such should be redone to validate that it's still working with the changes in its dependency.
I am looking forward to implementing a daily build for an upcoming project.
But before doing that, I need to know how to properly version an assembly.
I have the following concerns:
Should each assembly have an independent version number or should they all share the same version?
Should I use a * version for build and revision?
Is revision relevant to daily build?
We stamp all the assemblies within our products with the same version number using the following steps:
Link all assemblies to an
AssemblyInfoCommon.cs containing the
version number info: see here
for an example.
Generate the AssemblyInfoCommon.cs file as part of the build
using (in our case) the NAnt asminfo task, Cruise Control .NET and the SVN revision labeller
In our case, we don't use the * version. All deployed versions are built on the build server. We don't worry about version number on our desktops.
The answer really depends on what you are trying to accomplish with the assembly version numbers. If you are doing a ClickOnce deployment and want to do independent downloads of updated assemblies, you will need to have each assembly independently versioned -- otherwise, I think it's often nice to have assembly versions match the software release number. In more complex scenarios you may need another strategy.
A scheme I used at a prior company was major.minor.revision.build -- so in version 1.0 of the product, the assembly version and assembly file version on each assembly was 1.0.0.1129 (for example). This made it easy to match up what assemblies were part of which software release, down to the build number. We accomplished this using a pre-compilation search and replace in each AssemblyInfo.cs file to replace a token with the version numbers provided by our automated build process.
So Each assembly should have the same version which is typically a combination of the release version ie 3.4 + the build number which is a sequence that represents the number of times that release has been compiled on the build server. The revision is relevant because it demonstrates the number of builds that you have created for that release. You can really do this in one of 2 ways. The first way would be that if you planned a release ie 3.4 then when you start working on that release then that is your major version number and your minor version number increments with the build. Another way to do this is to tightly control the build versions in that when you are ready to perform your release to QA / Regression you set your major version to 3.4 and you leave your minor version number to 0. You keep things tightly controlled this way until you release. This way you can control your service pack numbering through the minor version number. Hope this helps.
I would normally agree that all assemblies should have the same version number; however, I would make one caveat to that. If one of the assemblies is used somewhere else outside of this project or if it is considered it's own project it should have it's own version number. It should also probably be moved out of that solution and into it's own. The only reason I mention this is that I have seen numerous occasions where people have an assembly that's used in a couple of other places, but mainly in one place and they try and keep the version straight. It's a bad idea to do that. I think the Single Responsibility Principle applies at the solution/project level as well.
As far as numbering goes, I agree with Guy Starbuck (major.minor.revision.build). That's the way I've always done it and it has always worked well.
We have a large app (hundreds of assemblies) with frequent releases (about 1 a month). We went for the "give every assembly the same version" but its a constant source of fustration to me that assemblies for 1 version are completely incompatible with those from another, despite the fact that the interfaces of these assmblies rarely (if ever) change.
If this is case for you then you might benefit from versioning assemblies separately - each time you update your assembly only bother to increment the version number in cases where you actually want to break assembly binding (for example if the interface changes, or the changes are otherwise significant enoigh that you want to prevent someone from accidentially using the previous version).