Cannot publish to webdav repositories using the 'maven-publish' plugin

Dear all,

How can I add support of the webdav protocol to the ‘maven-publish’ plugin?

It is document for the old ‘maven’ plugin with ‘uploadArchives’ (1) but not for the new ‘maven-publish’ plugin.

Where can I add to the classpath the jar ‘org.apache.maven.wagon:wagon-webdav:1.0-beta-2’ ?

I get the exception

Execution failed for task ‘:publishMyPublicationPublicationToMavenRepository’.

Failed to publish publication ‘myPublication’ to repository ‘maven’

Error deploying artifact ‘com.cloudbees.clickstack:tomcat8-clickstack:zip’:

Error retrieving previous build number for artifact ‘com.cloudbees.clickstack:tomcat8-clickstack:zip’: repository metadata

for: ‘snapshot com.cloudbees.clickstack:tomcat8-clickstack:1.0.0-SNAPSHOT’ could not be retrieved from repository: remote

due to an error: Unsupported Protocol: ‘dav’: Cannot find wagon which supports the requested protocol: dav

Extract of build.gradle

apply plugin: ‘maven-publish’

// …

publishing {

publications {

myPublication(MavenPublication) {

from components.clickstack

}

}

repositories {

maven {

url “dav:https://repository-community.forge.cloudbees.com/snapshot

}

}

}

(1) http://www.gradle.org/docs/current/userguide/maven_plugin.html “Table 52.3. Protocol jars for Maven deployment”

Publishing to webdav is not yet supported by the new publishing plugins. Unfortunately this means you’re stuck with the old publishing mechanism for now.

I’ve raised GRADLE-2919 to track this.

Thanks Daz

A fix for this would make a great community contribution, if anyone is interested.

We are looking to so something similar here by publishing to S3 (using the maven-s3-wagon). Is there a thought on how this should be implemented? Something similar to the how it’s implemented in the original ‘maven’ plugin?

I think the basic goal is to add some libraries to the classpath of the ant task that is backing the PublishToMavenRepository tasks, correct?

@john, I would say there are two part to the solution:

The first part is some DSL for defining S3 as a target repository, so you can do something like:

publishing {

repositories {

s3 { … }

}

}

The second part is an implementation to wire up the maven publishing plugin to S3. There are a couple of options here:

  1. Bundle the appropriate wagon jar in the Gradle distribution, and map the S3 configuration to the appropriate Maven Repository configuration. We’d also need to fail gracefully when you tried to publish an Ivy module to S3, or to resolve things from S3.

  2. Add a Gradle S3 repository implementation (a RepositoryTransport implementation) and an adapter from the Wagon -> Gradle APIs. This would allow S3 to be used for any kind of publication and also for resolving.

These aren’t mutually exclusive. We could do the first and later move to the second.

I should also add that the second option above would also mean that the maven-publish plugin would then be able to publish to any kind of repository that Gradle understands (eg sftp), as the ivy-publish plugin can.

@adam - would a new DSL really be necessary for utilizing S3 repos? It’s not a new repo type, it’s just a different protocol for talking to the repo. I was envisioning something more like:

publishing {

repositories {

maven {

url ‘s3://my-bucket/’

}

}

}

In this way, everything would still be stored in either a Maven or Ivy layout, just on an S3 backend.

For maven-publish this works as long as I can get the wagon jar into the PlexusContainer (using addJarResource(File…), which is what the old maven plugin does)

I like the idea of just adding a RepositoryTransport implementation, but would it be useful to create a more open API that allowed a user to add their own implementations (then build authors or plugins could add support for various protocols without changes to core)?

Last thing - I am initially using this S3-Wagon plugin: https://github.com/jcaddel/maven-s3-wagon, but it lacks a good API for providing the S3 credentials. It currently only supports through ENV vars, System properties, ~/.m2/settings.xml, or IAM through support in the AWS Java SDK.

In order to adhere to the Gradle Repository API, it will need to support using the configured PasswordCredentials. Would it be better to reimplement this code in Gradle natively instead of relying on a 3rd party library?

@john, good point. It should just be another protocol.

One question is what to do about credentials in the repositories { } definition - S3 doesn’t actually use username + password authentication, I don’t think. It would be nice to have some S3 specific credentials DSL that a build author can use in the repository definition. We also want something similar for the sftp protocol.

Re. adding the RepositoryTransport implementation - the idea is definitely to add some public API for this at some point. I’d probably add the S3 protocol and then extract the API later, but we could do things in the other way around.

Re. handling the credentials,if the 3rd party lib works out (and runs on Java 6) then we should go with that. If it’s awkward, then we should just implement it in Gradle.

Re: credentials - are you thinking just a new block under the repository definition:

repositories {

maven {

url ‘s3://mybucket’

s3credentials {

accessKey = ‘myaccesskey’

secretKey = ‘mysecret’

}

}

}

Or some variation like that? Or possible just additional properties under the existing ‘credentials’ DSL? I like something like this, but it doesn’t lend itself to validating that the proper items are configured.

I think the best way is to handle this through documentation (document that ways that credentials for S3 can be provided including setting the username/password to be the accessKey/secretKey).

For sftp, are you thinking supporting Public/Private Key auth?

Would be nice to allow setting the S3 credentials outside of the build file for security purposes, similar to the maven settings.xml file.

There were a few options discussed on the dev mailing list recently. One option is certainly something like a new s3Credentials { } method.

Is there any progress on this? In my case I’d like to be able to push Javadocs to a Maven Site repository (in practice a Webdav server).

We’ve recently added resolution from an AWS S3 repository, and there’s an outstanding pull request to add S3 publishing support, with a Maven Wagon -> Gradle Repository bridge.

The next steps are outlined in https://github.com/gradle/gradle/blob/master/design-docs/repository-transports.md. Because we don’t have a lot of time to dedicate to this, the progress will be largely dependent on community contributions.