2015-12-17 8 views
28

Ho giustamente aggiunto flavors (o productFlavors se lo si desidera) al mio progetto.Pubblicazione della libreria Android (aar) su Bintray con i gusti scelti

Il fatto è che quando pubblico la libreria su bintray, tutti gli aromi sono caricati (che è ottimo), ma non sono in grado Il plugin utilizzato è quello ufficiale here.

AAR caricato:

androidsdk-0.0.4-fullRelease.aar 
androidsdk-0.0.4-fullDebug.aar 
androidsdk-0.0.4-lightRelease.aar 
androidsdk-0.0.4-lightDebug.aar 

Come annotato, il fullRelease è chiamato come il classifier, vedi doc chapter 23.4.1.3.

Sto cercando una soluzione per scegliere quali sapori che voglio caricare.

Ho già guardato esempi bintray (here e here) e this, con anche altri esempi, ma sono ancora bloccati.

Ecco il mio script corrente:

apply plugin: 'com.android.library' 
apply plugin: 'com.github.dcendents.android-maven' 
apply plugin: 'com.jfrog.bintray' 

buildscript { 
    repositories { 
     jcenter() 
    } 
} 

android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.1" 

    defaultConfig { 
     minSdkVersion 9 
     targetSdkVersion 23 
     versionCode 64 
     versionName "0.0.4" 
    } 

    publishNonDefault true 

    productFlavors { 
     full { 
     } 
     light { 
     } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    compile 'com.android.support:appcompat-v7:23.1.1' 
    compile 'com.android.support:recyclerview-v7:23.1.1' 
    fullCompile 'com.squareup.picasso:picasso:2.5.0' 
} 

version = android.defaultConfig.versionName 

uploadArchives { 
    repositories.mavenDeployer { 
     pom.project { 

      packaging 'aar' 

     } 
    } 
} 

//////////////////////////////// 
// Bintray Upload configuration 

Properties properties = new Properties() 
properties.load(project.rootProject.file('local.properties').newDataInputStream()) 

bintray { 
    user = properties.getProperty("bintray.user") 
    key = properties.getProperty("bintray.apikey") 

    configurations = ['archives'] 
    pkg { 
     repo = "MyRepo" // repo name 
     userOrg = 'hugo' 
     name = "AndroidSDK" // Package name 
     websiteUrl = siteUrl 
     vcsUrl = gitUrl 
     publish = true 
    } 
} 

Per importare la libreria Attualmente sto usando questo:

compile ('com.example.lib:sdk:0.0.8:[email protected]') { 
    transitive = true; 
} 
+0

È necessario aggiornare ogni sapore come un artefatto diverso. –

+0

@GabrieleMariotti come si può specificare l'aroma nelle 'configurazioni 'di bintray? –

+0

Non l'ho provato prima. Ma devi specificare una parte delle configurazioni di bintray all'interno del flavor block per assegnare il nome del manufatto. –

risposta

8

ho affrontato la stessa sfida, ed ecco il meglio che potessi fare ancora:

Utilizzando mavenPublications e la Gradle maven-publish plug lungo il plugin bintray, è possibile pubblicare qualsiasi variante di mavenLocal e bintray.

Ecco il file publish.gradle applico alla fine di moduli di libreria di tutto il mio progetto voglio pubblicare:

def pomConfig = { 
    licenses { 
     license { 
      name 'The Apache Software License, Version 2.0' 
      url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 
     } 
    } 
    developers { 
     developer { 
      id 'louiscad' 
      name 'Louis CAD' 
      email '[email protected]' 
     } 
    } 
    scm { 
     connection 'https://github.com/LouisCAD/Splitties.git' 
     developerConnection 'https://github.com/LouisCAD/Splitties.git' 
     url siteUrl 
    } 
} 

