Copying Artifact from local Maven repository to remote - maven

I am trying to implement a staged CI/CD pipeline with a Gradle library. I have managed to get Gradle publishing the produced library to a local Maven repository (build/repository). What I'd like to do then is manually 'promote' the artifact in this local repository to a remote one. A different remote one for each stage in the build pipeline.
And I don't want that logic to be part of Gradle. What I'd like is a way to simply run a Maven command (mvn) to copy the artifact in build/repository to http://myrepositoryurl. I've found Maven copy:stage. However, it fails with some exception about missing implementation for org.apache.maven.plugins.stage.RepositoryCopier.
Problem is I know nothing about Maven, and don't know what this means. It recognizes 'copy', as it is trying to Do Something, and has figured out that RepositoryCopier at least is the thing it needs. But it won't work.
What do I need to do to get this to work?

AFAIK there is not Maven command to copy from a local repository to a remote one.
Maven deploys files from the target directory to remote repositories.

Related

Integrate the local maven plugin with remote repository

I have created a simple maven plugin and installed it in my local repo(.m2). Now I want to use that plugin with a git repo(maven project). How can I do that?
Currently, I am trying to build my git repo using Jenkins and it throws below error-
[ERROR] Plugin sample.plugin:hello-maven-plugin:0.0.1-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact sample.plugin:hello-maven-plugin:jar:0.0.1-SNAPSHOT
I believe simply changing the pom file of my git repo won't work. What should I do so that it resolves the plugin dependency by looking into the .m2 dir first
Your Jenkins probably deploys to a Nexus or Artifactory server. That server is also the right place to manage your plugin.

tell maven to get JAR dependency from given URL

