Deploy Maven project to local Artifactory service - maven

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.

Related

Unable to use class from Custom Spring boot library

Goal
I want to use a private repository as a library in other spring boot projects by hosting it as a GitHub package.
Library project
https://github.com/sagarnayak/privatecentralrepo
Client Project
https://github.com/sagarnayak/repoclientproject
Steps To Reproduce
the library project has a library001 module. this is what I want to use as a library for other projects.
In the library module pom file, I have added the repackage execution goal.
......
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
......
I want to use the module as a library and host it as a private GitHub package.
When I do the mvnw deploy in the library001 module this should create an exec jar and push to GitHub to use this library in other projects.
Github has this exec jar.
To use the jar in the client project I have added this as a dependency in the client project.
<dependency>
<groupId>com.sagar</groupId>
<artifactId>libraray001</artifactId>
<version>0.0.3-SNAPSHOT</version>
<classifier>exec</classifier>
</dependency>
This gets the project into the external libraries part of the client project. and this has the class that I want to use in the library (TestModel001).
But when I try to import this into any classes that I want to use it can not resolve the import.
How do I use the library project in this project?
I solved the issue with this -
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
The issue was with the pom file.
I was using the configurations for an older version.
The client project as visible at sagarnayak/repoclientproject is not configured to consume the artifacts from the private Maven repository hosted on GitHub as described in the Working with the Apache Maven registry.
Specifically, following settings are missing:
<repositories> configuration in pom.xml
<servers> configuration in local settings.xml
Add following elements to the pom.xml:
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/sagarnayak/</url>
</repository>
</repositories>
Add following elements to the settings.xml
<servers>
<server>
<id>github</id>
<username>sagarnayak</username>
<password>YOUR_PERSONAL_ACCESS_TOKEN_HERE</password>
</server>
</servers>
Note: Keep settings.xml local to your machine - don't leak that Personal Access Token!
You are packaging the library via spring-boot-maven-plugin
It produces a JAR that has a self-running spring boot structure, and so you are unable to import it as a library correctly.
Try to remove spring-boot-maven-plugin from your libraray001 pom.xml, rebuild, republish and try to consume that artifact in your client project again, refreshing the dependencies and preferably bumping up the library version, to exclude caching possibility during the test.

Pushing artifacts to the Nexus using Jenkins maven-release-plugin

In my Jenkins dashboard, I'm using maven-release-plugin (v0.16.2) to perform a maven release to Nexus repository. I have some issues while using this plugin.
Issue 1:
As shown in the image, it uses <project_name>-<release_version> as the SCM default tag. But I want to change it as v<release_version> value. Therefore, I have added the following change into my project pom.xml file's plugin section.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<tagNameFormat>v#{project.version}</tagNameFormat>
</configuration>
</plugin>
</plugins>
</build>
But still, it uses the aforementioned default tag. Is there any other configuration I have to do in Jenkins or pom.xml file?
Issue 2:
I have configured my pom.xml file with distributionManagement section to push my built artifact to the Nexus repository as follows.
<distributionManagement>
<repository>
<id>releases</id>
<name>Release Distribution Repository</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
</distributionManagement>
With this configuration, Jenkins pushes all the project built artifacts (packaging JAR artifact + dependency XML artifacts in M2) to the given Nexus repository successfully. But in my case, I want to deploy only the JAR file to the Nexus repository (excluding other dependency XML files). Is it possible to do with this Jenkins maven release plugin? Deploy only a specific file or directory?

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.

Maven Artifact download?

I'm new to maven world. My organization has maven release process all the artifacts are kept in our maven remote repo, so I want to deliver some specific artifact version to some of our customer. How can I download specific module version?
In case you don't have a web interface like Nexus for your internal repo, you can create a standalone pom.xml, enter the desired version into the dependencies and call mvn package.
If you need some sample poms and extra info to get you started, you can look here and here
EDIT : I forgot you might expect the artifact to turn up in the same folder as the pom is in. The default maven setting is to download it to a subfolder of /yourHomeFolder/.m2/repository/The name of the subfolder is the group Id of the artifact.
EDIT2: here is a sample setup for downloading the jars into the folder of your choice. If you delete the <outpuDirectory> setting, the artifact jar will be downloaded into the subfolder /dependendies. The execution is bound to the validate phase, so just call mvn validate
<build>
...
<plugins>
<!-- Dependency plugin to download the configured dependencies (transitive). -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<execution>
<execution>
<id>download-jar</id>
<phase>validate</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>put/your/directory/here</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

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

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. :-)

Resources