mvn deploy:file to different repositories for snapshot and release version - maven

Is it possible to in some way tell the maven deploy:file goal to deploy to two independent artifactories based on whether the version of the project is a snapshot / release?
I'm hoping there might be a property which indicates the fact the version has -SNAPSHOT prepended, or perhaps the default artifactory to deploy to (which has been worked out based on the version number already).
I thought about using two different profiles and working out if its a snapshot in ant by parsing the pom.xml file, but I'd rather a cleaner solution if possible.
Currently, my deploy plugin looks as follows, but this just deploys to the release artifactory regardless of the version;
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>deploy-zip-created-by-ant-to-artifactory</id>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<repositoryId>${project.distributionManagement.repository.id}</repositoryId>
<url>${project.distributionManagement.repository.url}</url>
<file>${project.basedir}/Build/deploy/MyArtifact.zip</file>
<pomFile>${project.basedir}/MyArtifact-pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
Many Thanks

If you defined your repositories within your settings.xml you can use the
mvn deploy:deploy-file -DrepositoryId=releases -DartifactId=... -Durl=

Over here, I used the GMaven plugin to choose the repository from the distributionManagement section of the POM and store it in a property.
The deploy plugin can then use that property.

Maybe you want to use the build-helper-maven-plugin to deploy an additional artifact

This is presumably the Maven way:
<distributionManagement>
<repository>
<id>release</id>
<url>http://my-releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://my-snapshots</url>
</snapshotRepository>
</distributionManagement>
When doing a deploy of a snapshot version, it'll go the snapshots repository. For a non-snapshot release the regular repository will be used.
Just run deploy and it'll work. :-)

Related

How to create own Maven Repository?

