做这款插件确实有点吃饱了没事干的嫌疑,毕竟 maven-publish 已经提供了很好的支持,但一想到每次都要写一遍那一大段的 publishing 又会觉得,能省几行代码是几行代码,也看过其他人将 publishing 相关的内容抽离到一个独立的 gradle 文件中,想用的时候再 apply from 引入一下,但始终觉得,这种每次都要拷贝文件到仓库的方式显得太麻烦,就没有那种直接申明 GAV 就可以上传的嘛?所以,我就想到了开发这个插件。
在之前有写过一篇《用 Github 实现组件自动发布》,这篇主要是利用 Github Actions 去构建组件,从标准交付流程来看,通过自动化构建是最合理的,但为了学习(主要是吃了没事干),硬是用 gradle 去实现了下发布组件到 github。
目前上传插件支持两种方式上传:
- uploadGithub : 上传 aar 到 github 仓库
- uploadMaven :上传 aar 到 Maven Nexus 仓库
当然,在写这款插件也遇到了一些问题,顺便也总结一下,最后再说一下如何接入这款插件。
问题记录
1、project exec commandLine 问题
在做 uploadGithub 插件时,在组件打包完成后,需要将配置的仓库 clone 到本地,然后将 aar 文件拷贝到仓库目录中,然后再将组件 aar 上传到配置的仓库,但在执行 git add ${aar 文件}
命令时没有任何反应,即使使用 git add .
也不行,起初怀疑是自己的 workingDir
设置的有问题,所以,尝试了下新建文件的命令 touch a.txt
来看看是否能生效,试了下是成功的,在仓库的目录生成了 a.txt
文件,这就让我百思不得其解。 为了不让自己思路进入死胡同,转而使用 eclipse 开源的 JGit 来实现,JGit 是一款 java 实现的用来操作 Git 的轻量库,本来想直接用 JGit 来操作整个 Git 流程的,但在用 JGit clone ssh 项目时,又出现了 The remote end hung up unexpectedly while git cloning
问题,在各种搜索中,stackoverflow 也是给出了 git config --global http.postBuffer 524288000
的设置,但在尝试后依然无果。 最终,整个 Git 链路写成了:
- commandLine 实现 git clone 项目到本地
- JGit 实现 aar 文件的 git add
- JGit 实现 aar 文件的 git commit
- commandLine 实现 git push origin branch
果然丑陋,哭了
2、hasPomDependencies
为了支持将模块组件依赖的 dependencies 也打入 pom 文件中,读取了 project 下的 dependencies 来拿到模块下的依赖,然后再拿到依赖的 GAV appendNode 到 dependency 节点中,但在实践到 implements project(":java-lib")
时发现,他是没有 GAV 的,所以,打入到 pom 中的他是长这个样子的:
<dependency> <groupId>pluginDemo</groupId> <artifactId>java-lib</artifactId> <version>unspecified</version> <scope>compile</scope> </dependency> 复制代码
显然,这种 unspecified 未指定的版本和不存在的 groupId 是无法被其他小伙伴给使用的,即使想拉这个组件也拉不下来。
后来想到曲线救国的方式,java-lib
这个组件不是也要对外发布嘛,那我直接读取 java-lib
的 build.gradle 中的 GAV 不也可以嘛,所以,这个地方又判断了下 dependency 是否是 DefaultProjectDependency,如果是的话,就读取该 dependency 目录下的 build.gradle 文件,然后用正则的方式把 GAV 给匹配出来,然后设置到 pom 文件中
接入插件:
一、配置 maven 镜像源和依赖
buildscript { repositories { ... // 配上 maven 源 maven{ url "https://raw.githubusercontent.com/MRwangqi/Maven/main" } } dependencies { classpath "com.android.tools.build:gradle:7.0.4" // 依赖 upload 插件 classpath "com.github.MRwangqi:uploadPlugin:1.0.0" } } 复制代码
二、依赖插件
1、上传到 github
在模块工程的 build.gradle 中依赖插件:
plugins { id 'com.android.library' // 配置上传到 github id 'uploadGithub' } upload { // 必选 groupId = "" // 必选 artifactId = "" // 必选 version = "" } 复制代码
local.properties 配置:
# github 仓库链接(可选,如果不配置的话则发布到 project 下的 build/repo 目录) githubURL = "" # github 仓库分支(可选,如果不配置的话则以仓库当前配置的分支为准) githubBranch = "" 复制代码
插件在运行时会读取 local.properties 中 github 的内容
2、上传到 maven
在模块工程的 build.gradle 中依赖插件:
plugins { id 'com.android.library' // 配置上传到 maven nexus id 'uploadMaven' } upload { // 必选 groupId = "" // 必选 artifactId = "" // 必选 version = "" } 复制代码
local.properties 配置:
// nexus 地址 (可选,如果不配置的话则发布到 project 下的 build/repo 目录) nexusURL = "" nexusName = "" nexusPsw = "" 复制代码
插件在运行时会读取 local.properties 中 nexus 的内容
uploadMaven 也支持通过命令参数来输入:
./gradlew :android-lib:upload -Pname=nexusName -Ppsw=${nexusPsw} -Purl=${nexusURL}
例如要打包 android-lib 模块,用户名和密码都是 admin,则命令行为:
./gradlew :android-lib:upload -Pname=admin -Ppsw=admin -Purl=http://localhost:8081/repository/android/
通用配置:
upload { // 模块下的依赖是否打入 pom : (可选,默认会打入) hasPomDepend = true // 模块是否打入 source 源码: (可选,默认会打入) sourceJar = true }