Search code examples
gradlekotlinartifactorygradle-plugin

How do I publish Gradle plugins to Artifactory?


I am working with this example Gradle Plugin project: https://github.com/AlainODea/gradle-com.example.hello-plugin

When I run ./gradlew publishToMavenLocal it creates these files in M2_HOME:

  1. com/hello/com.example.hello.gradle.plugin/maven-metadata-local.xml
  2. com/hello/com.example.hello.gradle.plugin/0.1-SNAPSHOT/com.example.hello.gradle.plugin-0.1-SNAPSHOT.pom
  3. com/hello/com.example.hello.gradle.plugin/0.1-SNAPSHOT/maven-metadata-local.xml
  4. com/hello/gradle-com.example.hello-plugin/maven-metadata-local.xml
  5. com/hello/gradle-com.example.hello-plugin/0.1-SNAPSHOT/gradle-com.example.hello-plugin-0.1-SNAPSHOT.jar
  6. com/hello/gradle-com.example.hello-plugin/0.1-SNAPSHOT/gradle-com.example.hello-plugin-0.1-SNAPSHOT.pom
  7. com/hello/gradle-com.example.hello-plugin/0.1-SNAPSHOT/maven-metadata-local.xml

When I run ./gradlew artifactoryPublish it logs:

Deploying artifact: https://artifactory.example.com/artifactory/libs-release-local-maven/com/example/hello/gradle-com.example.hello-plugin/0.1-SNAPSHOT/gradle-com.example.hello-plugin-0.1-SNAPSHOT.jar
Deploying artifact: https://artifactory.example.com/artifactory/libs-release-local-maven/com/example/hello/gradle-com.example.hello-plugin/0.1-SNAPSHOT/gradle-com.example.hello-plugin-0.1-SNAPSHOT.pom
Deploying build descriptor to: https://artifactory.example.com/artifactory/api/build
Build successfully deployed. Browse it in Artifactory under https://artifactory.example.com/artifactory/webapp/builds/gradle-com.example.hello-plugin/1234567890123

Attempting to load the plug-in from another build.gradle:

plugins {
    id 'java'
    id 'com.example.hello' version '0.1-SNAPSHOT'
}

With settings.gradle:

pluginManagement {
    repositories {
        maven {
            url 'https://artifactory.example.com/artifactory/libs-release-local-maven/'
        }
    }
}

Results in this error:

Plugin [id: 'com.example', version: '0.1-SNAPSHOT'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.example.hello:com.example.hello.gradle.plugin:0.1-SNAPSHOT')
  Searched in the following repositories:
    maven(https://artifactory.example.com/artifactory/libs-release-local-maven/)
    Gradle Central Plugin Repository

I'd like to get all of the artifacts that publishToMavenLocal creates to be published to Artifactory when I run artifactoryPublish. I am open to alternatives to artifactoryPublish if it is the wrong tool.

How do I publish Gradle plugins to Artifactory?


Solution

  • Since you have the maven-publish plugin on, the java-gradle-plugin already declares publications for you, so you can remove this explicit publications block from your build:

    publishing {
        publications {
            create<MavenPublication>("mavenJava") {
                from(components["java"])
            }
        }
    }
    

    You can then reference all automatically created publications in your artifactory publish defaults block as follows:

    invokeMethod("publications", publishing.publications.names.toTypedArray())
    

    Why not just publishing.publications.names?:

    • publishing.publications.names has type SortedSet<String>
    • ArtifactoryTask.publications() expects an Object... which is an Object[] really.
    • Calling ArtifactoryTask.publications() with a SortedSet<String> will attempt to add the entire set as if it is a single publication
    • So you need toTypedArray() to make it a Object[] so that the varargs call works

    Here's the complete, corrected artifactory block:

    artifactory {
        setProperty("contextUrl", "https://artifactory.verafin.com/artifactory")
        publish(delegateClosureOf<PublisherConfig> {
            repository(delegateClosureOf<GroovyObject> {
                setProperty("repoKey", "libs-release-local-maven")
            })
            defaults(delegateClosureOf<GroovyObject> {
                invokeMethod("publications", publishing.publications.names.toTypedArray())
            })
        })
    }
    

    Here's a complete adaptation of your build.gradle.kts solving the problem:

    import groovy.lang.GroovyObject
    import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
    import org.jfrog.gradle.plugin.artifactory.dsl.PublisherConfig
    
    buildscript {
        repositories {
            jcenter()
        }
    }
    
    plugins {
        `java-gradle-plugin`
        `maven-publish`
        `kotlin-dsl`
        id("com.jfrog.artifactory") version "4.9.0"
        kotlin("jvm") version "1.3.11"
        id("io.spring.dependency-management") version "1.0.6.RELEASE"
    }
    
    group = "com.example.hello"
    version = "0.1-SNAPSHOT"
    
    gradlePlugin {
        plugins {
            create("helloPlugin") {
                id = "com.example.hello"
                implementationClass = "com.example.HelloPlugin"
            }
        }
    }
    repositories {
        mavenCentral()
    }
    
    dependencyManagement {
        imports {
            mavenBom("org.junit:junit-bom:5.3.2")
        }
    }
    
    dependencies {
        implementation(kotlin("stdlib-jdk8"))
        testImplementation(kotlin("test"))
        testImplementation(kotlin("test-junit5"))
        testImplementation("org.junit:junit-bom:latest.release")
        testImplementation("org.junit.jupiter:junit-jupiter-api")
        testImplementation("com.natpryce:hamkrest:1.7.0.0")
        testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
    }
    
    tasks {
        withType<JavaExec> {
            jvmArgs = listOf("-noverify", "-XX:TieredStopAtLevel=1")
        }
    
        withType<KotlinCompile> {
            val javaVersion = JavaVersion.VERSION_1_8.toString()
            sourceCompatibility = javaVersion
            targetCompatibility = javaVersion
            kotlinOptions {
                apiVersion = "1.3"
                javaParameters = true
                jvmTarget = javaVersion
                languageVersion = "1.3"
            }
        }
    
        withType<Test> {
            @Suppress("UnstableApiUsage")
            useJUnitPlatform()
        }
    }
    
    artifactory {
        publish(delegateClosureOf<PublisherConfig> {
            repository(delegateClosureOf<GroovyObject> {
                setProperty("repoKey", "libs-release-local-maven")
            })
            defaults(delegateClosureOf<GroovyObject> {
                invokeMethod("publications", publishing.publications.names.toTypedArray())
            })
        })
    }
    

    Here's a log showing the successful deployment of the plugin artifact to Artifactory:

    Deploying artifact: https://artifactory.example.com/artifactory/libs-release-local-maven/com/example/hello/gradle-com.example.hello-plugin/0.1-SNAPSHOT/gradle-com.example.hello-plugin-0.1-SNAPSHOT.jar
    Deploying artifact: https://artifactory.example.com/artifactory/libs-release-local-maven/com/example/hello/gradle-com.example.hello-plugin/0.1-SNAPSHOT/gradle-com.example.hello-plugin-0.1-SNAPSHOT.pom
    Deploying artifact: https://artifactory.example.com/artifactory/libs-release-local-maven/com/example/hello/com.example.hello.gradle.plugin/0.1-SNAPSHOT/com.example.hello.gradle.plugin-0.1-SNAPSHOT.pom
    Deploying build descriptor to: https://artifactory.example.com/artifactory/api/build
    Build successfully deployed. Browse it in Artifactory under https://artifactory.example.com/artifactory/webapp/builds/gradle-com.example.hello-plugin/1234567890123