Unfortunately, my project has an external dependency that was never published to any Maven repository. The only way I can get it is by direct download from github (they pushed the binary to github).
One (bad) way is to download the jar manually and commit/push it to my code repository (git). It wouldn't help me to manually deploy this artifact in my local binary repository because I share this project with external contributors that cannot access my private binary repo.
I wonder if maven has a better way to handle this? (Given that I can't upload the artifact to my repo or public repo).
I know that npm allows getting some dependencies from URL. Does maven support it as well?
AFAIK there is no nice way to handle this. You could
Write a script that downloads the jar and installs it in your local Maven repository. This script could be shared through your code repository.
Include downloading and installing the artifact into the Maven build process (by writing a Maven plugin or using the antrun plugin)
Set up a nexus in the cloud that everyone in your team can access.

Maven install local usage when using a repository manger

I am lacking some basic understanding of using a repository manager for our projects. What I don't know is how, if I use a repository manager, if I run a local install command Maven doesn't deploy the package to something like a shared Nexus instance. I seem to have some confusion between local repositories and shared ones when using a repository manager.
Apologies for the naivity and for not testing this myself. We have started versioning our application and using a shared file system approach to getting artifacts and are left with a few questions about what, within the scope of what we are currently doing, will be gained by using a repository manager instead. We do use TeamCity as a build server which is deploying to that currently used file system. I need to know some answers to a few questions before POCing a repo manager.
install is specific to the local repository.
From Maven's point of view whether a remote repository is hosted by your repository manager or is completely external has no relevance - when you're adding your artifact to any kind of remote repository, you need to use the deploy plugin (or release for non-trivial deployments).
Repository managers usually generate instructions on configuring your projects for deployment to a hosted repo.
maven defines a lifecycle (clean, compile, install, deploy...). There are default mappings when you execute "mvn install". So maven knows which plugins to execute for that maven goal.
The Introduction page gives a good overview what happens for each phase (goal) and what the default plugins are: https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
In your case: mvn install will copy the artifacts into the local maven repository to be shared by other projects you have locally.
If you want to share artifacts with other developers on other locations "mvn deploy" will copy the artifacts to the remote repository. Note you need to configure the distributionManagement section in the pom.xml to be able to do that.
The normal maven setup should look like this:
project -> local repository -> private remote repository -> public remote repository
Project: in the simplest case your project consists of source files and a configuration file (pom.xml). The project may depend on third party libraries like junit. The jar files of the libraries are not stored in your project directory, only the information which jars are needed.
mvn package
This command creates a jar out of your project an places it in the target/ folder of your project.
Local Repository: This is a maven repository stored locally on your machine. It normally resides in ~/.m2/repository/. Every dependency you are using in your project will be stored in this repository. On compiling your project, maven will use the jar files from this location.
mvn install
This command creates a jar file and copies it to your local repository: ~/.m2/repository/groupId/artifactId/version/project.jar. Now you can use this jar in different independent projects as a dependency, but only your machine.
Private Remote Repository: Most of the time this is a Nexus in your company network. This server allows to share the build project across developers. Your TeamCity server builds the jar and copies it to your nexus server. Beyond this the nexus server works like a proxy, e.g. A Developer needs junit-4.1.1.jar, so the server looks for it on public remote repositories and caches it.
mvn deploy
This command builds a jar and sends it to your nexus server ('to your private remote repository') After that every developer inside your company network can access the jar.
Public Remote Repository: These are repositories available on the internet which contain several jar files, e.g. maven.codehaus.org
Summary:
If you call mvn compile maven looks for the dependencies in your local repository. If maven can't find them, it will ask the (private/public) remote repository, and copy the files to the local repository.
You should not synchronize a local repository over network, since this type of repository is not targeted at such use and may break in some obscure way.
What you need is a mvn deploy - copies the final package to the remote repository for sharing with other developers and projects
mvn install you tried will just build and install the project in your local ~/.m2 repository. It will_not publish the artifacts to your nexus repository which you have configured.
Both install and deploy are valid build phase - meaning it executes all previous phases. Please refer to Maven docs below for more understanding.
From maven documentation:
the default Maven lifecycle has the following build phases (for a complete list of the build phases, refer to the Lifecycle Reference):
validate - validate the project is correct and all necessary information is available
compile - compile the source code of the project
test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
package - take the compiled code and package it in its distributable format, such as a JAR.
integration-test - process and deploy the package if necessary into an environment where integration tests can be run
verify - run any checks to verify the package is valid and meets quality criteria
**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―Dependencies, static content from remote repository

I am a bit new to maven, but I have some experiences with ant and the build process. I would like to do one thing that is kind of driving me nuts:
Given:
A remote repository (git, svn, hg,…) that holds static content (like images),
one maven project that uses/manages the mentioned repository in the same way as it does with all other dependencies (checkout on install, update whenever updates occur), in other words: the maven project depends on that repository
I finally want to be able to access the content (no *.svn or *.git) and copy it into my build, on build time*.
I want maven to store a local copy of that repository in maven`s local repository (~/.m2/repository) only once on each machine and manage it like all other dependencies.
*I am not trying to build a Java project
Thanks for help!
From what I've seen, Maven projects don't use version control repositories as external artifacts. That's a little too fine-grained for what you want, I think.
I've done something similar, when Project A wanted to use resources from Project B.
Project B, as part of its build procedure, collected it's resources into a ZIP file and deployed the ZIP file into a maven repository.
Project A then references the ZIP file artifact, unpacking it when building to where it needs it.
Look into the dependency plugin for maven, especially the dependency:unpack and dependency:unpack-dependencies goal.
Have fun

Access Maven build properties in Jenkins post-build script to retrieve deployed artifact

I've got a Maven project that Jenkins builds and deploys to a remote repository. I then need to copy the deployed .war to an external location. I've been trying to do this with a post-build shell script but I don't see any way to get the build information from maven (for example, the URL of the deployed artifact). Is there a way to get it, or a way to do this that's more integrated into maven? I can calculate the deployment path using Jenkins build parameters but it seems like a hack.
Thanks,
Steve
After a maven build you should always find the build artifact at
target/<artifactId>-<version>.<packaging>
You can access this path within the maven pom.xml by using the maven properties (see pom reference)
${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}
To copy the artifact to another location after the build you can use several approaches described e.g. in this thread.

Resources