I want to know, how to create my own dependency to use my code in other projects.
I were following tutorial.
I`ve tried to create project with simple class as Maven Project.
I did clean-package. Created github repository. Added my project there with "target" package.
in pom.xml i added
<properties>
<java.version>1.8</java.version>
<github.global.server>github</github.global.server>
<github.maven-plugin>0.12</github.maven-plugin>
</properties>
<distributionManagement>
<repository>
<id>internal.repo</id>
<name>Temporary Staging Repository</name>
<url>file://${project.build.directory}/mvn-repo</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
<configuration>
<altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo</altDeploymentRepository>
</configuration>
</plugin>
<plugin>
<groupId>com.github.github</groupId>
<artifactId>site-maven-plugin</artifactId>
<version>${github.maven-plugin}</version>
<configuration>
<message>Maven artifacts for ${project.version}</message>
<noJekyll>true</noJekyll>
<outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
<branch>refs/heads/mvn-repo</branch>
<includes><include>**/*</include></includes>
<repositoryName>GITHUB_NAME_REPOSITORY</repositoryName>
<repositoryOwner>MY_GITHUB_NICKNAME</repositoryOwner>
</configuration>
<executions>
<execution>
<goals>
<goal>site</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
after in root of .m2 directory i created settings.xml with:
<settings>
<servers>
<server>
<id>github</id>
<username>[username]</username>
<password>[password]</password>
</server>
</servers>
</settings>
did again clean+package and pushed to github.
after trying to use dependency - not found.
in github repo no mvn-repo branch
I haven't used the new GitHub repositories yet, but what work quite well so far:
private, single machine usage: mvn install -> the artifact will be installed in your local Maven repository and can be referenced by any other project on the same machine
Open Source, multiple machines/ developers: mvn deploy to Maven Central. See the documentation for more information about configuration and involved steps.
Closed Source, multiple machines/ developers: mvn deploy to your own Maven Repository manager such as Nexus (configure the distributionManagement accordingly)
That said, it's a best practice to use your own Maven Repository Manager in all 3 cases and define a single group.
From the Maven default lifecycle documentation:
package: take the compiled code and package it in its distributable format, such as a JAR.
install: install the package into the local repository, for use as a dependency in other projects locally.
deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

Deploy Maven project to local Artifactory service

I have forked a webjar project for working locally in my company's environment. We use Artifactory/Ivy for dependency management.
Currently Smart Table (and other webjars) pom.xml show the following for deployment:
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.5</version>
<extensions>true</extensions>
<configuration>
<serverId>sonatype-nexus-staging</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
It will by default publish to Sonatype, which is good for publicly-visible open source projects once you have release credentials.
However we do currently want to work locally on a fork of the project and deploy to our local Artifactory server. Contributions (to the real project) will be shared via Pull Request, so we are not interested in going to Sonatype repository.
Question
How do I change Maven pom.xml so that mvn deploy will deploy to a locally-configured Artifactory service? (For which credentials are stored in Maven configuration of course)
Bonus question
Can I tell Maven to publish using Ivy layout or should I create a new Maven-layout repository in Artifactory?
First option is to use the standard Maven deploy plugin
<distributionManagement>
<repository>
<id>repo-id</id>
<name>Artifactory</name>
<url>http://server:8081/artifactory/repo-id</url>
</repository>
</distributionManagement>
You should configure your settings.xml file to define corresponding entries which provides authentication information. Server entries are matched to the different parts of the distributionManagement using their elements.
<server>
<id>repo-id</id>
<username>repo-username</username>
<password>password/encrypted password</password>
</server>
Second option is to use the JFrog Maven Artifactory plugin, available at the JCenter repository in Bintray
<build>
<plugins>
...
<plugin>
<groupId>org.jfrog.buildinfo</groupId>
<artifactId>artifactory-maven-plugin</artifactId>
<version>2.4.0</version>
<inherited>false</inherited>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>publish</goal>
</goals>
<configuration>
<deployProperties>
<gradle>awesome</gradle>
<review.team>qa</review.team>
</deployProperties>
<publisher>
<contextUrl>https://server:8081/artifactory</contextUrl>
<username>username</username>
<password>{DESede}...</password>
<repoKey>libs-release-local</repoKey>
<snapshotRepoKey>libs-snapshot-local</snapshotRepoKey>
</publisher>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Through the Maven Artifactory Plugin, Artifactory is fully integrated with Maven builds and allows you to do the following:
Attach properties to published artifacts in Artifactory metadata.
Capture a BuildInfo object which can be passed to the Artifactory REST API to provide a fully traceable build context.
Automatically publish all build artifacts at the end of the build.
More detailed usage examples of the plugin can be found in this Github project.
Bonus question
Maven can only deploy to a Maven2 (default) or Maven1 (legacy) layout repository. You will have to create a new Maven repository in Artifactory.

Simultaneously deploy artifact to Maven Central and internal Nexus

I have a project which deploys to Maven Central via OSSRH using the Maven release and nexus-staging-maven plugins using the directions from http://central.sonatype.org/pages/ossrh-guide.html and http://central.sonatype.org/pages/apache-maven.html .
This works fine, but it often takes several hours for the artifact to be visible on Maven Central. Often we would like to make use of the deployed artifact immediately, so we end up deploying it from our local repositories to our internal Nexus server using deploy:deploy-file . This works but it is inelegant and easy to forget to do. Is there any way to make Maven deploy to an internal Nexus as well as Maven Central as part of the release process?
Note: This question is similar to, but not quite the same as, https://stackoverflow.com/questions/29019682/promote-artifact-from-internal-nexus-repository-to-maven-central
Add an additional execution to the maven-deploy-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven.deploy.plugin.version}</version>
<executions>
<execution>
<id>nexus-deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration>
<altDeploymentRepository>yourNexusRepo</altDeploymentRepository>
</configuration>
</execution>
</executions>
</plugin>
The yourNexusRepo value will look something like this:
releases::default::https://nexus.host.org/nexus/content/repositories/releases
You should be able to get the exact URL from Nexus. The part before the first :: is the repository ID.
We solved this problem by no longer using nexus-staging-maven-plugin as an extension. This is described at https://help.sonatype.com/repomanager2/staging-releases/configuring-your-project-for-deployment :
If more control is desired over when the plugins deploy goal is
activated or if Maven 2 is used, you have to explicitly deactivate the
Maven Deploy plugin and replace the Maven Deploy plugin invocation
with the Nexus Staging Maven plugin...
In our case, we disabled the default-deploy execution by setting <phase>none</phase>. Our full solution is available at https://github.com/newmediaworks/nmw-oss-parent/commit/a7377a158feded473cb2f1618449e34173c22252 which includes an additional execution of maven-deploy-plugin in the jenkins-deploy profile.
The key takeaway follows, which so far seems to behave as if extension were enabled, but does not interfere with additional maven-deploy-plugin executions:
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId><artifactId>nexus-staging-maven-plugin</artifactId>
<!--
Not using as extension, since it blocks maven-deploy-plugin in the jenkins-deploy profile:
<extensions>true</extensions>
-->
<executions>
<execution>
<!-- Manually added since nexus-staging-maven-plugin is not used as extension -->
<id>default-deploy</id><phase>deploy</phase><goals><goal>deploy</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId>
<executions>
<execution>
<!-- Manually disabled since nexus-staging-maven-plugin is not used as extension -->
<id>default-deploy</id><phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>

How to configure Maven to run a SonarQube project analysis with two different quality profiles?

We run SonarQube analyses for our Java projects via Maven. Maven somehow does this automagically; all we did was add the sonar-maven-plugin to our pom.xml:
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</pluginManagement>
This works fine.
But now we need to run the SonarQube analysis twice, with different quality profiles. Since you can't easily change the project key from Maven, we use SonarQube's branch property to differentiate the SonarQube projects, like this (again from pom.xml):
<properties>
<sonar.profile>MyQualityProfile1</sonar.profile>
<sonar.branch>Dev_${sonar.profile}</sonar.branch>
...
</properties>
This way, we end up with two project entries in the SonarQube UI, both of which contain the exact same code, but have different issues depending on their quality profile (one used quality profile 1, and the other used quality profile 2).
Problem: In order to achieve this, I must manually change the pom.xml properties and run the entire build twice.
Question: How can I configure maven to simply run the sonar:sonar goal twice with different properties?
This would save us a lot of time on our builds. I already found this similar question, but no answers so far. Thanks!
Expanding on the previous answer given by Eldad AK regarding profiles:
Create two maven profiles as follows:
<properties>
<sonar.branch>Dev_${sonar.profile}</sonar.branch>
</properties>
<profiles>
<profile>
<id>QualityProfileOne</id>
<properties>
<sonar.profile>MyQualityProfile1</sonar.profile>
</properties>
</profile>
<profile>
<id>QualityProfileTwo</id>
<properties>
<sonar.profile>MyQualityProfile2</sonar.profile>
</properties>
</profile>
</profiles>
Then run the following:
$ mvn clean install -DskipTests
$ mvn sonar:sonar -PQualityProfileOne
$ mvn sonar:sonar -PQualityProfileTwo
(you may need to perform a clean between running sonar, not sure)
Try to configure two executions of your plugin. Something like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<executions>
<execution>
<id>s1</id>
<phase>verify</phase>
<goals>
<goal>sonar</goal>
</goals>
<configuration>
<sonar.branch>MyQualityProfile1</sonar.branch>
</configuration>
</execution>
<execution>
<id>s2</id>
<phase>install</phase>
<goals>
<goal>sonar</goal>
</goals>
<configuration>
<sonar.branch>MyQualityProfile2</sonar.branch>
</configuration>
</execution>
</executions>
</plugin>
This will start two executions of sonar in phases verify and install, each with another sonar.branch value. In Sonar you can then configure the required quality profiles after the first analysis.
A combination of maven and Ant might work: Use Maven for the first sonar analysis as you already do and use the Maven Antrun Plugin to execute another SonarQube configuration defined using the SonarQube Ant Task.
I would opt for the maven profiles.
Each profile would have its own properties.
I hope this helps.

maven release:prepare not deploying the projects with release version

I have a flat project structure with multiple projects.
I am using Nexus for internal repository and SVN for Source code management.
I am able to deploy the SNAPSHOT build of my project.
In my parent pom i have added the maven release plug-in:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
</plugin>
and the distribution info:
<distributionManagement>
<repository>
<id>releases</id>
<url>http://localhost:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Internal Snapshots</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
When I am doing a mvn release:prepare, the artifacts with the release versions are not getting deployed to repo. So if I have a project A with dependency on project B. Project A is not able to get the artifact of B with the release version.
The release:prepare by default calls "clean" and "verify" goals which simply tries to compile and run test. So nothing is deployed to your remote repository nor installed in your local repository.
To handle dependencies in multi-module projects with the new release version you need to have things installed in local repository during release:prepare, so change the default goals to "clean" and "install" with the preparationGoals property.
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<preparationGoals>clean install</preparationGoals>
</configuration>
</plugin>
You can add any goals you would need during your build.
The actual deployment to remote repository will be done by the release:perform goal.
Laurent

Resources