Maven versioning & repositories - How to update during build - maven

I have a project being built with maven using TFS for source control and Octopus for deployment.
At the moment, I can perform a TFS CI build, create an octopus deploy package as a zip file from the output, and use octopus to deploy to my deployment target, extract the package and install the app.
What I would like to do is increment the version of the application projects when a new build is performed (perhaps nightly).
Is the correct way to do this, to get my build server to set the new version on the project, using mvn versions:set -DnewVersion=x.y.z then to run mvn deploy to push the updated packages to the networked repository. Then to finally create my maven package from this?
I'm a bit unsure the best way to allow my build server to up issue the versions and then use those updated versions of the packages in the build.
It seems like I may have the wrong end of the stick here. Any pointers greatly appreciated.

If you had already at Maven 3.2 or better Maven 3.3+ you could have done that in a more convenient way, but if you are at Maven 3.1. you need to go
via build-helper-maven-plugin and versions-maven-plugin you can do simply via:
mvn build-helper:parse-version versions:set \
-DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}\${parsedVersion.nextIncrementalVersion} \
versions:commit
But as far as I know the versions:commit will probably not work based on support of TFS for Maven SCM....(I never tested it with TFS). But the commit step be done by something different.

Related

Jenkins - get latest artifact version from remote repository

I'm trying to create a deploy job in Jenkins. Up until now I was building my artifact via the maven install goal and then deploying it on the application server with a shell script. However, I'd now like to skip the install part and just get the artifact from my nexus repository.
I know there is the maven dependency:get which I can use to retrieve the artifact from the repository but is there any way I can make sure I'll get the latest version without passing it as a build parameter?
You have different options:
1) Use the Repository Connector Plugin. With this plugin, you get an additional "Artifact Resolver" build step, where you can download an artifact from a centrally configured (Manage Jenkins) repository to the workspace of your deploy job (with different options like renaming etc).
If you use the version LATEST, you always get the latest version. Likewise, you can use RELEASE for the latest release version or ranges like [1.0,1.1).
There are two caveats however:
In the newest version of the plugin, LATEST is broken (see https://issues.jenkins-ci.org/browse/JENKINS-20263), so you need to use version 0.8.2 for now).
You should manually fingerprint the downloaded artifact, since this is not automatically done right now.
2) Use dependency:get as suggested, but use LATEST or RELEASE as above. However, I do not think this is a really elegant solution. (if you simply use SNAPSHOTs with the same base version, follow khmarbaise's advice and simply add -U to the commandline)
3) Use the Maven Deployment Linker Plugin plugin, which is a rather elegant alternative, since you can copy artifacts from other jobs like Copy-Artifact, but they are still retrieved from your Artifact repository (thus you do not waste diskspace and time). The largest problem with that plugin is that it currently does not support authentification.

Build Maven -SNAPSHOT project in Jenkins

I believe that the answer will be really easy, but I haven't figure out how to do it.
The problem is:
I have a third-party project, which is being cloned from github, so I'm not going to change anything there, but I need this project for my work with MUnit.
The project is mule-interceptor-module and it has a version 3.4-M4-SNAPSHOT.
I created a build in Jenkins and I want to get mule-interceptor-module-3.4-M4-SNAPSHOT.jar after it, but Jenkins REMOVES -SNAPSHOT from the jar name and updates pom.xml with new version: 3.4-M4 instead of 3.4-M4-SNAPSHOT. The project, which uses this one (munit) in its dependencies has 3.4-M4-SNAPSHOT. So I need the SNAPSHOT in version.
What I tried to do:
I tried to build the same project on the server, which my Jenkins is installed on, using just mvn clean install and I got mule-interceptor-module-3.4-M4-SNAPSHOT.jar.
The question is:
How to tune Jenkins so that I could finally have SNAPSHOT build?
My job setup:
JDK: jdk 1.6.0_45
Source Code Management:
Git
Repository URL: https://github.com/mulesoft/mule-interceptor-module.git
Branch Specifier (blank for default):3.4.x
Repository browser: githubweb
URL: https://github.com/mulesoft/mule-interceptor-module/
Pre Steps:
Execute shell: git checkout 3.4.x
Build:
Root POM: pom.xml
Goals and options: clean install
Post steps:
Run regardless of build result
Build Settings:
- Publish Checkstyle analysis results
- Publish FindBugs analysis results
Jenkins Console output
Jenkins Console output wirh -X
The solution:
in Jenkins /Configuration/Build/Advanced check in Use private Maven repository
Choose Strategy: Local to the workspace
remove everything from /workspace folder by rm -R *
#Grove: thanks you a lot for the support!
I can see in the logs: Your branch is ahead of 'origin/3.4.x' by 1 commit. and Building Mule Interceptor Module 3.4-M4. Could it be that your revision has 3.4-M4 as a version in the pom?
The solution:
in Jenkins /Configuration/Build/Advanced check in Use private Maven repository
Choose Strategy: Local to the workspace
remove everything from /workspace folder by rm -R *
Why are using SNAPSHOT dependency from a 3rd party ? The standard is to use a RELEASE version, right ?
Answer Anyways the fact that using the private maven repository worked for you proves just one thing, that the negative cache in your server's maven repo was causing the problem. See this Q and A from me more than a year back, when exactly the same solution worked for me, albiet for a different problem and I marked it as the answer. Only to find a few months later that I did not go to the root cause of the problem and just found a workaorund.
To test this theory, set <updatepolicy> true <updatepolicy> and use maven -U clean install. It will have the same effect as your solution of using a private repo.

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.

