Java和Android 发布jar或aar到Nexus

1,352 阅读2分钟

[TOC]

可以用的插件主要有maven和maven-publish,
maven是grale1.0就已经有了,比较原始兼容性好;
maven-publish是从gradle 1.3新引入的发布机制,使Gradle发布更加强大,具体看官网吧;

常用的Task

Java的Task也可以用在Android中

配置文档属性

tasks.withType(Javadoc) {
    description "Generates project-level javadoc for use in -javadoc jar."
    if (JavaVersion.current().isJava8Compatible()) {
        options.addStringOption('Xdoclint:none', '-quiet')
    }
    options.docTitle = "<h1>" + GROUP + "</h1>"
    options.windowTitle = options.docTitle
    options.memberLevel = JavadocMemberLevel.PRIVATE
    options.encoding = "UTF-8"
    options.charSet = 'UTF-8'
    //关联源码
    options.linkSource true
    //检查作者
    options.author = true
    //自定义注释Tag see:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#tag
    options.tags = ["date:a:日期"]
    options.links("http://docs.oracle.com/javase/7/docs/api/", "http://d.android.com/reference")
    failOnError true
}

Java工程

// 生成Java源码
task javaSourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier 'sources'
}

// 生成Java文档
task javadocsJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}

// 同时打包源码和文档
artifacts {
    archives javadocsJar
    archives javaSourcesJar
}

Android工程

// 生成Android源码
task androidSourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.source
}

// 生成Android文档
task androidJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    // TODO Update to include KT files OR stop publishing javadoc artifacts.
    exclude "**/*.kt"
    exclude "**/internal/**"
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
    // Append also the classpath and files for release library variants.
    // This fixes the javadoc warnings.
    // Copy pasta from https://github.com/novoda/bintray-release/pull/39/files
    def releaseVariant = android.libraryVariants.find {
        it.name.endsWith("release")
    }
    if (releaseVariant != null) {
        classpath += releaseVariant.javaCompileProvider.get().classpath
        classpath += releaseVariant.javaCompileProvider.get().outputs.files
    }
}

// 生成Android文档
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
    classifier = 'javadoc'
    from androidJavadocs.destinationDir
}

// 同时打包源码和文档
artifacts {
    archives androidSourcesJar
    archives androidJavadocsJar
}

// 支持对库文件数字签名的插件,可以通过签名知道文件的创建者,创建时间等信息
apply plugin: 'signing'
signing {
    required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
    sign configurations.archives
}

通用信息

// Nexus 服务器账号密码
def properties = Properties()
properties.load(rootProject.file("local.properties").newReader(Charset.forName("UTF-8")))
def NEXUS_USERNAME = properties.getProperty("NEXUS_USERNAME")
def NEXUS_PASSWORD = properties.getProperty("NEXUS_PASSWORD")

// 本版描述信息,对应:example.planb.com:maven-publish:1.0.0
def GROUP = "example.planb.com"
def POM_ARTIFACT_ID = "maven-publish"
def VERSION_NAME = "1.0.0"

// nexus 服务器地址
def RELEASE_REPOSITORY_URL = "http://xxx.com/nexus/content/repositories/releases/"
def SNAPSHOT_REPOSITORY_URL = "http://xxx.com/nexus/content/repositories/snapshots/"

// 本机发布地址
def REPO_RELATIVE_PATH = rootDir.absolutePath
def RELEASE_LOCAL_REPO_URL = "$REPO_RELATIVE_PATH/maven-repo/maven-releases/"
def SNAPSHOT_LOCAL_REPO_URL = "$REPO_RELATIVE_PATH/maven-repo/maven-snapshots/"

// POM文件中指向你网站的地址
def POM_URL = "http://git.xxx.com/projects/xxx/browse/README.md"
def POM_NAME = GROUP
def POM_ARTIFACT_ID = POM_ARTIFACT_ID
def POM_PACKAGING = jar
def POM_DESCRIPTION = "maven example"

// SCM是指版本管理工具,描述相关信息
def POM_SCM_URL = "http://git.xxx.com/projects/xxx/browse"
def POM_SCM_CONNECTION = "http://weishuxin@git.xxx.com/scm/xxx/xxx.git"
def POM_SCM_DEV_CONNECTION = "http://weishuxin@git.xxx.com/scm/xxx/xxx.git"

// 你的开放协议相关信息
def POM_LICENCE_NAME = "The Apache Software License, Version 2.0"
def POM_LICENCE_URL = "http://www.apache.org/licenses/LICENSE-2.0.txt"
def POM_LICENCE_DIST = "repo"

