Remove SNAPSHOT suffix from Jenkins build - maven

I recently upgraded from hudson to jenkins. Since they are practically the same I thought it would be just plug and play. I noticed that when I build my projects my war files are being appended with the SNAPSHOT version instead of just .war. I didn't have this problem in hudson.
Is there a way to globally tell jenkins to use the release war, the one in my target directory, as it's artifact build file or have jenkins, I'm assuming the maven plugin, to not append the SNAPSHOT to the file?

SNAPSHOT is added on purpose. Don't mess with it. Either use bleeding-edge or perform mvn release:prepare release:perform in batch mode from Jenkins.

Related

How to allow any version in Snapshot repo

We're building feature branches into a version 'feature_'. Each feature build will produce the same version. Since these are no releases, I want to deploy the artefacts into the Snapshots repo, but Nexus does not allow versions without 'SNAPSHOT' into the Snapshot repo.
How to configure Nexus to allow any version in a repo?
Solved it by appending '-SNAPSHOT' to the branch version.
It's quite tricky to get Maven in Jenkins to use the right version. The way I solved it now is like this. In the build job configure Git to build the branches origin/feature/*. Then:
In the 'build' section, first thing to do is execute a shell command to construct a file 'env.properties' containing the feature branch version to be used by the Maven build command.
echo BRANCH_VERSION="feature_${GIT_BRANCH##*/}-SNAPSHOT" > env.properties
This uses the GIT_BRANCH environment property of Jenkins. The '##*/' is a Bash Shell Parameter Expansion which strips everything from the parameter value except the part after the last '/' character.
Then use the Environment Injector Plugin to 'inject environment variables' to the build job using the 'env.properties' created in the previous step.
Put 'env.properties' in the 'Properties File Path' field.
Use Maven to build a versioned pom with the correct version using 'Invoke top-level Maven targets':
help:effective-pom -Dbuild.number=${BRANCH_VERSION} -Doutput=versioned-pom.xml. This step is necessary because otherwise the pom in the jar artefact does not contain the correct version causing other problems.
Use another 'Invoke top-level Maven targets' step to do the actual build and deploy using the pom version created in the previous step: -f versioned-pom.xml clean source:jar deploy
That's all folks. If anyone knows a simpler solution, let me know.
This is actually a Maven restriction. You can still use version like feature_x-1.2.3-SNAPSHOT though.
What are you actually trying to achieve though?

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.

maven release perform failed

Today while doing the release of our project, the release:perform command failed in between as our nexus was having intermittent issues. The release command only able to upload one pom file to nexus.
Now, the nexus issue is resolved and I am trying to do the release, it fails as the pom file already exists and its not the snapshot version and we don't have access to nexus so that I can delete that file and start over again.
Is there any way I can pass an argument so that release:perform should continue if the file is already there and ignore this but continue with uploading the rest.
I have looked for options of such type but didn't find anything.
My last resource would be to start the release again, which will bump the version number, but would like to understand if there is any other approach where in I don't need to bump the version.
I am using maven 2.2.1
Here's how I have handled this in the past. The release:perform command does a checkout of the tag from your SCM provider (e.g. SVN). This is done in the target/checkout directory of that project - whatever is there should be an exact copy of the released tag, so it will have the right version number in the pom files etc.
If you move to that directory (target/checkout in the directory where you started the release), you can simply do a mvn deploy there and it should compile and package that version, and then upload it to your Nexus instance.
If you don't have the target/checkout directory, you can check out the Tag created as part of the release:prepare phase from your SCM system to a fresh directory and run mvn deploy there.
Since the tag in your SCM has already been created, the only thing that's left is really compiling, packaging and deploying the release, which is exactly what mvn deploy should do.
If you have provided additional parameters (e.g. for activating profiles) for the build during the call to mvn release:perform, you will have to provide these as well when you run mvn deploy.
Using this approach, your version number will not have to change, it can stay the same, since you're just uploading what has already been tagged as part of mvn release:prepare.
My advice would be for you to request from the admins that the old artifact be removed. You can either re-deploy the code from the tag by checking it out and simply doing
mvn deploy
Or rolling back your release:
mvn release:rollback
And re-doing it as usual.
It is essential to remove the old artifact from the remote repository, if the sizes do not match. Release repositories do not allow the redeployment of artifacts, unless this has been explicitly switched on on the server side.
Furthermore, #nwinkler's answer is also quite good.

Maven WAR overlay problems, while using Hudson + Artifactory

We have three artifacts:
common.jar : with common classes.
public.war : depending on the common.jar, contains only public site resources.
internal.war : depends on both common.jar and public.war, adding authentication
information and security context resource files. Also contains
few administration site classes.
Currently I have structured these in such way, that internal.war overlays itself with public.war.
Building the project locally, installing the artifacts to local repo, works perfectly.
Problems start when trying to get the Hudson builds working with following sequence:
Build all projects in dependency order.
Modify common.jar (say, add a new class method)
Modify internal.war classes in such way that they are compile-time dependent on changes done in 2. step.
Commit both changes, triggering the Hudson builds.
Internal.war build fails because it can not find the symbols added in step 2.
Somehow the build in step 5. is using an old version of the common.jar, and failing because of it.
The common.jar version number does not change, let's say it's 1.0.0-SNAPSHOT for the purposes of this example.
If I DO change the common.jar version number, the build works. (Supposedly because there is only one release by a release version number).
Now, what could cause this using of old artifacts in Hudson builds?
We are running maven builds on Hudson with command "clean package -e -X -U"
"Deploy artifacts to maven repository" has been checked.
It's hard to definitively answer this without access to the real poms, but here is what I would do:
1) Make sure Hudson is using the exact same version of Maven as you are on your local machine
2) Examine the effective pom.xml of internal.war on the Hudson machine in a terminal via mvn help:effective-pom making sure you are running the same mvn executable as your Hudson job does. You need to verify the version of the common.jar in the effective pom.xml of internal.war. It could be different than what you expect due to profiles or settings.xml differences.
3) Check the settings.xml file for your Hudson install of Maven. In particular you need to verify all is well in your distributionManagement, servers, and repositories stanzas. Another good way to check this is to go to your internal.war project and run mvn help:effective-settings and see if what is there matches what is on your local machine.
Something is awry and it won't take long to find with the right analysis.

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