美文网首页Android技术知识Android开发Android开发经验谈
Kotlin与Java混编项目的Nexus私有仓库持续打包与集

Kotlin与Java混编项目的Nexus私有仓库持续打包与集

作者: Jepack | 来源:发表于2019-01-18 00:45 被阅读16次

    关于 Android 开发结合 Nexus 仓库的使用已经有很多相关文章了,但大多是纯 Java 工程的应用。我使用 Kotlin 开发已有半年多了,愈发感觉 Kotlin 好用。现在新项目的开发中,95%以上的代码使用 Kotlin 编写,旧的项目也逐渐升级。随着项目规模的不断变大,模块越来越多,每次编译都十分耗时。而新项目使用旧有模块,需要手动拷贝,版本控制也是个问题。为了解决这个问题,我们搭建了私有 Nexus 仓库。相对稳定的模块直接通过私有仓库管理,在打包上传包含 Kotlin 的模块时,遇到了一些问题,这里记录下,大家有需要可以参考下。

    搭建 Nexus 仓库

    搭建 Nexus 仓库的文章相比有很多,官方也提供了详细的文档。但如果想快速搭建,建议使用 Docker,只需一行命令,当然前提是你已经安装了 Docker。在 Docker hub 搜索下


    Docker hub Nexus 搜索结果

    显而易见 sonatype/nexus3 是首选

    docker pull sonatype/nexus3
    

    是的一个强大的私有库,只需等待这条命令执行完成就可以了。具体如何配 nexus 这里就不做详细介绍了,无论是 Google 还是百度都一大把。


    Nexus仓库截图

    支持 Kotlin aar 打包,包括 java 文档打包。

    要想支持 Kotlin 打包,需要使用 Kotlin 官方插件 org.jetbrains.dokka:dokka-android-gradle-plugin,目前最新版本是 0.9.17,虽然还没到1.0,暂时没有发现问题。

    //工程的 build.gradle
    dependencies {
        ...
        classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:0.9.17"
        ...
    }
    
    repositories {
        ...
        maven {
            url "https://plugins.gradle.org/m2/"
        }
        ...
    }
    
    //库 Module 的 build.gradle
    task generateSourcesJar(type: Jar) {
        group = 'jar'
        from android.sourceSets.main.java.srcDirs
        classifier = 'sources'
    }
    
    task javadoc(type: Javadoc) {
        source = android.sourceSets.main.java.srcDirs
        classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
    }
    
    task dokkaJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) {
        outputFormat = "javadoc"
        outputDirectory = javadoc.destinationDir
    }
    
    task generateJavadoc(type: Jar, dependsOn: dokkaJavadoc) {
        group = 'jar'
        classifier = 'javadoc'
        from javadoc.destinationDir
    }
    
    artifacts {
        //在频繁打包交付测试时,可暂时注释掉文档打包,提高打包效率
        archives generateJavadoc
    
        archives generateSourcesJar
    }
    
    //动态获取版本名称
    def POM_VERSION_NAME = getVersionName()
    
    uploadArchives {
        repositories {
            mavenDeployer {
                snapshotRepository(url: NEXUS_REPO_SNAPSHOT_URL) {
                    authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
                }
                repository(url: NEXUS_REPO_RELEASE_URL) {
                    authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
                }
                pom.project {
                    name POM_NAME
                    version POM_VERSION_NAME
                    artifactId POM_ARTIFACTID
                    groupId POM_GROUP_ID
                    packaging POM_PACKAGING
                    description POM_DESCRIPTION
                }
            }
        }
    }
    
    def getVersionCode() {
        def versionFile = file('./version.properties')
        if (versionFile.canRead()) {
            Properties properties = new Properties()
            properties.load(new FileInputStream(versionFile))
            def versionCode = properties['VERSION_CODE'].toInteger()//读取version.properties文件存放的版本号。
            properties['VERSION_CODE'] = (++versionCode).toString()
            properties.store(versionFile.newWriter(), null)
            return versionCode
        } else {
            throw new Exception("无法读取version.properties文件!")
        }
    }
    
    //频繁测试发布时配置自动追加 -SNAPSHOT 后缀
    def getVersionName() {
        def versionFile = file('./version.properties')
        if (versionFile.canRead()) {
            Properties properties = new Properties()
            properties.load(new FileInputStream(versionFile))
            //这里可以根据 gradle.startParameter.taskNames 任务名称进行判断是打包快照版本还是正式版本
            return properties['VERSION_NAME'].toString() + "." + getVersionCode() + "-SNAPSHOT"
        } else {
            throw new Exception("无法读取version.properties文件!")
        }
    }
    
    

    SNAPSHOT上传 版本号必须以SNAPSHOT结尾

    通过上面的配置已经可以实现打包上传了。由于我的部分模块功能还处于开发阶段,就想着每次编译自动打包上传到Nexus私有仓库。显然这样频繁的上传不适用于release的仓库,应该上传至SNAPSHOT。可尝试了多种方法仍旧不能上传到SNAPSHOT,知道看到一个 官方例子
    我尝试着将版本号追加SNAPSHOT后缀,然后就神奇的可以了。上面的库 Module 的 build.gradle 已经包含了这个设置。

    持续打包,持续测试

    原本以为这样就天高任鸟飞了,但实践时发现不是这样的。频繁发布时需要不停的修改打包以及集成的版本,真心累。Google了半天大部分的答案是做如下配置:

    //在主 Module 的 build.gradle 配置
    configurations.all {
        // check for updates every build
        resolutionStrategy{
            cacheDynamicVersionsFor 0, 'seconds'
        }
    }
    

    我做了上述配置还是不会自动更新。于是便另觅它法,自动升级库版本号,而主 Module 自动使用最新的版本。同样上面的库的 build.gradle 已经做了版本自增长逻辑,还需要在库 Module 根目录下增加一个 version.properties 文件,每次回追加一个自增长的数字(0.0.1 0.0.2 0.0.3 .... 0.0.n)。当做大的升级时,修改下 VERSION_NAME 并重置 VERSION_CODE=0 即可。

    #Thu Jan 17 18:53:14 CST 2019
    VERSION_NAME=0.0
    VERSION_CODE=0
    

    集成私有库

    要想使用私有的库,需要做如下配置:
    配置私有的 Nexus 仓库地址,包括 release 仓库,snapshots 仓库。

    //工程的 build.gradle
    maven {
        url "http://<nexus server>:port/repository/xxxx-releases/"
    }
    maven {
        url "http://<nexus server>:port/repository/xxxx-snapshots/"
    }
    

    在应用打包的仓库时,如果想每次获取最新的库,需要设置一个动态的版本,下面的两种形式都可以:

    //主 Module 的 build.gradle
    implementation '<group id>:<name>:latest.integration'
    // implementation '<group id>:<name>:0.0.+-SNAPSHOT'
    

    到这里基本就可以满足基本的需求了,欢迎大家批评指正。


    相关文章

      网友评论

        本文标题:Kotlin与Java混编项目的Nexus私有仓库持续打包与集

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