Best practice wrt. `mvn install`, multi-module projects, and running one submodule

I tend to avoid using mvn install in my multi-module projects because I feel like I then don't know which exact version of a submodule is then used when building / launching other submodules (particularly when switching between branches very often).
I tend to use mvn package a lot and then mvn verify.
I'm now facing the issue in a FOSS project (a Maven archetype moreover) where I'd like to use Maven's best practices.
It's a multi-module project with a webapp submodule depending on the other modules, and what worries me is the ease of development along with mvn jetty:run (or jetty:start).
Currently, I defined 2 profiles:
prod, the default one, declares dependencies on the other submodules;
dev on the other hand does not depend on the other modules, and configures the jetty-maven-plugin by adding the other modules' output directories as extraClasspath and resourcesAsCSV.
That way, I can mvn package once and then cd webapp && mvn jetty:start -Pdev and quickly iterate, reloading the webapp without the need to even stop the server.
AFAICT, extraClasspath was added for that exact purpose (JETTY-1206).
I've been pointed at the tomcat7-maven-plugin which can resolve modules from the reactor build when using Maven 3 (and I raised an issue to bring the same to Jetty: JETTY-1517), but that hardly solve my
If I hadn't removed the dependency on the other submodules from in dev profile, I'd have had to do an mvn install first so that validating the POM doesn't fail, even if jetty:start doesn't use those dependencies afterwards.
So here's my question: is mvn install really that common? or my approach of putting the intra-reactor dependencies only in the prod profile OK?
(note that I have the exact same problem with the gwt-maven-plugin, so please don't tell me to simply switch to Tomcat; that wouldn't even work actually, details here)
The mvn install is common in particular in relationship with multi-module builds, cause it will give you the chance to run a single module from your multi-module build.
This can be achieved by using:
mvn -pl submodule LifeCycle
I just found a workaround (which seems logical as an afterthought): https://jira.codehaus.org/browse/JETTY-1517?focusedCommentId=306630&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-306630
In brief: skip the plugin by default in the parent module then re-enable it where needed.
This however only works if the plugin can be skipped (i.e. has a skip configuration) and is only used in one specific submodule, and it has to be selectively done for each plugin you need/want to run that way (in my case, jetty:run and gwt:run).
I do most of my development on my laptop. For the projects I'm currently working on, my local repository is really more of a temporary holding area. I run mvn install all the time. Putting artifacts in one's local repo is the only way I know of to share built artifacts between projects, especially if you are working on projects which are related but are not (and should not be) part of the same multi-module build.
When I'm done developing I commit changes to the shared SCM and let Jenkins build & deploy the code to the shared remote repo. Then I either blow away the changed projects in my local repository so the next build brings down the freshly built artifacts, or I run Maven with -U to force updates.
This works well for me, YMMV.

Share Maven Dependencies with team members using Mercurial

I want to share all the External Jars currently being managed by MAVEN with my other team members. I am using Mercurial as my SCM and i am trying to figure what is the easiest way to commit my entire project (include libs) to a repository so that my team members can clone and get running without severe eclipse configuration?
Maven is there in order to help you retrieving libraries. So that, all you have to do is to commit all your files including the pom.xml (.hg should contains everything in target, and other unrelevant files)
Then your project members can pull the sources and run mvn eclipse:eclipse (see eclipse & maven.
And finally import the project in Eclipse.
That was is they need sources...
If they only need the jars, you must put in your infrastructure a company repo that will handle your deployment using mvn deploy. Some information there maven repo::Intro, take special care at the wagon you could use (ftp, ...)
This way, when you're done with your devel and you have pushed your code, you just have to deploy the jar on your repo.
Doing so, your project member'll have to run mvn -U eclipse:eclipse or any goal to update their local repository with your lastest deployed version.

Resources