hudson/maven publishing snapshots - maven-2

I would like to be able to publish snapshots to the repository using maven (or have hudson publish snapshots after each build using maven). I've been reading up on the SCM section of the POM, and I have a couple of questions. Sorry if I'm off base here - this part is new to me.
I don't want to put my username and password in SCM section the POM (under developer connection). Is there any other way for hudson (or anyone else using the maven task) to gain authorization to publish using maven without putting a username/password in the POM?
For just pulling from the repository using maven, can the SCM connection tag point to web svn (the URL tag does right now). In our repository, you need a username and password just to pull down the code.
Thanks,
Jeff

For publishing your login data can be placed in $HOME/.m2/settings.xml
<settings>
<servers>
<server>
<id>internal</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
</settings>
For pulling from source control you'll need to configure Hudson, and it does not need to read from the POM.

You could remove the SCM section from your pom and have hudson pass "-Dproject.scm.developerConnection=scm:type:user#pass:foobase://footron/fooproj" on to maven.
Hudson doesn't need the SCM section. As far as I can tell, you only the scm info (either by tag or by passing it in) for release. You can deploy snapshots without the SCM tags.

Related

Creating a link to the latest release with maven's deploy plugin

My pom.xml contains:
<distributionManagement>
<repository>
<id>ssh-myown-repository</id>
<url>scpexe://user#host/path/to/repository</url>
</repository>
</distributionManagement>
So whenever I issue:
mvn deploy
My project is, well, deployed properly on my remote repository, under a name such as this:
http://host/repository/project/0.7.0-SNAPSHOT/project-0.7.0-20120518.212052-3.jar
I know file "maven-metadata.xml" contains information about which file is the latest release, but I'd very much like the mvn deploy stage to create a link to the latest jar file, say:
http://host/repository/project/0.7.0-SNAPSHOT/project-0.7.0-latest.jar
I understand "scpexe" has no way of doing this directly as links are part of the file system on which the web server is running (ie.: they are not represented as uploadable file content).
I have shell access on this remote server, so is there a way to hook on maven's deploy action to execute a script after deployment is complete ?
You know that the -SNAPSHOT is a thing like the "LATEST". Furthermore i recommend to use a repository manager.

Maven + Mercurial + Site Deploy issues

