美文网首页
android 发布aar到私有仓库

android 发布aar到私有仓库

作者: czins | 来源:发表于2018-12-20 18:32 被阅读15次

    发布aar到私有仓库大概分为两种方案:

    方案一: 利用 maven 插件:

    1. 在项目根目录下新建 upload.gradle 文件:
    apply plugin: 'maven'
    
    afterEvaluate { module ->
        // 将源码打包发布
        task androidSourcesJar(type: Jar) {
            classifier = 'sources'
            from android.sourceSets.main.java.srcDirs
        }
    
        // 将类说明文档打包发布
        tasks.withType(Javadoc) {
            // 设置编码
            options.encoding = 'UTF-8'
        }
        task androidJavadoc(type: Javadoc) {
            source = android.sourceSets.main.java.srcDirs
            classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
            destinationDir = file("./javadoc/")
            // 忽略错误
            failOnError false
        }
        task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
            classifier = 'javadoc'
            from androidJavadoc.destinationDir
        }
    
        artifacts {
            archives androidSourcesJar
            archives androidJavadocJar
        }
    
        uploadArchives {
            repositories {
                mavenDeployer {
                    repository(url: MAVEN_URL) {
                        authentication(userName: MAVEN_USER_NAME, password: MAVEN_PWD)
                    }
                    pom.artifactId = ARTIFACT_ID
                    pom.groupId = GROUP_ID
                    pom.version = android.defaultConfig.versionName
                    pom.packaging = PACKAGE_TYPE
                }
                doLast {
                    println "upload aar success."
                }
            }
        }
    }
    
    1. 在项目的根目录的 gradle.properties 中添加配置项:
    # 发布私有仓库的地址,我这里是本机地址
    MAVEN_URL=file://localhost/e:/deploy/
    # 如果私有仓库有账号,这里为账号
    MAVEN_USER_NAME=admin
    # 如果私有仓库有密码,这里为密码
    MAVEN_PWD=123456
    # 包的类型,会写到 pom 文件中
    PACKAGE_TYPE=aar
    # 包的分组名,和 ARTIFACT_ID 对应
    GROUP_ID=com.colbert.lib
    
    1. 在要发布的 library 项目的目录下新建 gradle.properties 文件
    # 库的名称,引用时配合GROUP_ID,implementation 'com.colbert.lib:log:1.0.0'
    ARTIFACT_ID=log
    

    4.在 library 项目的目录下的 build.gradle 文件引用改 upload.gradle 文件

    apply from: '../upload.gradle'
    

    至此,同步gradle之后,gradle 任务列表中多了个 uploadArchives 的任务,运行之后即可在仓库中看到发布的aar包。

    以上是针对 library 项目中没有 flavor 的情况,但如果 library 中含有 flavor,例如:

    library 项目中有以下配置:

    flavorDimensions 'push'
    productFlavors {
        excludePush {
            dimension 'push'
        }
        includePush {
            dimension 'push'
        }
    }
    

    运行 uploadArchives 任务会任何库都不会发布,需要加以下配置:

    android {
        // 默认发布的配置,必须加
        defaultPublishConfig 'excludePushRelease'
    }
    

    加了上面的配置,你会发现可以发布了,但生成的库的 pom 没有依赖信息,所以我们要重新写一个 upload.gradle 文件,添加依赖信息。

    在 library 的项目文件加下,新建 upload.gradle 文件:

    afterEvaluate { project ->
        def RELEASE_BUILD_TYPE = "Release"
    
        // 将源码打包发布
        task androidSourcesJar(type: Jar) {
            classifier = 'sources'
            from android.sourceSets.main.java.srcDirs
        }
    
        // 将类说明文档打包发布
        tasks.withType(Javadoc) {
            // 设置编码
            options.encoding = 'UTF-8'
        }
        task androidJavadoc(type: Javadoc) {
            source = android.sourceSets.main.java.srcDirs
            classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
            destinationDir = file("./javadoc/")
            // 忽略错误
            failOnError false
        }
        task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
            classifier = 'javadoc'
            from androidJavadoc.destinationDir
        }
    
        artifacts {
            archives androidSourcesJar
            archives androidJavadocJar
        }
    
        uploadArchives {
            repositories {
                mavenDeployer {
                    repository(url: MAVEN_URL) {
                        authentication(userName: MAVEN_USER_NAME, password: MAVEN_PWD)
                    }
                    android.libraryVariants.all { variant ->
                        def name = "${variant.name}"
                        addFilter(name) { artifact, file ->
                            // 只上传 release 包
                            name.contains(RELEASE_BUILD_TYPE)
                        }
                        pom(name).artifactId = archivesBaseName + "-" + flavorName
                        pom(name).version = android.defaultConfig.versionName
                        pom(name).groupId = GROUP_ID
                        pom(name).packaging = 'aar'
                        // 在 pom 文件中加入依赖
                        pom(name).withXml {
                            def root = asNode()
                            def dependenciesNode = root["dependencies"][0] ?: root.appendNode("dependencies")
                            def addDependency = {
                                if (it.group == null || it.version == null || it.name == null || it.name == "unspecified") {
                                    // 忽略
                                    return
                                }
                                def dependencyNode = dependenciesNode.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')
                                }
                                if (!it.transitive) {
                                    def exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                                    exclusionNode.appendNode('groupId', '*')
                                    exclusionNode.appendNode('artifactId', '*')
                                } else if (!it.properties.excludeRules.empty) {
                                    def exclusionsNode = dependencyNode.appendNode('exclusions')
                                    it.properties.excludeRules.each { rule ->
                                        def exclusionNode = exclusionsNode.appendNode('exclusion')
                                        exclusionNode.appendNode('groupId', rule.group ?: '*')
                                        exclusionNode.appendNode('artifactId', rule.module ?: '*')
                                    }
                                }
                            }
                            configurations.api.allDependencies.each addDependency
                            configurations.implementation.allDependencies.each addDependency
                            configurations.compile.allDependencies.each addDependency
                            if (!flavorName.isEmpty()) {
                                def flavorNameLower = flavorName.toLowerCase()
                                android.productFlavors.each {
                                    def flavor = it.name
                                    if (flavorNameLower.contains(flavor.toLowerCase())) {
                                        configurations["${flavor}Implementation"].allDependencies.each addDependency
                                        configurations["${flavor}Api"].allDependencies.each addDependency
                                        configurations["${flavor}Compile"].allDependencies.each addDependency
                                    }
                                }
                                configurations["${name}Implementation"].allDependencies.each addDependency
                                configurations["${name}Api"].allDependencies.each addDependency
                                configurations["${name}Compile"].allDependencies.each addDependency
                                configurations["${flavorName}Implementation"].allDependencies.each addDependency
                                configurations["${flavorName}Api"].allDependencies.each addDependency
                                configurations["${flavorName}Compile"].allDependencies.each addDependency
                            }
                        }
                    }
                }
                doLast {
                    println "upload aar success."
                }
            }
        }
    }
    

    在 library 中引用这个文件即可:

    apply from: './upload.gradle'
    

    这时在运行 uploadArchives 任务即可成功发布。

    方案二:利用 maven-publish 插件

    这种方式需要注意:
    不会自动追加依赖到pom文件中,需要像上面一样,将依赖文件加进入

    apply plugin: 'maven-publish'
    afterEvaluate { module ->
    
        // 将源码打包发布
        task androidSourcesJar(type: Jar) {
            classifier = 'sources'
            from android.sourceSets.main.java.srcDirs
        }
    
        // 将文档打包发布
        tasks.withType(Javadoc) {
            // 设置编码
            options.encoding = 'UTF-8'
        }
        task androidJavadoc(type: Javadoc) {
            source = android.sourceSets.main.java.srcDirs
            classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
            destinationDir = file("./javadoc/")
            // 忽略错误
            failOnError false
        }
        task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
            classifier = 'javadoc'
            from androidJavadoc.destinationDir
        }
    
        artifacts {
            archives androidSourcesJar
            archives androidJavadocJar
        }
        publishing {
            publications {
                maven(MavenPublication) {
                    groupId GROUP_ID
                    artifactId ARTIFACT_ID
                    version android.defaultConfig.versionName
                    artifact bundleRelease
                    artifact androidJavadocJar
                    artifact androidSourcesJar
                    // 在 pom 文件中加入依赖
                    pom(name).withXml {
                        def root = asNode()
                        def dependenciesNode = root["dependencies"][0] ?: root.appendNode("dependencies")
                        def addDependency = {
                            if (it.group == null || it.version == null || it.name == null || it.name == "unspecified") {
                                // 忽略
                                return
                            }
                            def dependencyNode = dependenciesNode.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')
                            }
                            if (!it.transitive) {
                                def exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                                exclusionNode.appendNode('groupId', '*')
                                exclusionNode.appendNode('artifactId', '*')
                            } else if (!it.properties.excludeRules.empty) {
                                def exclusionsNode = dependencyNode.appendNode('exclusions')
                                it.properties.excludeRules.each { rule ->
                                    def exclusionNode = exclusionsNode.appendNode('exclusion')
                                    exclusionNode.appendNode('groupId', rule.group ?: '*')
                                    exclusionNode.appendNode('artifactId', rule.module ?: '*')
                                }
                            }
                        }
                        configurations.api.allDependencies.each addDependency
                        configurations.implementation.allDependencies.each addDependency
                        configurations.compile.allDependencies.each addDependency
                        if (!flavorName.isEmpty()) {
                            def flavorNameLower = flavorName.toLowerCase()
                            android.productFlavors.each {
                                def flavor = it.name
                                if (flavorNameLower.contains(flavor.toLowerCase())) {
                                    configurations["${flavor}Implementation"].allDependencies.each addDependency
                                    configurations["${flavor}Api"].allDependencies.each addDependency
                                    configurations["${flavor}Compile"].allDependencies.each addDependency
                                }
                            }
                            configurations["${name}Implementation"].allDependencies.each addDependency
                            configurations["${name}Api"].allDependencies.each addDependency
                            configurations["${name}Compile"].allDependencies.each addDependency
                            configurations["${flavorName}Implementation"].allDependencies.each addDependency
                            configurations["${flavorName}Api"].allDependencies.each addDependency
                            configurations["${flavorName}Compile"].allDependencies.each addDependency
                        }
                    }
                }
            }
            repositories {
                maven {
                    // 本地文件路径改成 "file://e:/deploy"
                    url = MAVEN_URL 
                    // 本地文件不支持 credentials 这种认证,请注释掉
                    credentials {
                        username MAVEN_USER_NAME
                        password MAVEN_PWD
                    }
                }
            }
        }
    }
    

    在右边的 gradle 任务栏中多了个 publishing 文件夹, 运行里面 publishMavenPublicationToMavenRepository 的任务即可。

    这里需要注意:
    如果你发布的library库引用了别的子项目,建议将子项目单独配置发布,在library中都引用maven格式的地址。

    相关文章

      网友评论

          本文标题:android 发布aar到私有仓库

          本文链接:https://www.haomeiwen.com/subject/hctukqtx.html