How to split maven tasks between tasks and pipelines without running redundant maven tasks - maven

I'm trying to set up a deployment pipeline using GoCD as follows:
Compile, test and deploy to Maven repo
Check out source code from SVN
Run mvn clean compile test install
Run mvn deploy to deploy the WAR artifact to Sonatype repo
Deploy to Tomcat server
Retrieve WAR artifact from Sonatype repo
Run mvn tomcat7:redeploy to deploy it to the Tomcat instance I have running
The thing is, I can't seem to split 1.2 and 1.3 (for example) without having to rerun the whole the entire source code checkout again in 1.3. This seems redundant to me as I had already gotten it up to the package stage and should be able to just continue to run from there.
Between 1.3 and 2.2, I can see that it can retrieve the WAR artifact from Sonatype, but I can't do much with it with maven because there's just no pom.xml for me to execute the maven task with. Of course, I can just add the source code material and run the entire mvn package tomcat7:redeploy cycle again, but I'm pretty sure that's not what this was designed for initially.
I can also write a shell script and ask Go to run it to copy the WAR file to the right location, but again, I could have done everything in one maven pass and save myself some effort but that would just reduce the entire pipeline to a single box which isn't much help to help visualize the deployment pipeline.
Can I get some advice on how I should be designing this pipeline if I wanted to split a maven task flow into different Go tasks / pipelines?
Thanks
Wong

Related

Jenkins build and deploy separately

I need help in configuring a jenkins job. I am able to deploy the code using mule mvn deploy command in a single job. Now i need to build the package and use the package to deploy it to multiple environments with out building it again. Can some one help me with that. I am able to package the code using mvn package. BUt when I want to deploy the build package I am using mvn deploy command and this is compiling and building the code. Am I missing something?
Usually, you would build the project and then deploy it to one Nexus/Artifactory. If you need it in different artifact repositories, you usually proxy the original repository in the other repository.
If you really need to deploy the same file to two Nexus/Artifactory, you can add additional deployments using the goals in the deploy plugin.

What does maven clean install -U do?

I have eclipse ide with m2e plugin, maven and weblogc app server running from my local box.
I have imported someone else's multiple maven projects from bitbucket to my box. I was told that one of them is main and rest are dependencies in which I never seen anything like that before. I have always dealt with single maven project. Anyhow from the instruction, it says I have to run maven command such as "clean install -U".
In the IDE so I touched run configuration for each mvn project by setting goal as "clean install -U". By reading maven guide, I kind understand what each term means but when you combine together with a passing parameter, what does it do actually? I didn't expect a jar (web app) to be deployed to an application server but it did also.
-U forces maven to check any external dependencies (third party dependencies) that might need to be updated based on your POM files.
clean install are both basic maven lifecycle phases (https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html).
install normally would simply take the artifact that is built and put it in the local repository, i.e. a directory on the box you are building on (.m2 directory most of the time). It would not do a deployment to a server - typically the deploy phase would be used to do that.
However, developers can override and add to what maven does in the various phases, so just like in the days of ant things can easily devolve into chaos no one can understand on complex projects ;-).
sometimes in the integration-test phase, developers will tell maven to start up a container temporarily to run the web app on, so that tests can be run against it, and then that container is shut down when the integration-test phase completes.

How to configure maven multi module project and FindBugs?

I have a multi module maven project ('assembler'), and I would like to add a FindBugs phase.
The problem is that some of the projects are not able to build stand alone since have dependencies on other projects... however when I invoke mvn package from the 'assembler' project - it works fine and all inner dependencies are resolved.
The problem is that when mvn findbugs:findbugs command is executed, those inner dependencies are not resolved, and maven complains.
Searching Google, I found a way to make it work, using mvn install, but I do not like this approach since eventually this should be used in CI with Jenkins and I do not want to rely on local maven repo on the build server.
Will appreciate hearing your ideas.
Thanks.
Don't be afraid of mvn install, it is your friend. What you need is to set up a centralized Maven repository (such as Nexus or Artifactory) or rent one (such as Bintray) to which you deploy your Maven artifacts to.
Jenkins or any other decent CI engine can do the actual deploying for you, either natively or through Maven. Once deployed, other users - Jenkins included - will be able to resolve their dependencies and you will be able to run FindBugs, PMD, JaCoco, host Javadoc or pretty much anything you want.
Side-note: Don't get confused by the term deploy as most people new to Maven usually get. In context of Maven, it has absolutely nothing to with your target environment. It simply means that an artifact is pushed out to a remote repository and nothing else.

