maven-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Robert Patrick <robert.patr...@oracle.com>
Subject RE: AW: Maven and Continous Integration / Continous Delivery
Date Wed, 20 Apr 2016 13:05:44 GMT
SNAPSHOTs work fine within a project, having SNAPSHOT dependencies across projects is tricky
and probably best avoided.  If the two projects are truly worthy of their own independent
project, then the cross-project dependencies should probably not be using SNAPSHOT dependencies.
 If you follow this rule, the problem is much simpler...

In my current project, we have a similar situation where have branched another team's code
that we are enhancing (project B) and our project (Project A) is relying on it.  We do use
a SNAPSHOT dependency on Project B in our Project A SNAPSHOT versioned POMs but when we switch
to a non-SNAPSHOT version during a release process (which we do frequently), we release Project
B, update Project A's dependency on Project B to the new version, release Project A, and then
revert to a SNAPSHOT dependency on Project B in the new Project A SNAPSHOT.  

It is more complex than I would like but it is working reliably.  We allow the Maven Release
plugin to tag and push changes to Git during the release process so that we can have repeatable
builds for the releases...

-----Original Message-----
From: Hohl, Gerrit [mailto:g.hohl@aurenz.de] 
Sent: Wednesday, April 20, 2016 7:54 AM
To: Maven Users List
Subject: AW: Maven and Continous Integration / Continous Delivery

Hello,

thanks Robert, thanks Stephen and thanks Irfan for your replies.

Somehow it seems no easy to handle this.
And it also seems to break the principals of that book in one point or another (strict dependencies,
not checking in into the SCM during the process, etc.).
That makes me wondering how these two guys - Jez Humble and David Farley - implemented CI/CD
with Maven in their projects.

In our context we currently have multi-module projects, but want to split them as we want
to reuse our components more than we did in the past. 

Regards,
Gerrit


-----Urspr√ľngliche Nachricht-----
Von: Robert Patrick [mailto:robert.patrick@oracle.com]
Gesendet: Mittwoch, 20. April 2016 14:24
An: Maven Users List
Betreff: Re: Maven and Continous Integration / Continous Delivery

While having the developers update the POM may sound ok, it turns out to be problematic in
practice when there are more than a handful of developers.  In a previously life, we had an
elaborate scheme where we had scripts that the developer had to run to update the POM and
dependency version numbers before committing any change.  We had Git hooks that would fail
a checkin if it didn't include the updates.  It was a nightmare and developers hated it. 
They have since switched to SNAPSHOTs and let Jenkins do the conversion to a non-SNAPSHOT
versions, as Stephen is suggesting.  This made the Jenkins job more complex but simplified
the developers lives and made them more productive.

> On Apr 20, 2016, at 7:14 AM, Stephen Connolly <stephen.alan.connolly@gmail.com>
wrote:
> 
> Well if you have a true CD deployment and keep strictly to not 
> breaking backwards compatibility then you can use version ranges for 
> upstream dependencies...
> 
> if that is setting alarm bells off then developers will need to either 
> have Jenkins update their poms for them or will have to view updating 
> the pom as a task they need to run...
> 
> For most cases you will have a multi-module app that is released from 
> a single reactor, so the process I outlined is not so complex
> 
>> On 20 April 2016 at 11:07, Hohl, Gerrit <g.hohl@aurenz.de> wrote:
>> 
>> 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):
>> 
>> <project>
>>        <groupId>com.company</groupId>
>>        <artificateId>project-a</artificateId>
>>        <version>1.0-SNAPSHOT</version>
>>        <packaging>pom</packaging>
>> </project>
>> 
>> 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:
>> 
>> <project>
>>        <groupId>com.company</groupId>
>>        <artificateId>project-b</artificateId>
>>        <version>1.0-SNAPSHOT</version>
>>        <packaging>pom</packaging>
>>        <dependencyManagement>
>>                <dependencies>
>>                        <groupId>com.company</groupId>
>>                        <artificateId>project-a</artificateId>
>>                        <version>???</version>
>>                </dependencies>
>>        </dependencyManagement>
>>        <dependencies>
>>                <dependency>
>>                        <groupId>com.company</groupId>
>>                        <artificateId>project-a</artificateId>
>>                </dependency>
>>        </dependencies>
>> </project>
>> 
>> 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.
>> 
>> Regards,
>> Gerrit
>> 
>> -----Urspr√ľngliche Nachricht-----
>> Von: Stephen Connolly [mailto:stephen.alan.connolly@gmail.com]
>> 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 wiser
>> 
>> If it's all good and you are all set to push to production you now 
>> have a
>> choice:
>> 
>> * 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 production.
>> 
>> 
>> 
>> 
>> 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 <g.hohl@aurenz.de> 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
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org

?
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Mime
View raw message