Jenkins - get latest artifact version from remote repository - maven

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.

Related

Maven 3.6 How to resolve the latest artifact for a deployment job?

I've got a deployment module with its own pom.xml. I use the module to deploy a 'module' and its version.
Modules are built by bamboo and pushed into the local repository of the agent (we haven't got nexus or artifactory yet so currently using the local repo).
When it's time to deploy, I would want to pass the module name and something to fetch me the latest version in the repo.
In ivy, I can use latest.integration or latest.release. However, I am not sure why maven does not allow it or at least not anymore.
So the plan is to use the LATEST version if we don't explicitly request any version.
How would we do this?
Actually, using LATEST as version would fetch the latest one.

Can I avoid Maven deployed war version with timestamp in Archiva?

In out project we are using using deployed war file in /archiva-2.2.0/repositories/internal/com/xyz/1-SNAPSHOT/proj-1-20160204.122021-15.war path using shell script to copy to jboss. However finding the latest build timestamp and build number is very difficult. Is there a way to avoid using timestamp while storing it in archiva like proj-1-SNAPSHOT.war?
I have already read about <uniqueVersion>false</uniqueVersion> whcih is not supported in maven 3.
I am using archiva-2.2.0, maven-3.3.9.
Maven repositories wasn't designed to distribute deployable components, your continuous integration environment should take care of this. Jenkins has eg Archive Artifacts (native) and Copy Artifact Plugin which you can use to store and recover binaries in your pipelines.
But you can workaround this behavior changing the version of the war to a stable one - removing the -SNAPSHOT suffix. This will lead you with a predictable URL.
I am posting this as it is a new finding, if I wget http://xx.xx.xx.xx:8083/repository/internal/com/xyz/1-SNAPSHOT/proj-1-SNAPSHOT.war. I get the latest deployed artifact in the archiva repository. So archiva does a 302 redirect to point to url of http://xx.xx.xx.xx:8083/repository/internal/com/xyz/1-SNAPSHOT/proj-1-20160204.122021-15.war location and downloads the latest build. I am not sure if this works for other repositories like nexus or artifactory etc.
Ofcourse I will need a cron job to periodically clear of the stale snapshot artifacts.

Maven ssh deployment overrides artifacts in nexus - Can this be prevented?

we are using the Maven Wagon SSH and Wagon SSH External plugins to deploy to our nexus repository. This way artifacts in the nexus can be overridden.
Is there a way to prevent this on the maven side? Or do we have to change either the wagon or the file system permissions for the artifacts?
I would suggest you to use the deploy command or use maven-release-plugin. With the plugin you can prepare your pom.xml to next version and it will commit these changes to your version control (git,svn). Then you can run perform command to build prepared version and deploy it into the nexus.
The point is you can re-deploy your working snapshot version (that ends with -SNAPSHOT) as much as you want. But you can deploy version WITHOUT snapshot only once. That ensures you the release version wont be overridden this way!
The problem is you have to update your version manually or you will use that mentioned plugin.

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.

How do I find the latest version of an artifact from a maven repository

As part of an automated deployment I need a script to download the latest version of an artifact from our internal repository.
Ideally this script will be with ant or a unix shell script.
So for example:
I have myArtifact.war and it has versions 1.0 , 1.1 and 2.0 - I need the script given the correct group id and artifact id to retrieve version 2.0 from our maven repository (currently using artifactory).
Is there any easy way to do this?
You can use the Maven Dependency Plugin goal get together with LATEST as version for your artifact:
mvn org.apache.maven.plugins:maven-dependency-plugin:2.8:get
-DremoteRepositories=<URL_to_your_maven_repo>
-Dartifact=<group_id>:<artifact_id>:LATEST
-Dpackaging=jar
-Ddest=<target_dir>/<artifact_name>.jar
You can parse the maven-metadata.xml to see what versions are available, and which version is the "release" version. See this answer about plugin versions for more details.
If you are using Nexus, you can use the REST API to query the repository. You can also use the REST client API to simplify your processing.
To update the release version, activate the release-profile in the Maven super POM when you do mvn deploy. You can do this by adding -Prelease-profile or -DperformRelease=true to the command line.
The profile is activate by default in the maven-release-plugin's perform goal. It is controlled by the useReleaseProfile property. See the release-perform goal's documentation for more details.

Resources