Andrew Thorburn wrote:
I'm struggling to come up with the best way to handle the various
versions of the various different JARs we have floating around. We've
recently transitioned to Ivy from a "SVN super-project" approach,
where everything (3rd party dependencies, internal company projects,
etc) were all in one great big project. Made things tricky, oddly
enough.
Anyway, we now have the following projects
company-core
partner-company-core_1
partner-company-core_2
product-core
client-end-product
That's not all that dissimilar to what I have here.
Where company-core is a very generic set of utility projects that can
be shared between all projects, partner-company-core_1/2 is a set of
interfaces to external companies. Some clients may use them, some
clients may not. product-core is the client-agnostic code, and the
client-end-product is all the client-specific code bundled up into a
WAR file and actually released. It may contain any or all of the other
projects.
What I'm having problems with is the versioning of the first 4
libraries. Here is my process at the moment:
1 - Make a change.
2 - Whine about lack of unit tests.
3 - Compile the code and make a JAR with Ant.
4 - Publish locally with Ivy.
5 - Make and deploy the WAR.
6 - Realize it doesn't have my updated code, grumble, clear the cache
and do it again.
7 - Test.
Rinse and repeat above steps.
The problem comes in at step 6, really. What I would like is to be
able to publish a new version of the code to my local repository, with
the same version number (and maybe a qualifier, like -dev), and not
have to clear the cache when Ivy resolves the dependencies for my WAR.
Well, that's not quite true. I'd really like to have proper unit
tests, so I don't *have* to deploy it to test it. Unfortunately,
that's not practically possible at the moment.
Given that, what am I missing? I'm sure I'm doing something in a
less-than-optimal manner (maybe I've just missed something in my ivy
settings file?), but I can't see what it is. I'd really, really
appreciate some advice here...
I think you can set your resolver checkmodified attribute for the local
repo (or ivy.resolver.default.check.modified) to true, if dependencies
in that resolver can change (e.g. the <info publication="<timestamp>"
has changed in the ivy file) without changing version. That will
hopefully fix your immediate problem.
There are some related problems with IvyDE (the Eclipse plug in), but
I'm not sure if I should be asking those on this list?
Also, the other thing I'm wondering about, is how do you folks roll
your version numbers?
For 'core' components, where the versions are quite insulated from the
end user and sales team, we use the format <subversion branch
name>-rev.<subversion revision>. The revision is not held in the source
ivy file, but is added to the delivered one (using pubrev and an ant
property set by our build server, or 'dev-SNAPSHOT' if not running on
the build server).
Some VCSes offer a similar incrementing revision number you can use to
give you a version number, though others give you a revision hash, which
can be problemmatic since it doesn't increment like a normal version does.
e.g. Once you have made a release, do you manually increment the
version number by one? Do you have a script that does it all for you?
Again, this is something I'm not really sure how to deal with.
For product releases, the build server manually increments the version.
Product releases are manually triggered builds on the server, rather
than continuous integration builds, so the numbers don't get too big.
I don't often do local multi-module builds, so haven't hit the problem
you talk of.
Should I be updating the version number every time I publish to my
local repository? That seems a little insane, and means I'll
eventually end up with a build number like 1.1.1841, which is a little
absurd, and makes them a little meaningless. Also major potential for
conflicts with other developers.
Yes, I don't think your local builds should be affecting other
developers. It's probably easiest to use a fixed version for your local
builds (e.g. dev-SNAPSHOT or similar).
Should I just roll the version number every time changes I've made to
it need to go to Test? That seems like the best idea, especially since
the WAR that goes to Test may end up being the WAR that goes to
prod...
How about having a build server that handles it via ant scripts? Hudson
looks very easy to set up, and is free, as is TeamCity Professional
edition (I use the not free Enterprise version).
On the other hand, if I *don't* roll the version number every time we
do a release to Test, then I'm going to have no idea what's in
production, as there'll be different copies of the JAR with the same
version number but different contents... Auditing nightmare!
Finally, how do you handle things like the '-dev' qualifier? Do you
create a project, start committing everything to Trunk, eventually
decide to roll a release, update the revision to remove the '-dev'
tag, commit, release, then roll the version number, add the '-dev' tag
and commit back to trunk? It just seems like an awful lot of steps to
me, and it seems like something isn't quite right...
You could keep revision information out of the source code as much as
possible, and instead impose it using ant properties set by your build
server or a non-source properties file (for local builds). The build
script can of course write a version file into the build
products/manifest so your software can query its own version.
Tom