def publicationNames = [] 
publishing.publications { 
    android.libraryVariants.all { variant -> 
     if (variant.buildType.name == "debug") return // Prevents publishing debug library 

     def flavored = !variant.flavorName.isEmpty() 

     /** 
     * Translates "_" in flavor names to "-" for artifactIds, because "-" in flavor name is an 
     * illegal character, but is well used in artifactId names. 
     */ 
     def variantArtifactId = flavored ? variant.flavorName.replace('_', '-') : project.name 

     /** 
     * If the javadoc destinationDir wasn't changed per flavor, the libraryVariants would 
     * overwrite the javaDoc as all variants would write in the same directory 
     * before the last javadoc jar would have been built, which would cause the last javadoc 
     * jar to include classes from other flavors that it doesn't include. 
     * 
     * Yes, tricky. 
     * 
     * Note that "${buildDir}/docs/javadoc" is the default javadoc destinationDir. 
     */ 
     def javaDocDestDir = file("${buildDir}/docs/javadoc ${flavored ? variantArtifactId : ""}") 

     /** 
     * Includes 
     */ 
     def sourceDirs = variant.sourceSets.collect { 
      it.javaDirectories // Also includes kotlin sources if any. 
     } 
     def javadoc = task("${variant.name}Javadoc", type: Javadoc) { 
      description "Generates Javadoc for ${variant.name}." 
      source = variant.javaCompile.source // Yes, javaCompile is deprecated, 
      // but I didn't find any working alternative. Please, tweet @Louis_CAD if you find one. 
      destinationDir = javaDocDestDir 
      classpath += files(android.getBootClasspath().join(File.pathSeparator)) 
      classpath += files(configurations.compile) 
      options.links("http://docs.oracle.com/javase/7/docs/api/"); 
      options.links("http://d.android.com/reference/"); 
      exclude '**/BuildConfig.java' 
      exclude '**/R.java' 
      failOnError false 
     } 
     def javadocJar = task("${variant.name}JavadocJar", type: Jar, dependsOn: javadoc) { 
      description "Puts Javadoc for ${variant.name} in a jar." 
      classifier = 'javadoc' 
      from javadoc.destinationDir 
     } 
     def sourcesJar = task("${variant.name}SourcesJar", type: Jar) { 
      description "Puts sources for ${variant.name} in a jar." 
      from sourceDirs 
      classifier = 'sources' 
     } 

     def publicationName = "splitties${variant.name.capitalize()}Library" 
     publicationNames.add(publicationName) 

     "$publicationName"(MavenPublication) { 
      artifactId variantArtifactId 
      group groupId 
      version libraryVersion 

      artifact variant.outputs[0].packageLibrary // This is the aar library 
      artifact sourcesJar 
      artifact javadocJar 

      pom { 
       packaging 'aar' 
       withXml { 
        def root = asNode() 
        root.appendNode("name", 'Splitties') 
        root.appendNode("url", siteUrl) 
        root.children().last() + pomConfig 
        def depsNode = root["dependencies"][0] ?: root.appendNode("dependencies") 

        def addDep = { 
         if (it.group == null) return // Avoid empty dependency nodes 
         def dependencyNode = depsNode.appendNode('dependency') 
         dependencyNode.appendNode('groupId', it.group) 
         dependencyNode.appendNode('artifactId', it.name) 
         dependencyNode.appendNode('version', it.version) 
         if (it.hasProperty('optional') && it.optional) { 
          dependencyNode.appendNode('optional', 'true') 
         } 
        } 

        // Add deps that everyone has 
        configurations.compile.allDependencies.each addDep 
        // Add flavor specific deps 
        if (flavored) { 
         configurations["${variant.flavorName}Compile"].allDependencies.each addDep 
        } 
        // NOTE: This library doesn't use builtTypes specific dependencies, so no need to add them. 
       } 
      } 
     } 
    } 
} 

group = groupId 
version = libraryVersion 

afterEvaluate { 
    bintray { 
     user = bintray_user 
     key = bintray_api_key 
     publications = publicationNames 

     override = true 
     pkg { 
      repo = 'splitties' 
      name = project.name 
      desc = libraryDesc 
      websiteUrl = siteUrl 
      issueTrackerUrl = 'https://github.com/LouisCAD/Splitties/issues' 
      vcsUrl = gitUrl 
      licenses = ['Apache-2.0'] 
      labels = ['aar', 'android'] 
      publicDownloadNumbers = true 
      githubRepo = 'LouisCAD/Splitties' 
     } 
    } 
} 

Affinché ciò funzioni, ho bisogno di avere le proprietà bintray_user e bintray_api_key definiti. Io personalmente appena li ho nella mia ~/.gradle/gradle.properties file in questo modo:

bintray_user=my_bintray_user_name 
bintray_api_key=my_private_bintray_api_key 

Ho anche bisogno di definire le seguenti proprietà ext ho usato nel file publish.gradle in build.gradle fascicolo di mio progetto principale:

allprojects { 
    ... 
    ext { 
     ... 
     // Libraries 
     groupId = "xyz.louiscad.splitties" 
     libraryVersion = "1.2.1" 
     siteUrl = 'https://github.com/LouisCAD/Splitties' 
     gitUrl = 'https://github.com/LouisCAD/Splitties.git' 
    } 
} 

Ed ora , Posso finalmente usarlo nel mio modulo di libreria Android, dove ho più productFlavors. Ecco un frammento da build.gradle file di un modulo di libreria pubblicabile:

