Using publish-plugin to publish a plugin not created by jar task


(Chris Rankin) #1

Hi,

I have needed to shade my Gradle plugin so that the final artifact is being created by my ShadowJar task instead of the jar task. (My plugin is not a “fat jar”. I went to considerable effort to ensure that only a particular dependency was being shaded, and that the rest - including gradleApi and localGroovy are still transitive dependencies.)

My next task is to publish this plugin to the Gradle Plugin Portal using com.gradle.plugin-publish. However, I can’t see any way of telling the publish-plugin which jar it should be publishing. Does it publish the output from all jar tasks, please? Or just the artifact without a classifier? Or is there an extension to configure all this behaviour somewhere?

Thanks for any help here?
Chris


(Tom Dunstan) #2

Hi Chris

The plugin will publish a jar found in the archives configuration. By default this is the jar produced by the default jar task, but can be changed by clearing out the archives artifacts and adding back in what you would like to publish.

E.g.:

configurations.archives.artifacts.clear()
artifacts {
    add("archives", shadowJar)
}

will publish the jar produced by the shadowJar task.

Hope that helps.

Tom


(Chris Rankin) #3

Hi, and thanks! Yes, that’s a big help.

Cheers,
Chris


(Eric Wendelin) #4

Hey Tom, is this missing from our docs? Should I file an issue?


(Chris Rankin) #5

Hi,

I did check the documentation before posting here, and didn’t find this information. It’s certainly not mentioned in the Full Example.

Cheers,
Chris


(Tom Dunstan) #6

Hi Eric! I don’t think it’s documented, so sounds good!

Cheers

Tom


(Chris Rankin) #7

Hi,
I’ve been experimenting with this change via the --dry-run options, and I’ve noticed that whereas by default the publishPlugins task will execute:

jar
shadowJar
publishPluginJar
javadoc
publishPluginJavaDocsJar
publishPlugins

when I add shadowJar to configuration.archives it becomes only:

jar
shadowJar
publishPlugins

So then I add sourceJar and javadocJar to the archives too, and this still becomes only:

javadoc
javadocJar
jar
shadowJar
sourceJar
publishPlugins

Should I be concerned by the loss of the publishPluginJar and publishPluginJavaDocsJar tasks please?

Thanks,
Chris


(Tom Dunstan) #8

Hi Chris

As long as you are publishing the artifacts that you want to be published you’re fine.

Regards

Tom


(Chris Rankin) #9

Hi,

I’ve been testing this, and it has indeed published my plugin and its sources into the Portal. However, the POM it has created isn’t the same as the one created by the maven-publish plugin. The Portal’s one also contains a runtime dependency on the jar that I have shaded, and so causes resolution errors when I try to use the plugin in projects.

Specifically, my build.gradle file contains

dependencies {
    shadow gradleApi()
    shadow localGroovy()
    shadow "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    shadow "org.ow2.asm:asm:$asm_version"
    implementation configurations.shadow
    implementation project(':internal-jar-project')
    ...
}

And for maven-publish, I did this:

artifact shadowJar
pom.withXml {
    def dependenciesNode = asNode().appendNode('dependencies')
    configurations.shadow.resolvedConfiguration.firstLevelModuleDependencies.forEach {
        def dependency = dependenciesNode.appendNode('dependency')
        dependency.appendNode('groupId', it.moduleGroup)
        dependency.appendNode('artifactId', it.moduleName)
        dependency.appendNode('version', it.moduleVersion)
        dependency.appendNode('scope', 'runtime')
     }
}

However, the publish-plugin seems to have ignored all of this and used the full set of the implementation dependencies instead, including the unwanted internal-jar-project.jar.

Can you help me fix the published POM dependencies please?
Thanks,
Chris

Edit: FWIW, I’ve now modified my project better to leverage the shadow plugin functionality, where shadow here is an extension object:

publications {
    shadow(MavenPublication) { publication ->
        project.shadow.component(publication)
    }
}