// 开发者的相关信息
def POM_DEVELOPER_ID = "weishuxin"
def POM_DEVELOPER_NAME = "shuxin.wei"
def POM_DEVELOPER_EMAIL = "weishuxin@xxx.com"

使用maven-publish

增加插件依赖:apply plugin :'maven-publish'

发布到本地

Groovy脚本,Kotlin类似

// Task:publishToMavenLocal
publishing {
    publications {
        maven(MavenPublication) {
            groupId = GROUP
            artifactId = POM_ARTIFACT_ID
            version = VERSION_NAME
            
            // 指定文件
            // artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
        
            // 指定jar,Java工程可以直接用
            // from components.java
            
            // 指定task,Android工程需要先打包
            artifact bundleRelease
        }
    }
}

发布到Nexus仓库

Kotlin脚本,Groovy类似

publishing {
    publications {
        // 配置Task信息
        create<MavenPublication>("mavenJava") {
            groupId = GROUP
            artifactId = POM_ARTIFACT_ID
            version = VERSION
            artifact(tasks.findByName("jar"))
            pom {
                name.set(POM_NAME)
                description.set(POM_DESCRIPTION)
                developers {
                    developer {
                        id.set(POM_DEVELOPER_ID)
                        name.set(POM_DEVELOPER_NAME)
                        email.set(POM_DEVELOPER_EMAIL)
                    }
                }
                licenses {
                    license {
                        name.set(POM_LICENCE_NAME)
                        url(POM_LICENCE_URL)
                        distribution(POM_LICENCE_DIST)
                    }
                }
                scm {
                    connection.set(POM_SCM_CONNECTION)
                    developerConnection.set(POM_SCM_DEV_CONNECTION)
                    url.set(POM_SCM_URL)
                }
            }
        }
    }

    // 可以配置多个仓库
    repositories {
        maven {
            name = "repo1"
            url = uri(if (VERSION.toLowerCase().contains("snapshot")) SNAPSHOT_REPOSITORY_URL else RELEASE_REPOSITORY_URL)
            credentials {
                username = NEXUS_USERNAME
                password = NEXUS_PASSWORD
            }
        }
        maven {
            name = "repo2"
            url = uri(if (VERSION.toLowerCase().contains("snapshot")) SNAPSHOT_REPOSITORY_URL else RELEASE_REPOSITORY_URL)
            credentials {
                username = NEXUS_USERNAME
                password = NEXUS_PASSWORD
            }
        }
    }
}

使用maven

增加依赖:apply plugin: 'maven'

maven 发布本地和发布到远程仓库相同:

uploadArchives {
    repositories {
        mavenDeployer {
            beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
            // 发布到本地
            if (isLocal) {
                repository(url: uri(RELEASE_LOCAL_REPO_URL))
                snapshotRepository(url: uri(SNAPSHOT_LOCAL_REPO_URL))
            } 
            // 发布到远程仓库
            else {
                repository(url: RELEASE_REPOSITORY_URL) {
                    authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
                }
                snapshotRepository(url: SNAPSHOT_REPOSITORY_URL) {
                    authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
                }
            }
            pom.groupId = GROUP
            pom.artifactId = POM_ARTIFACT_ID
            pom.version = VERSION_NAME
            pom.project {
                name POM_NAME
                packaging POM_PACKAGING
                description POM_DESCRIPTION
                url POM_URL
                scm {
                    url POM_SCM_URL
                    connection POM_SCM_CONNECTION
                    developerConnection POM_SCM_DEV_CONNECTION
                }
                licenses {
                    license {
                        name POM_LICENCE_NAME
                        url POM_LICENCE_URL
                        distribution POM_LICENCE_DIST
                    }
                }
                developers {
                    developer {
                        id POM_DEVELOPER_ID
                        name POM_DEVELOPER_NAME
                        email POM_DEVELOPER_EMAIL
                    }
                }
            }
            // 替换关联的Library
            // 例如: implementation project(':example-annotation'),上传后version为unspecified
            pom.whenConfigured { pom ->
                pom.dependencies.findAll { dep -> dep.groupId == rootProject.name }.collect { dep ->
                    dep.groupId = pom.groupId = GROUP
                    dep.version = pom.version = VERSION_NAME
                }
            }
              pom.withXml {
                  configurations.implementation.allDependencies.each {
                      if (it.name == 'unspecified') {
                          it.name = VERSION_NAME
                      }
                  }
              }
        }
    }
}