plugins { 
    id "com.jfrog.bintray" version "1.7.3" // Enables publishing to bintray 
    id "com.github.dcendents.android-maven" version "1.5" // Allows aar in mavenPublications 
} 

apply plugin: 'com.android.library' 
apply plugin: 'maven-publish' // Used for mavenPublications 

android { 
    ... 
    defaultPublishConfig "myLibraryDebug" // Allows using this library in another 
    // module in this project without publishing to mavenLocal or Bintray. 
    // Useful for debug purposes, or for your library's sample app. 
    defaultConfig { 
     ... 
     versionName libraryVersion 
     ... 
    } 
    ... 
    productFlavors { 
     myLibrary 
     myLibrary_logged // Here, the "_" will be replaced "-" in artifactId when publishing. 
     myOtherLibraryFlavor 
    } 
    ... 
} 

dependencies { 
    ... 
    // Timber, a log utility. 
    myLibrary_loggedCompile "com.jakewharton.timber:timber:${timberVersion}"; // Just an example 
} 
... 

ext { 
    libraryDesc = "Delegates for kotlin on android that check UI thread" 
} 

apply from: '../publish.gradle' // Makes this library publishable 

Quando hai tutto questo impostato correttamente, con il nome della vostra libreria, invece di mine's (che si può usare come esempio), si può provare l'editoria una versione della libreria aromatizzata cercando di pubblicare prima su mavenLocal. Per fare ciò, eseguire questo comando:

myLibrary $ ../gradlew publishToMavenLocal 

si può quindi provare ad aggiungere mavenLocal nei repository della vostra app (example here) e provare ad aggiungere la libreria come una dipendenza (artifactId dovrebbe essere il nome di sapore, con "_" sostituito con " - ") e costruendolo. Puoi anche controllare con il tuo file explorer (usa cmd + shift + G su Mac in Finder per accedere alla cartella nascosta) la directory ~/.m2 e cercare la tua libreria.

Quando è il momento di pubblicare a bintray/jcenter, è sufficiente eseguire questo comando:

myLibrary $ ../gradlew bintrayUpload 

Importante:

Prima di pubblicare la vostra libreria per mavenLocal, Bintray o altro repository Maven , di solito vuoi provare la tua libreria con un'app campione che utilizza la libreria. Questa app di esempio, che dovrebbe essere un altro modulo nello stesso progetto, deve solo avere la dipendenza del progetto, che dovrebbe assomigliare a questa: compile project(':myLibrary'). Tuttavia, dal momento che la tua libreria ha più productFlavors, ti consigliamo di testarli tutti.Purtroppo, al momento non è possibile specificare quale configurazione si desidera utilizzare dal file build.gradle dell'app della tua app campione (a meno che non si usi publishNonDefault true nel file build.gradle della libreria, che interrompe le pubblicazioni di maven e bintray), ma è possibile specificare la configurazione predefinita (ad esempio buildVariant) nel modulo della libreria in quanto tale: defaultPublishConfig "myLibraryDebug" nella chiusura android. Puoi vedere le varianti di build disponibili per la tua libreria nello strumento "Build Variants" Windows in Android Studio.

Sentitevi liberi di esplorare my library "Splitties" here se avete bisogno di un esempio. Il modulo aromatizzato è denominato concurrency, ma io uso il mio script anche per i moduli di libreria non formattati e l'ho testato in modo approfondito su tutti i moduli di libreria del mio progetto.

Puoi contattarmi se hai bisogno di aiuto per configurarlo.

+0

come una nota sulla sezione inferiore, è possibile ottenere l'applicazione che consuma per allinearsi alla configurazione corretta specificando missingDimensionStrategy come "missingDimensionStrategy" brand "," XXX ' missingDimensionStrategy' environment ',' ZZZ'' – MrTristan

3

non l'ho provato così sarò cancellare la risposta, se esso doesn risolve il problema

Si dovrebbe postare un artefatto diverso per ogni sapore (o costruire la variante se si preferisce).
In questo modo si avranno in jcenter x artefacts, ognuno con un file pom.

Qualcosa di simile:

groupId 
|--library-full 
|----.pom 
|----.aar 
|--library-light 
|----.pom 
|----.aar 

Nel file di livello superiore è possibile definire

allprojects { 
    repositories { 
     jcenter() 
    } 

    project.ext { 
     groupId="xxx" 
     libraryName = "" 
     ...... 
    } 
} 

Poi, nel tuo modulo di libreria:

productFlavors { 
     full { 
      project.ext.set("libraryName", "library-full"); 
     } 
     light { 
      project.ext.set("libraryName", "library-light"); 
     } 
} 

