On 23 February 2015 at 13:45, Lennart Jörelid <lennart.jore...@gmail.com>
wrote:

> Hello all again,
>
> This is exactly my experience with large reactors; while semver would be
> the desired way to go it is impractical bordering on impossible to combine
> semver for a large number of projects. (In fact, it boils down to manually
> correctly managing all versions within a release.properties file, which is
> practially impossible for a large reactor).
>
> Thus, the only realistic option (due to the way that the release plugin
> currently
> works) is to release all the subprojects within the reactor as a whole.
> This is
> basically saying that we sacrifice semver to acquire smoother releases. We
> also sacrifice upgradeability for bugfixes in implementation projects to
> acquire
> a workable release.
>
> Conclusion: As the number of projects in a reactor grows, the maven tools
> (in particular the maven-release-plugin in its current state) are unsuitabe
> for combining an efficient release process and semver.
>

Well the question you really need to ask is different then isn't it?

First we need to consider what a release root is.

To me a release root encapsulates all the modules that are captured in a
single tag and released as a unit (never mind atomic or non-atomic deploys,
we are dealing with more ideal processes)

So when we use a release root, ideally, everything in that release root
should have the exact same version number. If you are to have different
version numbers of modules within that release root then there must have
been one of two things driving that:

1. Historically, at least one module existed independent from this release
root and was refactored into the release root. For consistency, it's
version number was not reset during the refactor

2. We may need to release some of the modules independently from the rest
of the release root... this really speaks to these modules being
incorrectly part of the release root.

The first case can be viewed as a transient problem, eventually you will
cut a major version bump to get to alignment.

The second case really speaks to a poorly formed release root. Those
modules should not actually be part of the release root.

Why is this important? Because the principle of the release root says that
everything should have the same version within the release root. Thus if
you are following semver, the semver scope is *everything in the release
root* not each individual module. So if _one_ of your modules in the
release root has a backwards breaking compatibility change, then _all_
modules are subjected to a major version bump... if you don't like that,
then you either don't like semver or you didn't construct your release root
correctly.

I can feel people itching to say that I am wrong on the above... so let me
ask you this...

Do you version the packages _within each jar_? Does each package have a
package-info.java with a doc comment saying "package version x.y.z"?

Just because you package up all three packages `com.acme.foo.api`,
`com.acme.foo.impl.bar` and `com.acme.foo.impl.manchu` into the single jar
file does not mean that I consume all three of them. I might be just
unpacking `com.acme.foo.api` with a view to writing my own implementation,
so I do not care that your `com.acme.foo.impl.bar` has had a breaking
change.

We can go further, and ask do you version each individual class file using
semver?

These are all individual components that we choose to release as a single
unit (i.e. a jar file). Thus the version number of the composite is
determined by the worst change of any single individual component.

We could look at that jar file and say... you know what, we have users that
just want the API. Let's put the API into a different jar from the IMPL.
Now we have two jar files, so we can have two version numbers... but we
still always release them in tandem, so they have the same version number...

Some time later we have a bug that needs fixing in the IMPL. The QA process
for testing a new release of the API is quite involved so nobody wants a
new version of the API when nothing has changed... that is a smell that the
API and IMPL need to be released independently, so they need to be in
separate release roots...

And now we hit the main issue. *Currently* the maven-release-plugin only
works on a single release root.

I have a ruby script that reads the root pom file and identifies all
release roots, determines which have unreleased changes, determines the
dependencies between release roots, and then releases each one in turn
(using the maven-release-plugin) updating dependency versions as it goes,
until there are no release roots with unreleased changes... (my script also
has a special flag I call `--yolo` where it doesn't ask questions and runs
the releases with `-B`)

What I want to do is port that logic into the release plugin, which would
effectively enable people to have their release roots less big and more
closely match the needs of each module.

A final point is that very large reactors probably are ill suited to
independent module versioning anyway. You end up with lots of different
components and people basically end up having dependencies for each use
case if they have a need for cross-cutting dependency selection... and if
you don't have such a need then you typically end up depending on
everything anyway.

So you have the foo-db-access and foo-comms "dependency-set" plugins which
pull in the required modules in all their multi-version glory via
transitive dependency resolution... and how do we version those
"dependency-set" plugins? If using semver, well they need to follow the
worst version change of their dependencies... foo-logging got a major
version bump... so foo-db-access and foo-comms both need a version bump...
next release foo-utils gets a major version bump, so again foo-db-access
and foo-comms need a major version bump... etc. Very soon all your regular
modules have had one version bump (you are practicing CD) and your
"dependency-set" plugins are on version 48.0.0 and 56.0.0 respectively
(because say there are 47 and 55 dependencies pulled in to each
respectively)

Now there is nothing really wrong with that... except that when it comes to
tracing user problems you need a major matrix to help you decide if there
is something wrong with the system (perhaps they have got foo-widget 3.0.4
and that was never tested with foo-gasket 5.0.3 because they were not
released as a unit)... plus the users don't care about the foo-widget and
foo-gasket version numbers because you have given them the nice handy
foo-comms "dependency-set" that is all they bother tracking... and so you
realise:

* either the release root is too big;
* I should just quit messing around and give them all the same version
number anyway.

So my conclusion is that we need not bring maven or the maven release
plugin into this discussion at all.

For releasing many individual things always as one atomic transaction,
semver is best applied to everything in the transaction as a whole. Semver
is ill-suited to versioning the individual components *if* you will always
release them atomically as a whole.

Maven, as it always does, lets you ignore this but punishes you with a
world of pain if you deviate from the best practice of giving everything in
a release root the same version number

;-)


>
>
> 2015-02-23 11:43 GMT+01:00 Martijn Dashorst <martijn.dasho...@gmail.com>:
>
> > On Sun, Feb 22, 2015 at 10:42 PM, Fred Cooke <fred.co...@gmail.com>
> wrote:
> > > I'd also love to hear that no one is trying to release 200 artifacts
> in a
> > > single reactor.
> >
> > At Wicket Stuff (https://github.com/wicketstuff) we do just that. It
> > is a pain, but
> > it is quite a lot less pain than trying to release each project by
> itself.
> >
> > > That makes no sense at all, to me. The chances are on a big
> > > corporate project you've only changed <25% of them per top level
> release
> > > anyway. So to run a top level MVN release against the entire tree would
> > > produce 75% duplicate (by code, not number) artifacts. Or did I
> > > misunderstand?
> >
> > You understand correctly, but in Wicket Stuff's particular case we assume
> > that
> > while not everything was modified, it is a much bigger benefit of having
> > all
> > version of all sub modules align, such that we can ensure that one
> > particular
> > version of Wicket works with one particular version of any Wicket Stuff
> > project.
> >
> > For a release manager it is actually hard to figure out which projects
> > should
> > be released, releases of submodules linger long etc. The benefits for the
> > community with regular, full releases are tremendous. No more trying to
> > figure
> > out which versions will work with your version of Wicket.
> >
> > Martijn
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
> > For additional commands, e-mail: dev-h...@maven.apache.org
> >
> >
>
>
> --
>
> --
> +==============================+
> | Bästa hälsningar,
> | [sw. "Best regards"]
> |
> | Lennart Jörelid
> | EAI Architect & Integrator
> |
> | jGuru Europe AB
> | Mölnlycke - Kista
> |
> | Email: l...@jguru.se
> | URL:   www.jguru.se
> | Phone
> | (skype):    jgurueurope
> | (intl):     +46 708 507 603
> | (domestic): 0708 - 507 603
> +==============================+
>

Reply via email to