maven-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hohl, Gerrit" <>
Subject AW: Maven and Continous Integration / Continous Delivery
Date Wed, 20 Apr 2016 10:07:50 GMT
Hello Stephen,

thank you very much for your fast and long answer.
Somehow that seems very complicated.
And unfortunately it also doesn't answer some of my questions.

Let' say we have a project A with the following POM (short version just as an example):


If I build this my CI server will produce an artifact project-a-1.0.123 (123 is the build
number) and put this into the artifact repository.

Then I have another project B with the following POM:


The resulting artifact will also something like project-b-1.0.234 (234 is the build number)
and put into the artifact repository.
But I will have the problem with the "???" at the version tag of project A. I can put there
also "1.0-SNAPSHOT" which maybe would be okay for the environment of the developer. But if
I want to build it on the CI server I have to define a unique version as I don't want that
dependencies switch automatically and builds can't be repeated.
If I put a defined version there I also need that defined version in the project A. Otherwise
I will get problems in the IDE as it maybe don't realize that project B uses the project A
which I currently have checked-out. Means if I do debugging I will always end up in the sources
of the artifact downloaded from the artifact repository and not in the source code of project
A which I also have checked-out.


-----Urspr√ľngliche Nachricht-----
Von: Stephen Connolly [] 
Gesendet: Mittwoch, 20. April 2016 11:47
An: Maven Users List
Betreff: Re: Maven and Continous Integration / Continous Delivery

If I were doing this myself here is what I would do:

I would use a MRM that has staging support and setup a Jenkins Pipeline
that starts by doing
`mvn release:prepare release:perform -B -DpushChanges=false
-DlocalCheckout=true "-DdevelopmentVersion=dev-SNAPSHOT"
"-DreleaseVersion=${BUILD_ID}" "-DpreparationGoals=clean validate"` it
should also capture the GIT repo state so that the tag and release commits
can be resurrected on a different node (because I'd be using e.g. docker
based build slaves that are ephemeral)

That will basically perform a release with the appropriate commits.

Then you do the rest of your downstream tests on the release artifacts.

If anything fails then I would drop the staging repo and nobody is any the

If it's all good and you are all set to push to production you now have a

* Do you want a human intervention or auto-deploy?

If a human intervention - put an input step in your pipeline to get
confirmation to continue

Now we need to do the deployment for real.

So we grab a node, restore the git repo and now we can push the tag
upstream, release the staging repo and push the released artifacts into

Now here are some of the tricks that we do with this approach:

   - We do not push the release commits back to the git server, we only
   push the tag (and only on a successful build that is being deployed into
   production - a tag for *every* build is not necessary, alternatively you
   could delete tags that are not needed any more and push every tag)

   This is important as there could be intervening commits in master that
   modify the pom.xml and as a result the merge may not be possible.
   - We leave the pom with a dummy -SNAPSHOT version for developers, thus
   they never have to worry about merge conflicts from master due to the
   release plugin bumping version numbers
   - We specify the release version using the build id (or some other
   component controlled by the CI server... we want something that is either a
   timestamp or a strictly increasing function)
   - We skip the preparation checks. Because nobody will ever see the
   borked tag, we only need to test once and we will throw away everything if
   something went wrong, so nobody has to worry about broken artifacts.

That is how I would handle it. Given a bit more time I could probably make
it an even nicer flow (e.g. we could push the tags always, but into a
different git repo and then we can pull those tags over to the developer
repo for promotion to deploy

On 20 April 2016 at 10:07, Hohl, Gerrit <> wrote:

> Hello everyone, :-)
> I'm currently sitting on the book "Continuous Delivery" written by Jez
> Humble and David Farley.
> They write that each build is a potential release candidate. And each
> build should be triggered by the check-in into the SCM.
> So far, so good. But how do I realize that in Maven?
> Up until now the version number in our Maven projects and modules have
> been static. If it had to be changed the developer had to perform that
> step.
> But if the CI server performs the build as well as putting the result
> into the repository (in our case Nexus), the resulting artifacts have to
> include the build number in some way. Otherwise I overwrite the same
> artifact other and other again until a developer changes the version in
> the POM file. Depending projects then will see only the last version of
> the artifact and builds won't be repeatable (means the functionality of
> the artifact changes without anyone noticing it).
> One way would be to modify the POM between the check-out from the SCM
> and the Maven build process and writing the build number into it.
> But then I will have the problem in the IDE that it don't understand
> that the current version I've checked-out is the version I have referred
> on in another project I've checked-out.
> If the CI server checks-in the changed POM file afterwards it will
> trigger the next build. Also it will cause problems if the POM was
> changed in the SCM in the meantime as the CI maybe can't merge it.
> Anyone solved that problem?
> Regards,
> Gerrit
View raw message