mvn opposite of dependency:get? How to set up authorization? - maven

I've been tasked with writing scripts to interact with Nexus/Maven. The files I'm working with in Maven are XML files placed there with the specific idea that they would be used by shell scripts. Essentially, the files are configurations for another application.
I've already completed the scripts to pull the files from the repositories, but I'm having problems with putting files into the repositories. To pull the files, I'm using the plugin dependency:get.
What I need is more or less the opposite of that plugin. One that will update the repository with new versions of a file. I think that "mvn deploy:deploy-file" is what I need to use. Will that work?
If so, then the next problem I have is that I can't seem to figure out how to set up the authorization. I have a settings file with a server defined that has the correct authorization information in it, but the link between the server and the repository (or URL?) is missing and the authorization isn't being performed correctly.
How do I connect the repository URL to the server info in the settings.xml file so that mvn will be authorized to perform the correct actions? (I don't know where the .pom file is for Maven, and may not have permissions to alter it.)
Thanks,
Sean.

deploy:deploy-file is correct. Use it with -Durl=http://repo:port/path, -DrepositoryId=server-whatever. Your settings.xml needs to contain
<servers>
<server>
<id>server-whatever</id>
<username>demo</username>
<password>demo</password>
</server>
</servers>
where the server ID server-whatever matches the repositoryId parameter.
Having said that, I'd question the appropriateness of Maven for this. It's designed for binary artifaccts rather than configuration.

The problem turned out to be in the -Durl option.
When using the dependency:get plugin, the URL was something like:
-Durl=http://companymavenrepo
And that worked fine for the dependency plugin.
However, that's not sufficient when trying to put things into the repository using the deploy plugin. The URL has to contain the maven server and the exact repository of where to place the artifact. (My terminology might be off.) I went to our Nexus/Sonatype webpage, looked at the exact repository where the artifact was stored, then used something like this:
-Durl=http://companymavenrepo/nexus/content/repositories/this_maven_repo
That solved the authorization problem, and I was able to add the file into the repository without issue.
(This might have been easier for other to see had I posted both mvn command lines I was trying to use. On the other hand, it also seems reasonable that when you use the -Durl option with a specific value in one command line and it works that it will work unchanged in another command line.)
Sean.

Related

Download artifacts from Maven repository without using Maven

In various shell scripts, we need to download artifacts from a Maven repository (Nexus 2.x at the moment, but may change in the future).
The servers that run the scripts usually have no Maven installed. So I am looking for something http based.
On the one hand, there is a REST interface which can be used like
wget "http://local:8081/service/local/artifact/maven/redirect?g=com.mycompany&a=some-app&v=1.2.3"
On the other hand, you can construct a "standard" URL that seems to work for different Maven repositories. It consists of a prefix, then the groupId with slashes instead of dots, then the artifactId, then the version and then a file name of the form artifactId-(classifier)-version.type.
What is the recommended practise?
The Maven coordinates section of the POM reference describes the second scenario you mentioned. In general I've found that pattern easiest to explain to folks learning Maven, i.e. whether local or remote, an artifact is located at
$REPO/groupId/as/path/artifactId/version/artifactId-version[-classifier].type
where $REPO can be $USER_HOME/.m2/repository or https://remote.repo:port/....
I would also prefer the second as I suspect it will be easier for this app to work with another repository some day if needed. Even if not quite true, it's more self-documenting, so seems like it would be easier to adjust.

TeamCity local artifacts path pattern

I want to create automatic upload to ftp, using 'FTP Upload' runner, with different build configuration, which depends on successfull build of main configuration. But the thing is I don't know the pattern. As for now path looks like this:
C:\ProgramData\JetBrains\TeamCity\system\artifacts\<project_name>\<build config name>\528
What variable contains this last number?
The problem was with bad description of my problem, more definiteve one:
I have to store artifacts on FTP. FTP is on the same machine as TC server and agent (don't ask me why). So I have to somehow grab artifacts and put them into ftp://"project"/msi and ftp://"project"/nuget, depending on build configuration. I've tried: Grabbing artifacts directly - from folder shown in the initial post, idea failed.
The solution is to create another build configuration and set Artifact dependencies, this makes artifacts reachable from new build configuration, which allows to use FTP Upload runner.
Thanks everyone!

Maven remote settings.xml file

Is it possible to specify a remote settings.xml file for maven to use?
So it could be convenient to update one settings.xml file in some remote location (server), and the rest of the dev team wouldn't have to download it manualy.
Quite likely you could do this using tricks outside maven itself, such as symlinking or, as mentioned before me, sharing them through a repository.
But you probably should not. The settings.xml file is used for local settings - specific to your machine. You use this for example to specify the location of your local application server or a local database connection, etc. You would have to force every user to use the same file system layout and server setup, which probably requires more hassle than a shared settings.xml would save.
The proper way to share settings across a project is to include them in the project's pom. If you want to share across a team or organisation regardless of project, you can use a parent pom, or even several layers of them.
Simple answer no, cause the settings.xml defines the configuration to access remote resources furthermore it could contain passwords/keys etc. which would not make sense to store remotely.
You can create a git repository which contains ${HOME}/.m2/ included the settings.xml as a template so the onboarding is simpler.

How to host a maven repo without Nexus

I have small open-source projects hosted on Github which I want to make available for others via Maven. I have a small webspace where I can host static files. How can I create a repo? Also, I would want to remove old snapshots from there if possible.
Standard maven repository implementations are almost all Tomcat web apps. Each one of them should have a static repository, just as your local repository. The webapp serves to the purpose of searching and management of the artifacts stored in that static repository.
If you want to host the repository with static web access only, you'll have to perform the management manually and provide a static manually generated html page that contains GAV coordinates of all artifacts in the repo. No other user but you could ever upload to the repository unless you give your password or enable anonymous FTP acces.
If maven doesn't try to upload anything to the repo until the deploy phase then this approach is still partly usable, since running a mvn clean deploy should fail.
You can check if is it doable like this (I suppose that you have that projects in your local repo):
upload your local repoistory folder to a URL
for the purpose of testing mirror your central repo to that URL
try to build your project with dependencies from your repo
Open your settings.xml file and under <mirrors> node add:
<mirror>
<url>http://your/url/repo</url>
<mirrorOf>*</mirrorOf>
</mirror>
and see if mvn clean install suceeds. Please feedback.
In this SO answer I have outlined the way I set up my OSS projects which are all hosted in Github. There are actually a number of free services out there you could you when you would like to run an OSS project.
I would recommend publishing to Maven Central, if your plugin is well-tested and expected to bring other people benefits as well. You can use CloudBee's BuildHive as a free Jenkins CI.
A static repo works great, per my experience.
I scp'd up my local repository into a static apache server. Legit repo. Not as easy to maintain as a real repo of course, but quite a bit cheaper if you've already got a plain vanilla web host.
Other than setting the permissions properly (same as required for you to browse the folders), it was a pretty painless procedure.
The only two things I did to make it more reasonable were
1 - Wrote a script to "rm -rf ...." on most of the contents of my local repo so that the only thing I am deploying is those few artifacts that are not available in the general repos.
2 - Tarred it up first before scping to my web host.
Hope this helps.
The guy below did something similar, only using FTP which saves him a lot of hand work if he updates his binaries very often.
http://stuartsierra.com/2009/09/08/run-your-own-maven-repository
I think I know how to do it now. I'm using mvn deploy now to create a local repository on the file system and then I upload it to the webserver. If I'm not wrong, there doesn't even need to be a file listing.
The command I'm using is:
mvn deploy -DaltDeploymentRepository=local::default::file:./repo
This creates/updates the local repository automatically, so the repo can be synced with a server.

Maven verify signatures of downloaded pom/jar files

I was trying to find if there is SSL enabled central repository but there probably isn't. I noticed that there are signatures for every jar and pom file in maven central repository. So at least I'd like to check signatures of all maven downloaded files (pom/jar).
The example from http://repo1.maven.org/maven2/org/apache/ant/ant/1.8.2/:
ant-1.8.2.jar
ant-1.8.2.jar.asc
ant-1.8.2.jar.asc.md5
ant-1.8.2.jar.asc.sha1
ant-1.8.2.jar.md5
ant-1.8.2.jar.sha1
ant-1.8.2.pom
ant-1.8.2.pom.asc
ant-1.8.2.pom.asc.md5
ant-1.8.2.pom.asc.sha1
ant-1.8.2.pom.md5
ant-1.8.2.pom.sha1
I realize that I'll have to import public keys for every repository and I'm fine with that. I guess that public keys for maven central are here https://svn.apache.org/repos/asf/maven/project/KEYS.
There are PLENTY of tutorials on web on how to sign with maven. However I didn't find any information on how to force maven (2 or 3) to verify signatures of downloaded jar/pom files. Is it possible?
(Nexus Professional is not an option)
Thank you for help.
Now, that people seem to realize this is a real security problem (as described in this blog-post (the blog seems down, here is an archived version of the blog)), there is a plugin for verifying PGP signatures. You can verify the signatures for all dependencies of your project with the following command:
mvn org.simplify4u.plugins:pgpverify-maven-plugin:check
Of course, to be 100% sure the plugin is not malicious by itself, you would have to download and verify the source for the plugin from maven central, build it with maven, and execute it. (And this should also be done with all the dependencies and plugins that are needed for the build, recursively.)
Or you use Maven 3.2.3 or above (with a clean repository), which uses TLS for downloading all artefacts. Thus man-in-the-middle attacks are impossible and you get at least the artefacts as they are on maven central.
See also:
related Question and Answer
Sonatype's Blog to this topic
Could you write a bash shell script using GnuPG to verify each sig?
Something like:
for x in *.jar; do gpg --verify "${x}".asc; done
Obviously you would need the public keys for all the sigs before you started.
SSL access to Central is now available for a token payment. From https://blog.sonatype.com/people/2012/10/now-available-ssl-connectivity-to-central/ :
We’re making SSL connectivity to Central available to anyone that downloads open source components regardless of the repository manager.
...
In order to ensure the highest level of performance for those who count on SSL, we are securing the service with a token. You can get a token for your organization simply by providing a $10 donation that will be donated to open source causes.
Assuming you only want to download artifacts w/ valid checksums, one option would be to run the OSS version of Nexus and configure it to have a proxy of central. Then configure your settings.xml to only load from your repo (mirror tag in settings.xml). You can then configure nexus to only allow artifacts that have a valid checksum.

Resources