Maven deploy multi module project only if all modules build successfully

I have a maven multi module project with several modules. I want to deploy them (mvn deploy) only if they all pass a full mvn install (which includes the tests).
Currently, I run a mvn install on the project. If all modules pass, I run mvn deploy to do the deployment. The problem I see is the waste of time calling mvn twice (even if I skip tests on the second run).
Does anyone have an idea on this?
EDIT: I have learned that using Artifactory as a repository manager and the maven-artifactory-plugin with your maven setup will add the atomic deploy behaviour to the mvn deploy command. See the Build Integration section in the Artifactory documentation.
[DISCLOSURE - I'm associated with JFrog. Artifactory creator.]
Take a look at the deployAtEnd parameter of Maven Deployment plugin: http://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html
This is a bit tricky. Maven is not atomic when it executes the build life-cycle. So a broken set of artifacts may end up in a repository.
One solution I know is Nexus Pro: http://www.sonatype.com/Products/Nexus-Professional/Features - it allows you to promote builds or define certain repos as staging. So only verified versions get promoted to be used. Maybe artifactory has something similar - I just don't know.
If that solution is too expensive you probably need to create a cleanup build or profile to remove artifacts that where already uploaded. My first guess would be to write a Maven plugin to use the the proxy remote API or maybe the maven features are already sufficient. But since deploy means update the meta-data xml files too I dont think there is a delete - not sure on this either.

Continuous integration server beginner

I'm trying to setup a complete CI server, but I struggle on some points.
Currently, my system work as follow :
I commit local changes on my local GIT repository, then push to the GIT repository on the CI server
I then have a jenkins job triggered by the SCM change, who run a clean install and by doing so executes all my Junit and Jstestdriver test (via a local jstd server). This job deploy the snapshot artifact to a repository on my nexus repository
I installed M2-release-plugin for jenkins, and setup my pom.xml accordingly using maven-release-plugin. When i click on "Perform maven release" in jenkins job page, jenkins run mvn release:prepare release:perform, thus creating a tag in my git repo (say v000001) and deploying a versionned artifact on my nexus repository.
I don't really know if this process is fine, but i guess so...
My problem is that I want to deliver the versionned artifact in my nexus repo (say "artifact-v0000001.war") in my production tomcat. But I can't figure out how to do it.
When I do "mvn release:prepare release:perform tomcat:deploy" it deploys the new SNAPSHOT artifact built ... I don't want to do this, I want to reuse the artifact from the nexus repository.
Is there a way to doing this using a tool (maven/jenkins plugin, or external)?
Basically, I want to fetch the last release artifact on the repository, and send it to the tomcat manager for dereploying the webapp.
Do I need to setup a delivery job separated from the release job?
Jenkins, especially when combined with a tool like ANT, can do just about anything. It has a lot of plug-ins, and you can always write a script and incorporate it into a Jenkins build. Currently, I use Jenkins to deploy web applications to Windows IIS servers. What you could do here is have a Jenkins build that has your SVN path set in the source control section so that it fetches the latest version when you trigger the build. From there it should be fairly trivial to write an ANT script that copies it over the existing JAR in Tomcat, which will automatically restart it.
Your problem is that you are probably using the Jenkins release plugin, not the "m2 release plugin". The problem with the standard plugin is that it performs the regular build, saves the artifacts, then performs the release. It will then try to deploy the wrong artifacts that it created from the regular build.
The m2 release plugin solves this particular problem. There are some tricky workaround for this problem, but that's how it stands at the moment until this feature is implemented: https://issues.jenkins-ci.org/browse/JENKINS-11120 (log in and vote for it!)

Resources