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

Reply via email to