2012/3/8  <[email protected]>:
>
> users Digest of: get.126118
>
> Re: Is it possible to tie current git branch to project version?
>        126118 by: Seth Call
>
> Bad smell eh?  Ok, here's my bad smell.  Version numbers.  Stinkier?
> Version *numbers* in source code.  More stinky than that? Version numbers
> in source code for projects that are never released to the public.

Hi Seth,

I think you hit the nail in the head when you questioned the semantics
of artifact versions yesterday.
I was researching this same problem and it came as a nice surprise to
see that your suggestion of
tying versions with branch names is exactly the one I was coming to.

I’d like to go a little bit further in your proposal and see what you
think. (I may be missing something
trivial because I’m not a Java programmer, but I do support a few
dozens of them by maintaining
their tool chain: Subversion, JIRA, Jenkins, Sonar, Maven, Nexus, etc.
Please, bear with me.)

The proposal would be along these lines:

* The POM artifact version tag could be specified something like this:
<version>${scm.version}</version>

* There should be a maven plugin that could derive the artifact
version from the SCM in the following way:

** If there is a tag associated with the current revision and it
complies with a specific syntax
(which would default to something like /^v(\d+\.\d+\.\d+)$/, but which
could be redefined by configuration)
then the ${scm.version} property would be taken from the tag name as
the group inside the parenthesis.
(E.g., if the tag is “v1.1.2” the version would be “1.1.2”.)

** Otherwise, the ${scm.version} property would be the current branch
name suffixed with “-SNAPSHOT”.
(E.g., “master-SNAPSHOT”.)

What benefits this would bring? Mainly, you would not need to ever
edit artifact version numbers again.

As it is now, when you create a release branch you have to edit the
POMs in the branch (to strip the
-SNAPSHOT suffix) and also edit the POMs in the trunk/master (to bump
the version number) in order
to differentiate versions and avoid the risk of collisions in
deployment. This can be made easier by the
Maven Release Plugin, but the amount of work it does to make all this
editing is a bad smell to me.

Feature branches are even worse. (I suspect that this is one of the
reasons why feature branches are
despised by some people
[http://martinfowler.com/bliki/FeatureBranch.html]. But they are wrong
[http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/],
and I digress.)
Since it’s not for a release it doesn’t make much sense to change
version “numbers” in any POM.
However, you’re forced to come up with an artificial new version in
the POMs either in the branch
or in master so that you don’t run the risk of collisions in
deployment. Being forced to make-up
versions are another bad smell to me.

Moreover, since feature branches are frequently rebased with master,
whenever master changes
versions they are carried over in the next rebase and you have to be
very careful to manually accept,
reject or fix conflicts in the merge. Of course, when the branch is
ready for the reintegration merge to
master, this will happen again, only more so because reintegration
merges done wrong have bigger
implications.

Now, with this new scheme in place you don’t have to bother anymore
with version editing, because
all versions are automatically derived from the SCM context, which is
the authoritative place where
you manage your product versions anyway.

I had one minor epiphany too while thinking about this. There are good
reasons to use the semantic
versioning scheme [http://semver.org/] for released code. One of them
is that you need to be able to
order versions sequentially. In particular, you need it to be able to
specify dependencies from version
ranges. However, as you pointed out, branches are “development
versions”. And these development
versions don’t need to be ordered, just uniquely identified. For
instance, when I create a feature branch
it doesn’t matter what was the most recent released version number nor
how many releases will be cut
until the branch it is reintegrated. All that matters is that this
branch is developing a unique version which
is different from all other branches and releases. Usually, I want to
use the latest artifact built from it,
i.e., its SNAPSHOT.

Now, the drawbacks... and some doubts.

I understand that currently no such plugin can be implemented for
maven due to a restriction on the
expansion of variables in the version tag. However, since it’s
possible to specify a version in the
command line, it’s at least feasible to try the scheme to see how it
works. I did it in a small example
and it worked fine as far as I could tell. I was able to install the
artifact by calling maven with the
option “-Dscm.version=branch-SNAPSHOT” and it installed it correctly.

Also, I’m not sure about the consequences of not using the maven
standard versioning scheme
[http://www.sonatype.com/books/mvnref-book/reference/pom-relationships-sect-pom-syntax.html]
while deploying MRMs, like Nexus. In my small test I was able to
deploy the branch-SNAPSHOT
version successfully. Can you foresee any problem?

Inferring branch and tag names from a Subversion working copy
necessarily involves adherence to
conversions (/trunk, /tags, /branches). But in Git or Mercurial it is trivial.


It’s interesting to notice that this scheme is not completely new. In
the Perl development community,
Dist::Zilla [http://dzil.org/] is a tool performing similar
functionality as Maven does for Java. One of the
things it does quite well is to manage package version numbers automatically
[http://dzil.org/tutorial/versioning.html]. As far as I know it does
not have the equivalent of versioning
by branch name. But it has an equivalent of the Maven Release Plugin
that can infer the release
version number from the tags it finds in the SCM. It works
particularly well with the ::Git::NextVersion
plugin 
[http://search.cpan.org/dist/Dist-Zilla-Plugin-Git/lib/Dist/Zilla/Plugin/Git/NextVersion.pm].

So, what do you think?

Gustavo.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to