Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle and Android : pom configuration with multiple Maven artifacts publication

Tags:

android

gradle

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.

like image 799
mklj Avatar asked Aug 23 '13 10:08

mklj


1 Answers

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)
    }
  }
like image 184
Yuchen Avatar answered Sep 22 '22 00:09

Yuchen