10
votes

Working on an Android library with Gradle (v 1.7) as the building tool, I've used the maven plugin and configured the task uploadArchives to publish both release and debug version of the lib to the local maven repository.
The code below works ok :

// [...]
apply plugin: 'android-library'

// [...] nothing unusual

/*
 * Define name of the apk output file (build/apk/<outputFile>)
 */
    android.libraryVariants.all
    {
        variant ->
        def outputName = "MyModule-${android.defaultConfig.versionName}-${variant.baseName}.aar"
        variant.outputFile = new File("$buildDir/libs", outputName)
     }


/*
 * Publish to maven local repo (older style maven plugin)
 * Used while android plugin is not fixed regarding maven-publish plugin
 * 
 * type command "gradle uploadArchives" to publish the module into the 
 * local .m2 repository
 */
apply plugin: 'maven'

android.libraryVariants.all
{
    variant ->
    // add final apk to the 'archives' configuration
    project.artifacts
    {
        archives variant.outputFile
    }
}

def localRepoPath = "file://" +  new File(
    System.getProperty("user.home"), ".m2/repository").absolutePath

uploadArchives
{   
    repositories.mavenDeployer
    {       
        repository(url: localRepoPath)

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

        pom('debug').groupId = 'com.company'
        pom('release').groupId = 'com.company'
        pom('debug').artifactId = 'id'
        pom('release').artifactId = 'id'
        pom('debug').version = android.defaultConfig.versionName + "d"
        pom('release').version = android.defaultConfig.versionName
        pom.packaging = 'aar'
    }
}
uploadArchives.dependsOn(assemble)

However, when trying to refactor the pom configuration :

uploadArchives
{   
    repositories.mavenDeployer
    {       
        repository(url: localRepoPath)

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

        pom.groupId = 'com.company'
        pom.artifactId = 'id'
        pom('debug').version = android.defaultConfig.versionName + "d"
        pom('release').version = android.defaultConfig.versionName
        pom.packaging = 'aar'
    }
}

artifactId is expanded as the name of the output file, and groupId as the name of the root directory ; thus giving bad paths in the maven repo.

I'd like to know why is that, and maybe if there is a cleaner way to achieve what I need.

2
In my project I had the requirement to rename the output .aar. Therefore, I set the archivesBaseName in build.gradle which is used for the artifactId. Maybe this helps.JJD
Have you figured this out?Yuchen
@YuchenZhong Unfortunately no, as this work was part of a short term internship. I don't know who took charge of the project, and therefore how it has been handled since.mklj

2 Answers

5
votes

As a reference, this is how we upload multiple APKs. It may not be exactly what you needed since we are uploading multiple APKs after APK splits, while you were trying to upload multiple APKs from different build types (debug & release). But in theory, they should be the same.

//declare some Variables for later use
def projectName = "ProjectName"
def versionString = "1.0.0"
def baseVersionCode = 1

// Values based on https://developer.android.com/ndk/guides/abis.html#sa
ext.abiCodes = ['armeabi-v7a': 1,
                'arm64-v8a'  : 2,
                'x86'        : 3,
                'x86_64'     : 4]

// collect artifacts, important for the `uploadArchives` to work
artifacts {
  if (new File('app/build/outputs/apk').exists()) {
    new File('app/build/outputs/apk').eachFile() { file ->
      if (file.toString().contains("productionRelease")) {
        archives file: file
      }
    }
  }
}

uploadArchives {
  repositories {
    mavenDeployer {
      repository(url: "http://...")

      project.ext.abiCodes.values().each{ abiVersionCode ->
        def version = "${versionString}.${baseVersionCode + abiVersionCode}"
        addFilter(version) { artifact, file -> artifact.name.contains(version) }

        pom(version).artifactId = projectName.toLowerCase()
        pom(version).groupId = 'com.yourcompanyname'
        pom(version).version = version
      }
    }
  }
}

android {
  defaultPublishConfig "productionRelease"

  buildTypes {
      productionRelease {
          minifyEnabled false
          zipAlignEnabled true
          //...more Config like proguard or signing
      }
  }

  applicationVariants.all { variant ->
    variant.outputs.each { output ->
      def abiName = output.getFilter(com.android.build.OutputFile.ABI)
      def abiVersionCode = project.ext.abiCodes.get(abiName)    
      output.versionCodeOverride = variant.versionCode + abiVersionCode
      output.versionNameOverride = "$versionString (${output.versionCodeOverride})"
      def apkName = "$projectName-${variant.name}-v${versionString}.${output.versionCodeOverride}.apk"
      output.outputFile = new File(output.outputFile.parent, apkName)
    }
  }
0
votes

You need(ed) to set the filter name for the groupId and artifactId the same as you have for version

pom('debug').groupId = 'com.company'
pom('release').groupId = 'com.company'
pom('debug').artifactId = 'id'
pom('release').artifactId = 'id'
pom('debug').version = android.defaultConfig.versionName + "d"
pom('release').version = android.defaultConfig.versionName

Im surprised you get away with the version name suffix, as its not semver.