bintray { 

    //... 
    pkg { 
     //...Do the same for other variables 
     name = project.ext.libraryName 
    } 
} 

Infine assicurarsi di pubblicare solo il rilascio tipo di build (perché anche la versione di debug?)

+0

ok, con questo sono in grado di caricare i diversi sapori in diversi pacchetti di bintray. Ma il classificatore è ancora qui e ogni pacchetto ha tutto il sapore. –

+0

Scusa ma non so a cosa ti riferisci con il classificatore. Sto verificando il file pom nel jcenter e dovresti avere groupId/artifactId per identificare una libreria. –

+0

sì, ho questo ma ho il classificatore è anche qui, quindi ho sia 'androidsdk-0.0.4-lightDebug.aar' e' androidsdk-0.0.4-lightDebug.aar' su ogni pacchetto. Quindi ci sono attualmente due problemi con questo. Il classificatore è 'lightDebug' per esempio. –

1

Sembra che tu non voglia il classificatore nel nome del file. Sembra che il classificatore sia uguale al nome del file della libreria generato. Hai provato a dare loro lo stesso nome di file ma li hai esportati per separare le directory? E.g. nel campo di applicazione Android:

libraryVariants.all { variant -> 
    variant.outputs.each { output -> 
     def outputFile = output.outputFile 
     if (outputFile != null && outputFile.name.endsWith('.aar')) { 
      def fileName = "same_name-${version}.aar" 
      output.outputFile = new File(outputFile.parent+"/${archivesBaseName}", fileName) 
     } 
    } 
} 
+0

che mi permettono di cambiare il nome del file .aar (da 'build/outputs/aar/androidsdk /' ma non quello usato dal plugin bintray, quindi non ha aiutato. –

2

Se qualcuno è ancora bloccato con questo problema qui è quello che ha funzionato per me -

Diciamo che si desidera pubblicare il build di rilascio per i vostri flavour1 aggiungere questo al vostro build.gradle

android { 
    ... 
    defaultPublishConfig "flavour1Release" 
} 

Rimuovere publishNonDefault true se è presente nel file gradle.

Aggiungere questo all'interno del blocco bintray come questo

bintray { 
    ... 
    archivesBaseName = 'YOUR_ARTIFACT_ID' 
    ... 
} 

Poi basta eseguire l'attività bintrayUpload come si farebbe.

Il defaultPublishConfig dovrà essere modificato ogni volta che è necessario pubblicare un nuovo sapore.

+0

Rimuovere 'publishNonDefault true' impedirà modulo da utilizzare in altri moduli nel debug, è una buona idea ma non risolve il problema interamente –

+0

Sì, se si desidera utilizzare il modulo della libreria in debug, sarà necessario utilizzare qualcosa come "defaultPublishConfig" flavour1Debug "'. passare a 'defaultPublishConfig" flavour1Release "' solo quando si deve pubblicare su bintray – k1slay

5

Il setup:

buildTypes { 
    debug { 
    } 
    release { 
    } 
} 

publishNonDefault true 

La correzione:

defaultPublishConfig 'release' 

// Fix for defaultPublishConfig not working as expected 
// ref: https://github.com/dcendents/android-maven-gradle-plugin/issues/11 
libraryVariants.all { variant -> 
    if(publishNonDefault && variant.name == defaultPublishConfig) { 
    def bundleTask = tasks["bundle${variant.name.capitalize()}"] 
    artifacts { 
     archives(bundleTask.archivePath) { 
     classifier null //necessary to get rid of the suffix in the artifact 
     builtBy bundleTask 
     name name.replace('-' + variant.name, '')//necessary to get rid of the suffix from the folder name 
     } 
    } 
    } 
} 

Questa correzione sarà ancora pubblicare tutti i manufatti, ma pubblicherà un artefatto di default senza il suffisso sapore, che è abbastanza per fare tutto funziona.

La correzione per caricare solo il manufatto di default sarebbe questo (se il plugin bintray sapeva cosa filtri POM sono):

install { 
    repositories.mavenInstaller { 
    /* 
    POM filters can be used to block artifacts from certain build variants. 

    However, Bintray does not respect POM filters, therefore this only works for maven deploy plugin. 
    Also, bintray crashes with named filters, since it always expects a /build/pom/pom-default.xml, 
    which does not happen with named filters. 
    */ 
    filter { artifact, file -> 
     // this how the default classifier is identified in case the defaultPublishConfig fix is applied 
     artifact.attributes.classifier == null 
    } 
    } 
} 
Problemi correlati