how to automate the snapshot versions in maven 3 - jenkins

I have two projects namely Abc and DEF. Now the project DEF has dependency of the project Abc. Daily we use the run the Jenkins build. The project Abc artifacts will be deployed to the Nexus. The Project DEF has to utilized the latest snapshot from the nexus directory which was created by the project Abc.
I should not change the project DEF pom.xml files every-time to pickup the latest build from project Abc. How can i achieve this automates process.
By the way i used the buildnumber-maven-plugin to do the auto version increment in the project Abc.

I assume you have something like this in your pom.xml of DEF
<dependency>
<groupId>some.group.id</groupId>
<artifactId>Abc</artifactId>
<version>1.00.000-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
With that, as long as both Abc and DEF are configured as Maven-Jobs in Jenkins, the CI-Server should notice every time a SNAPSHOT for Abc is built and therefore trigger a new build of DEF (unless, of course, somebody beside the CI-Server was building and deploying the SNAPSHOT to Nexus Repository, which shouldn't happen.)
If you want to enforce always using the latest Snapshot from the Nexus Repository you can add Option -U as a Maven Option.

Related

Nexus repository path

I have uploaded some release artifacts from Jenkins to Nexus. I can see they have been created under Nexus as per the -Dversion I have provided.
Example: AppName-BuildNumber-Snapshot.zip
However, somehow the repository path is autogenerated, it has extra yyyymmdd.hhmmss appended to it.
Example: AppName-BuildNumber-Snapshot-yyyymmdd.hhmmss.zip
I would like to download the release artifact from Jenkins but due to the autogenerated Nexus repository path I am not able to download it in the separate job.
How can I force it to stop adding yyyymmdd.hhmmss to the repository path? Or is there anyway I can retrieve the repository path using AppName and BuildNumber?
If you are uploading a SNAPSHOT, then Nexus dynamically stores it with a timestamp. That's because you can replace -SNAPSHOTs with newer copy w/same GAV. This is unlike real # jars which cannot/should not be redeployed, thus preserving their integrity.
To download a -SNAPSHOT, you just reference it as -SNAPSHOT; maven, aether, etc will retrieve the latest.
Maven (by default) only checks the remote repository for versions newer than your local once daily, unless you use -U option or change the updatePolicy.
If you want "solid" number, then you must release jar.
btw, you should see it's -yyyymmdd.hhmmss-nn, where nn is an incremental number for that version.
Nexus supports many different repository formats. If you only require maven, use Nexus 2 as it better supports maven.
Repository types: Maven has two distinct types:Release and Snapshot Repositories.
If you want to "upload a zip file containing release artifacts and retrieve it back based on the build version number?", then that's what you should do.
You must configure a repository of type release, not snapshots (gleened from: -DrepositoryId=dsnexus-snapshots) (or in addition to type snapshots).
To pass the "build version number", then presumably, you have:
[ X ] Create a formatted version number
Environment Variable Name [ label ]
Make sure your maven step has:
[ X ] Inject build variables
Then, mvn deploy:deploy-file -DgroupId=com.my.gid -DartifactId=AppName -Dversion=${label} -DrepositoryId=dsnexus-release
ps: you'll also want to implement a cleanup strategy in your Nexus repository if you are pumping every build as a new artifact.

Q: How can I save an artifact into Nexus Repository using a groovy pipeline?

My question is about saving artifacts into a repository. Especially, I am trying to upload into the Nexus Repository artifacts and release versions after the execution of a build pipeline for a Maven project (through Jenkins).
The only way that I want to do so, is just by using a pipeline written in Groovy so to integrate with Jenkins.
Note: I want the artifact version number to be always the same and the version number to change dynamically (not manually).
Is there a command or code generally which enables me to do that?
You are on the wrong level, this should happen in maven.
In pom.xml you need. (more here)
<distributionManagement>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://localhost:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
and then in the plugins section
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
and you should be able to just do mvn clean deploy from your pipeline.
EDIT
There is another way with Nexus Artifact Uploader plugin
nexusArtifactUploader {
nexusVersion('nexus2')
protocol('http')
nexusUrl('localhost:8080/nexus')
groupId('sp.sd')
version("2.4.${env.BUILD_NUMBER}")
repository('NexusArtifactUploader')
credentialsId('44620c50-1589-4617-a677-7563985e46e1')
artifact {
artifactId('nexus-artifact-uploader')
type('jar')
classifier('debug')
file('nexus-artifact-uploader.jar')
}
artifact {
artifactId('nexus-artifact-uploader')
type('hpi')
classifier('debug')
file('nexus-artifact-uploader.hpi')
}
}
As #hakamairi already said, it is not recommended to re-upload artifacts with the same version to Nexus repository, Maven is built around the idea that an artifact's GAV always corresponds to a unique artifact.
However, if you want to allow re-deployment, you need to set the deployment policy of a release repository to "allow redeploy", then you can redeploy the same version. You cannot do that without allowing on repository side.
And for deploying to Nexus repo, you can use either Nexus Platform Plugin or Nexus Artifact Uploader.
ADDITIONAL SOLUTION THAT ALSO WORKS
I executed it manually and I exported the result of Nexus call. The result was the following command. This command need to be inserted inside the Jenkins pipeline as a Groovy code:
nexusPublisher nexusInstanceId: 'nexus', nexusRepositoryId: 'maven-play-ground', packages: [[$class: 'MavenPackage', mavenAssetList: [[classifier: '', extension: '', filePath: '**PATH_NAME_OF_THE_ARTIFACT**.jar']], mavenCoordinate: [artifactId: '**YOUR_CUSTOM_ARTIFACT_ID**', groupId: 'maven-play-ground', packaging: 'jar', version: '1.0']]], tagName: '**NAME_OF_THE_FILE_IN_THE_REPOSITORY**' }
In the field of filePath we need to insert the path and the name of the artifact.jar file.
In the field of artifactId we need to insert the custom (in this occasion for mine artifact) artifact id
In the field of tagName we need to insert the custom name of the directory from inside the Nexus Repository
This is a solution that can be done automatically without manual changes and edits. Once we have created the directory in Nexus repository this is going to be executed without any issue and without the need of changing the version number.
Note: also we need to enable re-deploy feature from inside the Nexus Repository settings.

