web-dev-qa-db-ja.com

選択したフレーバーを使用してライブラリ(aar)をBintrayに公開Android

プロジェクトにflavors(または必要に応じてproductFlavors)を追加しました。

事実、ライブラリをbintrayに公開すると、すべてのフレーバーがアップロードされます(これは素晴らしいことです)が、使用できません。使用されるプラグインは公式のものです ここ

アップロードされたaar:

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

お気づきのとおり、fullReleaseclassifierという名前です。 ドキュメントの第23.4.1.3章 を参照してください。

アップロードしたいフレーバーを選択するための解決策を探しています。

私はすでにbintrayの例( herehere )と this を他の例で見てきましたが、まだ行き詰まっています。

これが私の現在のスクリプトです:

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
    }
}

ライブラリをインポートするには、現在これを使用しています。

compile ('com.example.lib:sdk:0.0.8:fullRelease@aar') {
    transitive = true;
}
33
Hugo Gresse

私は同じ課題に直面しました、そしてこれが私がこれまでに作ることができた最高のものです:

Bintrayプラグインに沿ってmavenPublicationsとgradle _maven-publish_プラグインを使用すると、任意のバリアントをmavenLocalとbintrayに公開できます。

これが _publish.gradle_ 公開したいすべてのプロジェクトのライブラリモジュールの最後に適用するファイルです。

_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'
        }
    }
}
_

これを機能させるには、_bintray_user_プロパティと_bintray_api_key_プロパティを定義する必要があります。私は個人的に次のように_~/.gradle/gradle.properties_ファイルにそれらを持っています:

_bintray_user=my_bintray_user_name
bintray_api_key=my_private_bintray_api_key
_

また、ルートプロジェクトの _publish.gradle_ ファイルの _build.gradle_ ファイルで使用した次のextプロパティを定義する必要があります。

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

そして今、私はついにそれを私のAndroidライブラリモジュールで使用できるようになりました。ここでは、複数のproductFlavorsがあります。これは公開可能なライブラリモジュールの _build.gradle_ ファイル:

_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
_

mine's (例として使用できます)の代わりにライブラリの名前を使用して、この設定をすべて適切に行うと、最初に公開することで、フレーバーライブラリのバージョンを公開してみることができます。 mavenLocalに。これを行うには、次のコマンドを実行します。

_myLibrary $ ../gradlew publishToMavenLocal
_

次に、アプリのリポジトリにmavenLocalを追加してみてください (ここの例) そしてライブラリを依存関係として追加してみてください(artifactIdはフレーバー名で、「_」は「-」に置き換えてください) ")そしてそれを構築します。また、ファイルエクスプローラーでディレクトリ_~/.m2_を確認し(MacではFinderのcmd + shift + Gを使用して非表示のフォルダーにアクセス)、ライブラリを探すこともできます。

Bintray/jcenterに公開するときは、次のコマンドを実行するだけです。

_myLibrary $ ../gradlew bintrayUpload
_

重要:

ライブラリをmavenLocal、Bintray、または別のmavenリポジトリに公開する前に、通常、ライブラリを使用するサンプルアプリに対してライブラリを試してみることをお勧めします。このサンプルアプリは、同じプロジェクト内の別のモジュールである必要があり、プロジェクトの依存関係が必要です。これは、compile project(':myLibrary')のようになります。ただし、ライブラリには複数のproductFlavorsがあるため、それらすべてをテストする必要があります。残念ながら、現在、サンプルアプリの_build.gradle_ファイルから使用する構成を指定することはできません(ライブラリの_publishNonDefault true_ファイルで_build.gradle_を使用すると、MavenとBintrayのパブリケーションが破損します) 、ただし、ライブラリのモジュールでデフォルト構成(つまり、buildVariant)を次のように指定できます。Androidクロージャーの_defaultPublishConfig "myLibraryDebug"_。ライブラリで利用可能なビルドバリアントは、WindowsのAndroid Studioの「ビルドバリアント」ツールで確認できます。

例が必要な場合は、自由に探索してください 私のライブラリ「Splitties」はこちら 。フレーバーモジュールの名前はconcurrencyですが、フレーバーのないライブラリモジュールにもスクリプトを使用し、プロジェクト内のすべてのライブラリモジュールで徹底的にテストしました。

設定についてサポートが必要な場合は、私に連絡してください。

12
Louis CAD

セットアップ:

buildTypes {
  debug {
  }
  release {
  }
}

publishNonDefault true

修正:

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
      }
    }
  }
}

この修正により、すべてのアーティファクトが引き続き公開されますが、フレーバーサフィックスのないデフォルトのアーティファクトが公開されます。これは、すべてを機能させるのに十分です。

デフォルトのアーティファクトのみをアップロードするための修正は次のようになります(bintrayプラグインがPOMフィルターが何であるかを知っている場合):

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
    }
  }
}
6
Ricardo Freitas

試していなかったので、問題が解決しない場合は回答を削除します。

フレーバーごとに異なるアーティファクトを投稿する必要があります(または、必要に応じてバリアントをビルドします)。
このようにして、jcenter xアーティファクトが作成され、それぞれにpomファイルが含まれます。

何かのようなもの:

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

トップレベルのファイルで定義できます

allprojects {
    repositories {
        jcenter()
    }

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

次に、ライブラリモジュールで:

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
    }
}

最後に、リリースビルドタイプのみを公開するようにしてください(なぜデバッグバージョンも公開するのですか?)

3

誰かがまだこの問題で立ち往生しているなら、これが私のために働いたものです-

Flavour1のリリ​​ースビルドを公開したいとします。これをbuild.gradleに追加します。

Android {
    ...
    defaultPublishConfig "flavour1Release"
}

publishNonDefault trueがgradleファイルに存在する場合は、それを削除します。

このようにbintrayブロック内にこれを追加します

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

次に、bintrayUploadタスクを実行します。

defaultPublishConfigは、新しいフレーバーを公開する必要があるたびに変更する必要があります。

2
k1slay

ファイル名に分類子を含めたくないようです。分類子は、生成されたライブラリファイル名と同じように見えます。それらに同じファイル名を付けて、別々のディレクトリに出力しようとしましたか?例えば。 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)
        }
    }
}
1
Jim Baca