run - Publicación de Android Library(aar) en Bintray con los sabores elegidos
flavors android gradle (5)
He agregado juste algunos flavors
(o productFlavors
si quieres) a mi proyecto.
El hecho es que cuando publico la biblioteca en bintray , todos los sabores se cargan (lo cual es genial), pero no puedo usarlos. El complemento utilizado es el oficial here .
El aar cargado:
androidsdk-0.0.4-fullRelease.aar
androidsdk-0.0.4-fullDebug.aar
androidsdk-0.0.4-lightRelease.aar
androidsdk-0.0.4-lightDebug.aar
Como ha notado, la fullRelease
se nombra como el classifier
, consulte el capítulo 23.4.1.3 del documento .
Estoy buscando una solución para elegir qué sabores quiero subir.
Ya he analizado ejemplos de bintray ( here y here ) y this , junto con otros ejemplos, pero todavía estoy atascado.
Aquí está mi guión actual:
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
}
}
Para importar la biblioteca, actualmente estoy usando esto:
compile (''com.example.lib:sdk:0.0.8:fullRelease@aar'') {
transitive = true;
}
Enfrenté el mismo desafío, y aquí está lo mejor que puedo hacer:
Usando mavenPublications
y el plugin madle maven-publish
largo del complemento bintray, puedes publicar cualquier variante en mavenLocal y bintray.
Aquí está el archivo publish.gradle
que aplico al final de todos los módulos de biblioteca de mi proyecto que quiero publicar:
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''
}
}
}
Para que esto funcione, necesito tener las propiedades bintray_user
y bintray_api_key
definidas. Personalmente los tengo en mi archivo ~/.gradle/gradle.properties
como este:
bintray_user=my_bintray_user_name
bintray_api_key=my_private_bintray_api_key
También necesito definir las siguientes propiedades ext que utilicé en el archivo publish.gradle
en el archivo publish.gradle
de mi proyecto raíz:
allprojects {
...
ext {
...
// Libraries
groupId = "xyz.louiscad.splitties"
libraryVersion = "1.2.1"
siteUrl = ''https://github.com/LouisCAD/Splitties''
gitUrl = ''https://github.com/LouisCAD/Splitties.git''
}
}
Y ahora, finalmente puedo usarlo en mi módulo de biblioteca de Android, donde tengo múltiples productFlavors
. Aquí hay un fragmento del archivo build.gradle
de un módulo de biblioteca publicable:
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
Cuando tenga toda esta configuración correctamente, con el nombre de su biblioteca en lugar de la mine''s (que puede usar como ejemplo), puede intentar publicar una versión de su biblioteca con sabor intentando primero publicar en mavenLocal. Para hacerlo, ejecuta este comando:
myLibrary $ ../gradlew publishToMavenLocal
Luego puede intentar agregar mavenLocal
en los repositorios de su aplicación (ejemplo aquí) e intente agregar su biblioteca como una dependencia (artifactId debe ser el nombre del sabor, con "_" reemplazado por "-") y compilarlo. También puede consultar con su explorador de archivos (use cmd + shift + G en Mac en Finder para acceder a la carpeta oculta) en el directorio ~/.m2
y busque su biblioteca.
Cuando es hora de publicar en bintray / jcenter, solo tiene que ejecutar este comando:
myLibrary $ ../gradlew bintrayUpload
Importante:
Antes de publicar su biblioteca en mavenLocal, Bintray u otro repositorio de maven, normalmente querrá probar su biblioteca con una aplicación de muestra que use la biblioteca. Esta aplicación de ejemplo, que debería ser otro módulo en el mismo proyecto, solo necesita tener la dependencia del proyecto, que debería verse así: compile project('':myLibrary'')
. Sin embargo, dado que su biblioteca tiene múltiples productFlavors, querrá probarlos todos. Desafortunadamente, actualmente es imposible especificar qué configuración desea usar desde el archivo build.gradle
la aplicación de build.gradle
(a menos que use publishNonDefault true
en el archivo build.gradle
su biblioteca, lo que rompe las publicaciones maven y bintray), pero puede especificar el valor predeterminado configuración (es decir, buildVariant) en el módulo de su biblioteca como tal: defaultPublishConfig "myLibraryDebug"
en el cierre de android
. Puede ver las variantes de compilación disponibles para su biblioteca en la herramienta "Variantes de compilación" Windows en Android Studio.
Siéntase libre de explorar mine''s si necesita un ejemplo. El módulo con sabor se llama concurrency
, pero también uso mi script para módulos de biblioteca sin sabor, y lo probé exhaustivamente en todos los módulos de biblioteca de mi proyecto.
Puede comunicarse conmigo si necesita ayuda para configurarlo.
La puesta en marcha:
buildTypes {
debug {
}
release {
}
}
publishNonDefault true
La solución:
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
}
}
}
}
Esta solución aún publicará todos los artefactos, pero publicará un artefacto predeterminado sin el sufijo de sabor, que es suficiente para que todo funcione.
La solución para cargar solo el artefacto predeterminado sería esto (si el complemento bintray supiera qué filtros POM son):
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
}
}
}
No lo intenté, así que eliminaré la respuesta si no resuelve el problema.
Debería publicar un artefacto diferente para cada sabor (o variante de compilación, si lo prefiere).
De esta forma tendrás en jcenter x artefactos, cada uno de ellos con un archivo pom.
Algo como:
groupId
|--library-full
|----.pom
|----.aar
|--library-light
|----.pom
|----.aar
En tu archivo de nivel superior puedes definir
allprojects {
repositories {
jcenter()
}
project.ext {
groupId="xxx"
libraryName = ""
......
}
}
Luego en tu módulo de biblioteca:
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
}
}
Finalmente, asegúrese de publicar solo el tipo de compilación de lanzamiento (¿por qué también la versión de depuración?)
Parece que no quieres el clasificador en el nombre del archivo. Parece que el clasificador es el mismo que el nombre del archivo de la biblioteca generado. ¿Has intentado darles el mismo nombre pero sacarlos a directorios separados? Por ejemplo, en el alcance de 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)
}
}
}
Si alguien todavía está atascado con este problema, esto es lo que funcionó para mí:
Digamos que quieres publicar la compilación de versión para tu sabor1 agrégala a tu build.gradle
android {
...
defaultPublishConfig "flavour1Release"
}
Elimine publishNonDefault true
si está presente en su archivo gradle.
Agregue esto dentro del bloque bintray
como este
bintray {
...
archivesBaseName = ''YOUR_ARTIFACT_ID''
...
}
Luego solo ejecute la tarea bintrayUpload
como lo haría.
El defaultPublishConfig
se tendrá que cambiar cada vez que necesite publicar un nuevo sabor.