5

I'm trying to configure an Android library project to deploy multiple artifacts to a locally hosted Maven repository. I've gotten far enough such that both artifacts have their own POM generated, and it gets deployed properly to the repo, with the following script:

android {
    // Publish both debug and release
    publishNonDefault true
}

uploadArchives {
    repositories.mavenDeployer {
        def majorVersion = 1
        def minorVersion = 1
        def buildVersion = project.properties.get('RELEASE', '0').toInteger()

        addFilter('release') { artifact, file ->
            file.name.contains('release')
        }

        addFilter('debug') { artifact, file ->
            file.name.contains('debug')
        }

        activePomFilters.each { filter ->
            pom(filter.name) {
                groupId = 'com.redacted'
                artifactId = 'redacted'
                packaging = 'aar'
                version = "${majorVersion}.${minorVersion}.${buildVersion}"

                if (!project.hasProperty('RELEASE')) {
                    version += "-SNAPSHOT"
                }

                if (filter.name == 'debug') {
                    artifactId += '-debug'
                }
            }
        }
    }
}

The expected delivery is:

com/
    redacted/
        redacted/
            1.1.0-SNAPSHOT/
        redacted-debug/
            1.1.0-SNAPSHOT/

Which happens as expected, but it seems to publish the artifacts with an additional suffix (which breaks the dependency discovery), and I cannot figure out where it is coming from, or how to change it. What I see is:

com/redacted/redacted/1.1.0-SNAPSHOT/
    redacted-1.1.0-20150717.213849-1-release.aar
    redacted-1.1.0-20150717.213849-1-release.aar.md5
    redacted-1.1.0-20150717.213849-1-release.aar.sha1
    redacted-1.1.0-20150717.213849-1.pom
    redacted-1.1.0-20150717.213849-1.pom.md5
    redacted-1.1.0-20150717.213849-1.pom.sha1

For some reason, it's appending the date, as well as a -release suffix to only the AAR-related files, but not the POM files. If I manually rename these files, everything works as expected. For example, this is what I expect to be output:

com/redacted/redacted/1.1.0-SNAPSHOT/
    redacted-1.1.0-20150717.213849-1.aar
    redacted-1.1.0-20150717.213849-1.aar.md5
    redacted-1.1.0-20150717.213849-1.aar.sha1
    redacted-1.1.0-20150717.213849-1.pom
    redacted-1.1.0-20150717.213849-1.pom.md5
    redacted-1.1.0-20150717.213849-1.pom.sha1

How can I change how these files are delivered?

Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
  • Re: "it's appending the date, as well as a -release suffix to only the AAR-related files, but not the POM files"; Are you not wanting the date included either, and is the debug version exhibiting the same behavior? – l'L'l Jul 17 '15 at 23:10
  • For the first, I don't care either way about the date (found out that was due to the uniqueVersion flag for snapshot builds) -- I'm okay with any output as long as it's consistent. :) And yes, this happens for debug builds as well. Doing some more logging, I believe this is due to the classifier being set on the artifact, but I'm still trying to find any way to change this (since the artifacts are auto-generated). – Kevin Coppock Jul 17 '15 at 23:13
  • I think most of the attributes you can adjust within the pom.xml or create a function to help handle things; afaik support for uniqueVersion is not supported in maven-3. Without knowing more about your build configuration I would say some of [these solutions](http://stackoverflow.com/questions/4275466/how-do-you-deal-with-maven-3-timestamped-snapshots-efficiently) might be helpful or some of the info from them. – l'L'l Jul 18 '15 at 01:16
  • can you check this? http://stackoverflow.com/questions/275555/maven-snapshot-repository-vs-release-repository – Radhakrishna Sharma Gorenta Jul 29 '15 at 13:21
  • @RKSharma Unfortunately this isn't about snapshot vs release. I need to deliver multiple builds to the release repository (one just happens to be named 'debug' and the other 'release', but they both need to be accessible). – Kevin Coppock Jul 29 '15 at 15:32
  • Can you please look into this problem I could not solve this https://stackoverflow.com/questions/56513672/errorunable-to-resolve-dependency-for-appdebugandroidtest-compileclasspath @kcoppock – Pie Jun 09 '19 at 13:59

1 Answers1

3

What you are running in to is this (emphasis mine):

Important: When enabling publishing of non default, the Maven publishing plugin will publish these additional variants as extra packages (with classifier). This means that this is not really compatible with publishing to a maven repository. You should either publish a single variant to a repository OR enable all config publishing for inter-project dependencies.

See the documentation: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

The suffixes release and debug that you see are the classifiers introduced by enabling publishing of non-default artifacts. The <artifact> elements in build/ivy.xml, which is used as the basis for the Maven configuration, contain these classifiers.

Iterating over the artifacts in the configurations and removing the classifier does not work. Although setting the classifier is allowed, its original value is kept.

But what does work is wrapping the original artifacts. The wrapper will always return null for a classifier. This does result in the release and debug artifact having the same fully-qualified ID (= name + classifier), which results in only one artifact being published. This can be fixed by using a different name for debug artifacts:

class UnclassifiedPublishArtifact implements PublishArtifact {

    private PublishArtifact delegatee;
    private boolean isDebugArtifact;

    UnclassifiedPublishArtifact(PublishArtifact delegatee, isDebugArtifact) {
        this.delegatee = delegatee
        this.isDebugArtifact = isDebugArtifact
    }

    @Override
    String getName() {
        return delegatee.name + (isDebugArtifact ? '-debug' : '')
    }

    @Override
    String getExtension() {
        return delegatee.extension
    }

    @Override
    String getType() {
        return delegatee.type
    }

    @Override
    String getClassifier() {
        return null
    }

    @Override
    File getFile() {
        return delegatee.file
    }

    @Override
    Date getDate() {
        return delegatee.date
    }

    @Override
    TaskDependency getBuildDependencies() {
        return delegatee.buildDependencies
    }
}

project.afterEvaluate {
    configurations.each { configuration ->
        def artifacts = configuration.artifacts
        if (!artifacts.isEmpty()) {
            def unclassifiedArtifacts = []
            unclassifiedArtifacts.addAll(artifacts.collect { classifiedArtifact ->
                new UnclassifiedPublishArtifact(classifiedArtifact, classifiedArtifact.classifier == 'debug')
            })
            artifacts.clear()
            artifacts.addAll(unclassifiedArtifacts)
        }
    }
}

I can't quite understand from the documentation what the consequences are for project dependencies, so you should check if these still work.

Johan Stuyts
  • 3,607
  • 1
  • 18
  • 21
  • This makes total sense, especially along with that line from the documentation. I think this solution would work for the naming, but as you mentioned will have some issues with dependencies. I've ended up just modifying the library to avoid the need to publish two variants (which simplifies things for me, but doesn't really answer the original question). I'll give this a try sometime soon and see what happens. Thanks for the clarification! – Kevin Coppock Jul 30 '15 at 01:20