Versioning modules independently in multi project environement and zipping all dependencies

I am new to ant and Ivy. We are using Jenkins for CI with ant for builds, Ivy for dependency manger. We have several modules/projects which generate jars and wars, which can be independently versioned and released (not all modules will be released at the same time), so, need to maintain version number separately for each module. We want to use the version format A.B.C.D (ex: 1.2.1.2). I found I can use a property file to enter a version number and use ant BuildNumber task to increment the number for our nightly builds. So, once all the features are in and tested we move the last successful nightly build as new released version but we want to change the version number without rebuilding it. For example last successful build was 1.2.1.20 and it was tested thoroughly and has all the feature, we have to make this build from 1.2.1.20 to 1.3.0.0 without rebuilding the modules. How can I do that using ant? And also I need to publish them to my shared repository with the version 1.3.0.0. How do I do that?
Also, we want to create a zip file for each module with all dependency files along with the module's jar file for delivery. Is there any ivy or ant tasks that can help to create this?
I think you've asked two questions...
Generally, every build I create is releasable so I'm always incrementing the last digit in my release number scheme. For controlling the version number I prefer to use the ivy buildnumber task, which increments based on what has been previously pushed to your repository (very useful).
Creating a zip package is quite straight forward. Just alter your ivy file to publish more than one artifact.

Jenkins Continuous Integration System

We have a maven-3 projects with dependencies like this A.jar <- B.jar <- C.jar <- D.war (<- means depends on). They all are under seperate SVN locations. So my question is , How can I organize Jenkins build job for D.war to force also build fresh jars for A,B and C? Also sometimes I need to build only B.jar and force to build A fresh jar. Maven simple <dependency> tag is not enough to force build them.
Thanks,
Arsen

Why is Grails taking the jar dependencies instead of the existing maven project dependencies?

I'm using IntelliJ IDEA 10.0.2 (with groovy/grails support), maven 2.2.1 and grails 1.3.6.
We have a big maven project, which depends on many other maven projects. Let's say the workspace structure looks as follows:
backend-project (Java project, without further project dependencies)
output-project (Java project, without further project dependencies)
frontend-project (Grails project, which dependes on both, backend and output)
That means, within my frontend-project's pom.xml I have defined 2 Project Dependencies:
e.g.
<dependency>
<groupId>com.company.project</groupId>
<artifactId>backend-project</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.company.project</groupId>
<artifactId>output-project</artifactId>
<version>${project.version}</version>
</dependency>
Let's assume that I change some Java Source within the output or backend project. When I
run the grails application now, then it won't consider the changes. I have to publish the changed artifact locally and then resolve it again by the grails project before running the application in order to take effect.
This tells me that the grails project just depends on the project dependency jars within the maven repository and does not care about any existing project dependency "sources" within the workspace.
Does it have to be that complicated and if so, why?
Note that if my frontend project was a spring web project, the changes will be seen in IDEA and tomcat will even reload the change dynamically.
Note that when IDEA recognizes a mavenized grails project, it won't run the grails project with: "grail run-app" anymore but with a more complicated version of: "mvn grails:exec -Dcommand=run-app". Don't know if this is of any relevance..
Thanks!
Mr. Slash
Maven always picks up the jar files from the repositories (local and then remote etc depending on your pom.xml config).
Think about it: How would your main project know where the backend-project or the output-project files are located?
If you want a direct dependency then remove it from pom.xml and modify the project build path to directly add the projects' outputs to your main projects. In Eclipse open the properties page of the main project => build path => projects => add.

Resources