16、发布与部署:Maven-Publish插件、Artifactory/Nexus配置、签名与校验、Gradle Portal发布、私有仓库

说实话,很多Android开发做到「能跑」就停了。但一个真正成熟的组件,必须能发布出去,让别人(或者别的模块)轻松引用。我见过太多团队,本地调试没问题,一集成就炸——说白了,就是发布流程没规范。

这一章,咱们就聊聊怎么把Gradle产物(AAR、JAR、POM)发到仓库里。不管是公网还是内网,都得有一套靠谱的流程。

16.1 Maven-Publish插件:最正统的发布方式

Gradle官方推荐用maven-publish插件。它比老旧的maven插件更灵活,也更好用。我个人习惯,新项目一律用maven-publish

先看一个最基础的配置:

plugins {
    id 'com.android.library'
    id 'maven-publish'
}

afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                from components.release
                groupId = 'com.example'
                artifactId = 'my-library'
                version = '1.0.0'
            }
        }
    }
}

这里有个坑——from components.release。如果你用的是Android Library,必须确保release变体存在。我曾经遇到过有人只配了debug变体,结果发布时直接报错。

注意:Android Library的components里只有releasedebug两个变体。如果你自定义了变体名称,记得手动注册。

16.2 签名与校验:没人想用被篡改的包

发布到公网仓库(比如Maven Central)时,签名是强制要求。说白了,就是让用户能验证这个包确实是你发的,没被人动过手脚。

配置签名其实不复杂:

plugins {
    id 'signing'
}

signing {
    sign publishing.publications.release
}

// 签名信息通常放在 gradle.properties 或环境变量里
signing.keyId = '你的KeyID'
signing.password = '你的密码'
signing.secretKeyRingFile = '路径/到/secring.gpg'

嗯,这里要注意——secring.gpg文件千万别提交到Git里。我见过有人直接把私钥传到GitHub上,那场面……你想想看,等于把家门钥匙挂在了大门口。

小技巧:建议把签名信息放在~/.gradle/gradle.properties里,或者用CI的环境变量注入。这样既安全,又不会污染项目代码。

16.3 Artifactory/Nexus配置:企业级私有仓库

大部分公司不会把内部组件发到公网。这时候就需要私有仓库了。我用得最多的是JFrog ArtifactorySonatype Nexus。两者功能差不多,选哪个看团队习惯。

配置方式也很直接:

publishing {
    repositories {
        maven {
            name = 'nexus'
            url = 'https://你的nexus地址/repository/maven-releases/'
            credentials {
                username = 'admin'
                password = '你的密码'
            }
        }
    }
}

发布时执行:

./gradlew publishReleasePublicationToNexusRepository

为什么我要强调name?因为如果你有多个仓库目标(比如测试仓库和正式仓库),名字就是区分的关键。我曾经踩过坑——两个仓库都叫maven,结果发布时总是覆盖了其中一个。

16.4 Gradle Portal发布:给全世界用

如果你写的是Gradle插件,那就要发到Gradle Plugin Portal。流程稍微有点不同。

首先,你得在gradlePlugin块里声明插件:

gradlePlugin {
    plugins {
        myPlugin {
            id = 'com.example.my-plugin'
            implementationClass = 'com.example.MyPlugin'
        }
    }
}

然后配置发布:

pluginBundle {
    website = 'https://github.com/你的项目'
    vcsUrl = 'https://github.com/你的项目.git'
    description = '一个超好用的Gradle插件'
    tags = ['android', 'build', 'plugin']

    plugins {
        myPlugin {
            displayName = 'My Awesome Plugin'
        }
    }
}

最后执行:

./gradlew publishPlugins

它会自动上传到plugins.gradle.org。嗯,这里要注意——插件ID一旦发布就不能改了。我见过有人手滑写错了ID,结果只能重新注册一个。

核心要点:发布到Gradle Portal需要先申请API Key。去plugins.gradle.org注册账号,然后在~/.gradle/gradle.properties里配置gradle.publish.keygradle.publish.secret

16.5 私有仓库:自己搭,自己用

私有仓库的好处很明显——速度快、安全、可控。我建议每个团队都搭一个。哪怕只有两三个人,也比互相传AAR文件强。

搭建方式其实不复杂:

  • Nexus:下载OSS版本,解压运行./bin/nexus run。默认端口8081。
  • Artifactory:下载Docker镜像,docker run -p 8081:8081 docker.bintray.io/jfrog/artifactory-oss

配置好之后,在Gradle里引用:

repositories {
    maven {
        url = 'https://你的私有仓库/repository/maven-public/'
        credentials {
            username = 'readonly'
            password = '只读密码'
        }
    }
}

我个人习惯把只读账号给开发者用,读写账号只给CI用。这样就算有人泄露了密码,最多只能读,不能改。

16.6 知识体系总览

下面这张图,把整个发布与部署的流程串起来了。你可以看到从构建产物目标仓库的完整链路:

发布与部署知识体系 构建产物 AAR / JAR / POM 签名与校验 GPG签名 / 校验和 发布方式 Maven-Publish插件 / Gradle Portal发布 目标仓库 Artifactory / Nexus / Gradle Portal / 私有仓库 消费者引用 implementation 'com.example:lib:1.0.0'

16.7 避坑指南

最后,分享几个我踩过的坑:

  • POM依赖丢失:发布后别人引用发现缺依赖。解决办法是显式声明pom.withXml,把apiimplementation的依赖都写进去。
  • 版本号冲突:同一个库发了多个版本,但消费者总是拉到旧的。我建议用maven-metadata.xml来管理版本列表,或者干脆用SNAPSHOT版本做开发测试。
  • 权限问题:私有仓库的账号密码写死在代码里,结果被实习生提交到了GitHub。嗯,从那以后我强制团队用gradle.properties + .gitignore
我的建议:发布流程一定要自动化。用CI(比如Jenkins、GitHub Actions)来触发发布,不要手动执行./gradlew publish。人总会犯错,机器不会。

好了,这一章的内容就到这里。发布与部署看似繁琐,但一旦搭好流程,后面就是一劳永逸的事。你想想看,每次改完代码,CI自动打包、签名、发布,多省心。

公众号:蓝海资料掘金营,微信deep3321