Basic use case for publishing to Ivy?


(Ryan Nelson) #1

I need a little help with publishing to Ivy. The Gradle docs on this are pretty brief.

Our current Ivy repository is just a web-friendly directory fronted by a Tomcat server. For publishing, we’ve configured it with an FTP resolver (we’ve also used SSH in the past), which is how our existing Ant builds publish to it. I tried using ftp intially, but got this error message: “You may only specify ‘file’, ‘http’ and ‘https’ urls for an ivy repository.”

I enabled WebDAV on Tomcat, and tried it again with “http”, but ran into this problem, which appears to be a “known” unsupported feature. So my question is, how does Gradle expect to publish out-of-the-box to Ivy? Is there some way I should configure my web server or repo to be more Gradle-friendly? I assume there’s some common use-case that works that I’m missing.

PS. I know about Artifactory, but at the moment that seems like overkill. We have a repo that’s working fine, and I don’t see a need to add a new 3rd party just to use a new build tool.


#2

Publishing to an HTTP Ivy repository currently assumes a ‘smart’ repository that will create intermediate directories on PUT. There is not yet built-in support for publishing via WebDAV, (S)FTP or any other protocol besides ‘file’.

You should be able to work around this limitation by configuring an Ivy DependencyResolver directly. An example of how to do this for an SFTP resolver is:

repositories {
    add(new org.apache.ivy.plugins.resolver.SFTPResolver()) {
        name = "sftprepo"
        host = "${server.hostAddress}"
        port = ${server.port}
        user = "simple"
        userPassword = "password"
        addIvyPattern "repos/libs/[organization]/[module]/[revision]/ivy-[revision].xml"
        addArtifactPattern "repos/libs/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
    }
}

For details on what ivy resolvers are available and how they can be configured, check out the ivy docs.


(Ryan Nelson) #3

Thanks, Daz. That worked great.


(Ryan Nelson) #4

I have a new question about this along the lines of the new ivy-publish plugin. The docs state:

“At this time, it is not possible to create arbitrary publication objects. When the “ivy-publish” plugin is applied it creates a single publication named ‘ivy’. This publication will publish all of artifacts of all of the project’s visible configurations, and any configurations that they extend from.”

So does this mean I can no longer add a custom resolver, as Daz suggests here? I tried this:

publishing {
 publications {
  repositories {
   add(new org.apache.ivy.plugins.resolver.SFTPResolver()) {
    name = "sftprepo"
    host = "${server.hostAddress}"
    port = ${server.port}
    user = "simple"
    userPassword = "password"
    addIvyPattern "repos/libs/[organization]/[module]/[revision]/ivy-[revision].xml"
    addArtifactPattern "repos/libs/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
   }
  }
 }
}

Gradle does not seem to recognize this and doesn’t publish to it. I ask this because I need the new ivy-publish functionality due to GRADLE-2575. Is there a best-of-both-worlds way to do this?

Thanks, Ryan


#5

The docs you mention relate to arbitrary publications, not repositories. But nope, we don’t plan for the new publication plugins to support native ivy resolvers. They may do so by accident, but there is certainly no guarantee of this behaviour, and it may stop working in the future.

We do have plans to add support for other transports (such as SFTP and WebDav) but they are not available yet. Unfortunately this means that you can’t use the new publishing features to publish via sFTP.


(Ryan Nelson) #6

Are there any updates for this use case? I’m boxed in by my inability to include WARs as a dependency (due to GRADLE-2575), but cannot publish via SFTP using the new ivy-publish plugin. As far as I can tell there is no workaround for this.


#7

The core Gradle team is currently working on other priorities, which means that the new publishing stuff is not progressing rapidly.


(Ryan Nelson) #8

Thanks for the update, Daz. I understand that there are other priorities.

I have an interim solution by locally mapping the Ivy drive to my Jenkins box. This is a poor solution, however, because we build using Jenkins slaves, and each (new) slave has to be configured this way.

Just to be clear what I need … maybe you can suggest some other way to do it. Can I either:

(1) Modify the configuration of the artifact in ivy.xml before it’s published using the traditional Gradle method (uploadArchives).

OR

(2) Instruct my dependencies to look for an Ivy configuration other than “runtime” when downloading a war.

Any way to do either of those with the code as it stands today?

FYI, the problem is a result of this problem:

http://forums.gradle.org/gradle/topics/uploading_war_archive_creates_an_ivy_xml_with_a_jar_runtime_artifact