Search code examples
androidgradlejarartifactoryaar

Gradle upload sources.jar and aar to jfrog artifactory. artifactoryPublish will generate two pom-default.xml, it will pushlish one of them randomly


i have a android project with kotlin, it includes a library module, i would like to upload this library to jfrog artifactory. i have uploaded an aar file to artifactory successfully. now i would like to upload library-sources.jar to artifactory. But when i execute gradle task artifactoryPublish, it will generate two pom-default.xml files, and publish one of them randomly.

Project build.gradle

    buildscript {
      ext.kotlin_version = "1.4.30"
      repositories {
        maven {
            url "http://localhost:8081/artifactory/my_virtual_repo/"
        }
      }
      dependencies {
        classpath "com.android.tools.build:gradle:4.1.2"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

        classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.15.2"
      }
    }
    allprojects {
      repositories {
          maven {
              url "http://localhost:8081/artifactory/my_virtual_repo/"
          }
      }
    }

library build.gradle

......

apply plugin: "com.jfrog.artifactory"
apply plugin: "maven-publish"

def MAVEN_LOCAL_PATH = "http://localhost:8081/artifactory"
def GROUP_ID = "com.xxx.artifactlib"
def ARTIFACT_ID = "artifactlib"
def VERSION_NAME = "1.3"

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

task sourcesJar(type: Jar) {
    group = 'jar'
    from android.sourceSets.main.java.srcDirs
    classifier = 'sources'
}

artifacts {
    archives sourcesJar
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId = GROUP_ID
            artifactId = ARTIFACT_ID
            version = VERSION_NAME
            artifact tasks.sourcesJar
            pom.withXml {
                def dependencies = asNode().appendNode("dependencies")
                configurations.api.allDependencies.each {
                    def dependency = dependencies.appendNode("dependency")
                    print(it.group)
                    dependency.appendNode("groupId", it.group)
                    dependency.appendNode("artifactId", it.name)
                    dependency.appendNode("version", it.version)
                }
            }
        }
    }

    publications {
        aar_pub(MavenPublication) {
            groupId = GROUP_ID
            artifactId = ARTIFACT_ID
            version = VERSION_NAME

            artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")

            pom.withXml {
                def dependencies = asNode().appendNode("dependencies")
                configurations.api.allDependencies.each {
                    def dependency = dependencies.appendNode("dependency")
                    dependency.appendNode("groupId", it.group)
                    dependency.appendNode("artifactId", it.name)
                    dependency.appendNode("version", it.version)
                }
            }
        }
    }
}

artifactoryPublish {
    contextUrl = MAVEN_LOCAL_PATH
    publications("mavenJava", "aar_pub")

    clientConfig.publisher.repoKey = "my_local_repo"
    clientConfig.publisher.username = "xxx"
    clientConfig.publisher.password = "xxx"
}
......

pom-default.xml of aar_pub

<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.xxx.artifactlib</groupId>
  <artifactId>artifactlib</artifactId>
  <version>1.3</version>
  <packaging>aar</packaging>
  <dependencies/>
</project>

pom-default.xml of mavenJava

<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.xxx.artifactlib</groupId>
  <artifactId>artifactlib</artifactId>
  <version>1.3</version>
  <packaging>pom</packaging>
  <dependencies/>
</project>

how to upload a given pom file(like pom-default of aar_pub)? thank you.


Solution

  • A single Publication contains all artifacts for a single release.

    You defined two identical Publications (well, both have the aar and pom, only one of them has sources JAR) and are trying to upload both of them to the same coordinates at the same time.

    • Don't define one Publication for each of aar, jar, pom, whatever.
    • Merge all articacts into a single Publication.

    In your case:

    publishing {
        publications {
            mavenJava(MavenPublication) {
                groupId = GROUP_ID
                artifactId = ARTIFACT_ID
                version = VERSION_NAME
    
                artifact tasks.sourcesJar
                artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
    
                pom.withXml {
                    def dependencies = asNode().appendNode("dependencies")
                    configurations.api.allDependencies.each {
                        def dependency = dependencies.appendNode("dependency")
                        print(it.group)
                        dependency.appendNode("groupId", it.group)
                        dependency.appendNode("artifactId", it.name)
                        dependency.appendNode("version", it.version)
                    }
                }
            }
        }
    }
    
    artifactoryPublish {
        publications("mavenJava")
    }
    

    Potential issues

    There's no formal relationship between the publication and whatever task that produces the AAR. You'll have to manually execute assemble before publish. (And remember to do that every time.)

    Consider migrating to Android Gradle Plugin 3.6.0 or newer which supports maven-publish plugin natively. See documentation. This has the following benefits:

    • You don't have to manually write dependencies to POM.
    • Whenever AAR would change the publication would pick it up automatically. (You don't publish nothing after a clean build. You don't have to manually execute assemble before publish.)
    • You still have to handle sources JAR until support for withSourcesJar() is added to AGP. See issue.

    In your case it would look something like this:

    // Because the components are created only during the afterEvaluate phase, you must
    // configure your publications using the afterEvaluate() lifecycle method.
    afterEvaluate {
        publishing {
            publications {
                mavenJava(MavenPublication) {
                    // Applies the component for the release build variant.
                    from components.release
                    artifact tasks.sourcesJar
    
                    groupId = GROUP_ID
                    artifactId = ARTIFACT_ID
                    version = VERSION_NAME
                }
            }
        }
    
        artifactoryPublish {
            // ...
        }
    }