I'm trying to deploy my Maven generated site to a googlecode project using mercurial.
When I do a
mvn site:deploy
I get Transfer error: org.apache.maven.scm.NoSuchCommandScmException: No such command 'list'.
Its like its trying to do a "svn list" even though I am using mercurial.
In my pom I have maven wagon and mercurial setup (I think correctly):
org.apache.maven.wagon
wagon-scm
1.0-beta-6
org.apache.maven.scm
maven-scm-provider-hg
1.4
Then for my site deploy I have a separate mercurial repository:
<distributionManagement>
<site>
<id>googlecode</id>
<name>googlecode site</name>
<url>scm:hg:${project.site.scm}/</url>
</site>
</distributionManagement>
In my settings.xml I have:
<servers>
<server>
<id>googlecode</id>
<username>...</username>
<password>...</password>
</server>
</servers>
Stumbled upon this question and thought I would provide an answer for anyone else as the documentation for how to do this is sparse:
For quite some time now I've been successfully hosting my website in a Google Code repository that uses Mercurial. It works well and I've had very little issues
First, you have to go to your project, tab "Administer", subtab "Source" and create a new repository called "site". Then, you have to commit and push at least one file, conveniently called "index.html" to that repository because "hg locate", which is called by the SCM plugin, fails on completely empty repositories.
I have this in my POM to deploy to http://site.MYREPO.googlecode.com/hg
<build>
<plugins>
...
<!--Deploy site with Mercurial (Hg)-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.0-beta-3</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-api</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-hg</artifactId>
<version>1.5</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
</build>
<!--
Distribution
-->
<distributionManagement>
<!--Site deploy repository-->
<site>
<id>MYREPO.googlecode.com</id>
<url>scm:hg:https://site.MYREPO.googlecode.com/hg</url>
</site>
</distributionManagement>
You then have to tell Maven your username and password, so add this to your Maven settings.xml file (note the # character is HTML encoded as Mercurial will choke on it normally)
<settings>
<servers>
<server>
<id>MYREPO.googlecode.com</id>
<username>MYEMAIL%40gmail.com</username>
<password>MYPASSWORD</password>
</server>
</servers>
</settings>
Now you can mvn clean site site:deploy and visit http://site.MYREPO.googlecode.com/hg/index.html to get your complete maven site.
site:deploy uses the scp or file protocol for deploying a site to the server (see here). I configure this along normal ssh lines (authorized_keys, etc). And in the pom have something along the lines:
<!-- The location for generating the website. -->
<distributionManagement>
<site>
<id>website</id>
<url>scp://username#server.com/path/to/deploy/directory/</url>
</site>
</distributionManagement>
It takes everything from the target/site directory and copies it across to the defined destination. However, the downside is, that it is up to me to ensure that what I have deployed is actually checked into my version control system. i.e:
hg push (use mercurial directly to push my changes to other developers).
mvn site:deploy (deploys from my local machine using scp).
First of all, I tried TheLQ's answer and even voted for that one (above), because it works for simple projects, especially if you also add wagon-scm and wagon-ssh dependencies to the maven-site-plugin and update all versions to the latest ;) With a multi-module project though I had an issue: each sub-module's site overwrites previously pushed content instead of nesting them (same problem with mvn deploy, i.e., deploying directly to a Hg managed remote maven repo does not create right folder hierarchy).
Therefore, here is an alternative solution, which also makes less commits to the remote repository (though, it requires a bit of manual work).
First, go to your Google Code project, https://code.google.com/p/MYPROJECT, tab "Administer", "Source" and create a new repository called, e.g., "site" (or how you'd like to call it). Then, you have to commit and push at least one file, conveniently called "index.html" to that repository.
Second, have the following in the parent project's pom.xml (only):
<distributionManagement>
<!-- ... other content ...-->
<site>
<id>MYPROJECT.googlecode.com</id>
<name>MYPROJECT auto-generated site</name>
<url>http://site.MYPROJECT.googlecode.com/hg</url>
</site>
</distributionManagement>
and also -
<url>http://site.MYPROJECT.googlecode.com/hg</url>
Note: Aye, it's "http:" and not "https:"; in my example, the URL is NOT going to be used by Maven to actually deploy the site content there (I am not going to execute site-deploy); instead, will use mvn site site:stage (see below). Also, you do not have to touch the settings.xml (the one in ~/.m2/ on *nix systems).
Third, simply clone the remote ('site') repository to your local machine (target directory can be under the parent project's dir as well as under anywhere else's - just cd to THAT_DIR where you want it):
cd THAT_DIR
hg clone https://USERNAME#code.google.com/p/MYPROJECT.site/
Note: if it existed, you do not have to clone again, just do hg pull, hg update (optionally remove old content using hg rm * and commit). You can also use e.g. free SourceTree software instead of console.
Next, from the projects root, do normally (skip 'clean, install' goals if you did already before; I used Maven 3.0.5):
mvn clean install site site:stage -DstagingDirectory=FullPathTo/MYPROJECT.site
Finally, switch to the clone/stage directory, THAT_DIR/MYPROJECT.site, test the website locally (open index.html in a browser), and if happy do:
hg add *
hg commit -m "re-generated MYPROJECT"
hg push
Check it out at http://site.MYREPO.googlecode.com/hg/index.html and the sources and changes at https://code.google.com/p/MYPROJECT.site/
Done.

Release problems with Nexus + Maven + Hudson

When using the release plug-in for Maven on Hudson(1.368), I am getting an error that my distributionManagement section is missing during the deployment phase to our Nexus Maven Repository Manager. If I deploy without using release It woks just fine so should not be a misconfiguration with the server, the section or the settings.
It is worth noting that my company uses different pom files for Hudson and have named them differently. Also the settings.xml in in the individual project directories. This has never been a problem as Hudson allows for the name of the pom and the location and name of the settings file to be specified.
The reason I note the above is that when distributionManagement is moved into the regular pom.xml it does find it (but still doesn't work because its missing the username and password in the settings file). This confuses the heck out of me since for the prior parts of the release process, it uses the correct pom and settings. It just seems to forget them later on. What is going on here?
Thank you in advance.
UPDATE
It seems that the maven release plug-in spins up a new instance of maven which, it seems, is using the default pom.xml rather than our differently named pom. More testing is needed.
The answer (for any lost souls who stumble upon this question) is that maven was indeed forking out a new process which was not using the correct pom file and settings. The solution was to add a section to the pom file as thus:
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.0</version>
<configuration>
<goals>-f POMFILE -s SETTINGSFILE deploy</goals>
</configuration>
</plugin>
This specified those two files to the new maven process.
If I deploy without using release It woks just fine so should not be a misconfiguration with the server, the section or the settings.
Well, there is clearly a misconfiguration somewhere, be it at the Hudson level. But it will be hard to spot it without seeing the pom, the settings, the active profiles, the profiles used during the release, the Hudson setup, etc.
First step: try to reproduce the problem on the command line using the exact same configuration as Hudson.
Second step: use the Maven Help Plugin to understand and debug the issue. More specifically, the following goals:
help:active-profiles
help:effective-pom
help:effective-settings
The reason I note the above is that when distributionManagement is moved into the regular pom.xml it does find it (but still doesn't work because its missing the username and password in the settings file).
It's unclear where the distributionManagement is specified if outside the project's pom.xml (in a corporate environment, it goes typically in a corporate pom.xml, is it the case here?).
It's also unclear if you are actually providing the username and password for a server id matching the repository id of the distributionManagement.
But somehow, a wrong combination is used here. Double check what profiles/settings are active during release/deploy to spot the problem as suggested.
See also
The Maven Deploy Plugin Usage page

Maven repository for Google Code project

I'm hosting a small open source project on Google Code, and I have been asked to submit the jar to a publicly accessible Maven repository. I have almost no practical knowledge of Maven. What would be the best way to do this?
Is there some central repository that I can submit to, or can I host my own? What would I need to do when I want to release a new version of the jar?
I've been Googling and found this, which looks nice and simple, but it seems a bit ... contrary to the spirit of Maven, to commit jar files to SVN :).
Also, would there be a way to still keep track of the download count, as Google Code does?
EDIT
I've been getting some answers, some of which containing hints on what to add to my pom.xml. Thanks guys! But obviously I forgot to mention one important thing: my build script is in ANT, and to put it bluntly, I intend to keep it that way :). I just want to make it easier for Maven users to include my jar in their projects.
The solution I went with in the end
In the end, I did use the solution I referenced before, where I simply commit a Maven repo to SVN. I have the ANT script call Maven to set up the local repo, and then call SVN to commit it to Google Code. For those interested: look at my build script here, in the publish-maven target.
There is a guide to the central repository that has a section on uploading projects that may help. If nothing else you can check the naming conventions and minimal information requirements against your project.
Sonatype also do OSS Repository hosting, see their guide for details.
Update: I'm not saying you should change your build process - if Ant works for you stick with it. It's worth following the Maven conventions in your POM regardless of your build method. As the point of putting your jar in a Maven repository is to make it accessible to Maven users, you will therefore need to define a POM for your published artifact. Following the naming conventions will help your users so you might as well do it. For example adding the SCM details to the pom will (amongst other things) allow your users to import the project into their workspace using the IDE integrations for Maven.
Basically, you have 4 options:
Perform a standard Maven build against a Maven repository (already ruled out)
Set up a Maven repository, do your builds with Ant, and use Maven to deploy the jar and POM.
Set up a Maven repository, ad use an Ant HTTP task to publish the artifacts
Use a Subversion "repository", and use the SvnAnt task to publish the artifacts
Option 1
Use Maven to build and deploy the artifacts (see the Maven book and the above links for details).
Option 2
Assuming you have a build process that creates your jar, and you've defined the POM, your best bet is to publish it to the Sonatype OSS repository as above.
Deploying an existing jar to a standard Maven repository is simple with the Maven deploy plugin's deploy-file goal:
Set up your repository (e.g on the Sonatype servers by raising a Jira request)
Build your jar with Ant.
If you have defined a POM, put it in the same directory as the jar.
Run the deploy-file goal:
mvn deploy:deploy-file -Durl=http://path/to/your/repository\
-DrepositoryId=some.id \
-Dfile=path-to-your-artifact-jar \
-DpomFile=path-to-your-pom.xml
Note that the Maven deploy goal will automatically translate the pom.xml to [project-name]-[version].pom. If you are doing either of the other two alternatives, you will need to ensure you commit the POM with the final name, i.e. [project-name]-[version].pom. You'll also need to ensure you compose the relative paths for the artifacts following the Maven conventions.
E.g. for groupId=com.foo.bar, artifactId=my-project version=1.0.0, the path to the files will be:
/com/foo/bar/my-project/my-project-1.0.0.jar
/com/foo/bar/my-project/my-project-1.0.0.pom
Option 3
If you want to use Ant to deploy to a Maven repository, you can use an Ant HTTP library (Note I've not tried this myself) . You would compose two HTTP put tasks, one for the jar and one for the POM.
<httpput url="http://path/to/your/repository" putFile="/path/to/yourproject.pom">
<userCredentials username="user" password="password"/>
</httpput>
<httpput url="http://path/to/your/repository" putFile="/path/to/yourproject.jar">
<userCredentials username="user" password="password"/>
</httpput>
Option 4
If you want to avoid Maven completely and use Ant to deploy to an SVN-backed repository, you can use the SvnAnt Subversion library. you would simply need to do configure the Svn import task to add your artifacts to the Remote Subversion repository.
<import path ="/dir/containing/the/jar/and/pom"
url="svn://your/svn/repository"
message="release"/>
Check wagon-svn. It will allow you to 'deploy' to a Subversion repository. It's a little convoluted, but it's better than nothing. I know of a few projects that use it at java.net, and I also came across some projects using it at code.google.com.
If you want to use it, then you first need to load wagon-svn as an extension:
<build>
...
<extensions>
<extension>
<groupId>org.jvnet.wagon-svn</groupId>
<artifactId>wagon-svn</artifactId>
<version>...</version>
</extension>
</extensions>
Next, you need to set your deployment targets using the svn: protocol identifier. Here's an example I copied from the Internet.
<distributionManagement>
<repository>
<id>maven-config-processor-plugin-repo-releases</id>
<name>Maven Repository for Config Processor Plugin (releases)</name>
<url>svn:https://maven-config-processor-plugin.googlecode.com/svn/maven-repo/releases</url>
<uniqueVersion>false</uniqueVersion>
</repository>
<snapshotRepository>
<id>maven-config-processor-plugin-repo-releases</id>
<name>Maven Repository for Config Processor Plugin (snapshots)</name>
<url>svn:https://maven-config-processor-plugin.googlecode.com/svn/maven-repo/snapshots</url>
<uniqueVersion>false</uniqueVersion>
</snapshotRepository>
</distributionManagement>
Check if the Maven repository support maven deploy plugin. This would be the easiest approach.
Most repositories uses ssh as the transport. See this for details.
Once it's setup, all you have to do is:
mvn deploy:deploy
You can submit your jar to https://clojars.org/
In your pom.xml:
<repositories>
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
</repositories>

Deploying an assembly to a FTP server using Maven 2

I have a project divided into several sub-modules (each of them are jar libraries):
myapp
myapp-commons
myapp-client
myapp-server
I've configured my pom.xml in order to create 3 assemblies (client.zip, oracle.tar.gz and server.tar.gz) that are finally stored in the myapp/target directory.
I want now is to distribute two of them (oracle.tar.gz and server.tar.gz) to a server using FTP.
Even if I didn't try yet, I know that I can do that quite easily using some lines of Ant inside my pom.xml, but I don't really like this option (I will solve my problem with Ant only if there are no other solution).
There are some SO questions (here or here) that offer solutions for that.
My question is to know if there is a better way to do that? I know about the Wagon Maven2 plugin but I didn't succeed in configuring it in order to deploy the assemblies (and not the JAR created).
As you say in your question, the Ant approach is not ideal, but if you don't find an alternative, this answer shows how to use the antrun plugin to deploy with FTP. The
Update, based on your updated question this part is less relevant, I'll leave it in to help others though.
The wagon-ftp plugin allows you to connect to FTP servers. I've not tried this, but you may then be able to bind the deploy-plugin's deploy-file goal to an appropriate phase to deliver the files to the FTP server (some hints on usage at this blog).
The way to deploy artifacts using FTP is documented in Deployment of artifacts with FTP:
In order to deploy artifacts using FTP
you must first specify the use of an
FTP server in the
distributionManagement element of
your POM as well as specifying an
extension in your build element
which will pull in the FTP artifacts
required to deploy with FTP:
...
<!-- Enabling the use of FTP -->
<distributionManagement>
<repository>
<id>ftp-repository</id>
<url>ftp://repository.mycompany.com/repository</url>
</repository>
</distributionManagement>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-alpha-6</version>
</extension>
</extensions>
</build>
Your settings.xml would contain a server element where the id of that element matches id of the FTP repository specified in the POM above:
<settings>
...
<servers>
<server>
<id>ftp-repository</id>
<username>user</username>
<password>pass</password>
</server>
</servers>
...
</settings>
Now, my understanding is that you want to use such settings for a subset of the produced assemblies only. To do so, I'd create a dedicated module to produced the assemblies to be distributed using FTP and override the distributionManagement element with the FTP setup in this module only.