Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖

现状

现在的项目是纯代码依赖的,Library需提供给其他团队使用,当前采用的是打aar的方式,在打生产包的时候,Jenkins会去打aar包,并存储下来,提供给其他团队使用。
项目的依赖情况如下图所示
Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖_第1张图片
Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖_第2张图片

目标

通过aar的方式提供给外部团队,既麻烦又不够优雅,所以想对此做出修改。

希望达到如下的效果

  • 本地开发模式下
    • 直接依赖Library源码进行开发调试
  • Jenkins打开发包
    • git每次提交了Commit之后,都会去打一个开发包,此时,会先将library编译上传到Maven快照仓库 (Snapshot) 上,然后在编译app的时候,会从Maven快照仓库里拉去最新的library库,然后进行打包
  • Jenkins打正式包
    • 每次打生产包的时候,都会将config.gradle中的versionCodeversionName+1,然后将构建环境的标志位build_flag改为生产环境
    • 此时,会先将library编译上传到Maven正式仓库上,然后在编译app的时候,会从Maven正式仓库里拉去最新的library库,然后进行打正式包。
    • 打包完成后,会将build_flag修改为开发环境

config.gradle是一个自己新建的gradle,用来全局存放项目的版本号,编译环境等

Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖_第3张图片

1.实现 Android Library上传到Maven仓库

这部分只是实现了将Android的Library上传到了Maven仓库
具体详见我的另一篇博客 Android Module上传到Maven仓库 及 实现同时上传到多个Maven仓库,新版 Gradle7.0 / 老版 Gradle6.5 Maven仓库上传配置

2.通过build_flag标志来判断编译环境

新建一个config.gradle,用来全局存放项目的版本号,编译环境等

ext.config = [
	"versionCode":1,
	"versionName":"1.0.0",
	"build_flag":"dev"
]

3.修改maven_upload.gradle

apply plugin: 'maven'

def RELEASE_REPOSITORY_URL = "http://xxxxxxxx/release/" //TODO <------- 这个修改为正式的Maven仓库地址
def SNAPSHOT_REPOSITORY_URL = "http://xxxxxxxx/snapshot/" //TODO <------- 这个修改为快照的Maven仓库地址
def REPOSITORY_URL = VERSION_NAME.endsWith("-SNAPSHOT") ? SNAPSHOT_REPOSITORY_URL : RELEASE_REPOSITORY_URL
def NEXUS_USERNAME = "maven账号" //TODO <------- 这个修改为Maven仓库的账号
def NEXUS_PASSWORD = "maven密码" //TODO <------- 这个修改为Maven仓库的密码
logger.info("groupId = %s\t\nartifactId = %s\t\nversion = %s\t\nrepository = %s\t\n", GROUP, POM_ARTIFACT_ID, VERSION_NAME, REPOSITORY_URL)
afterEvaluate { project ->
    uploadArchives {
        repositories.mavenDeployer {
            pom.groupId = GROUP
            pom.artifactId = POM_ARTIFACT_ID
            pom.version = VERSION_NAME
            repository(url: REPOSITORY_URL) {
                authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
            }
        }
    }
    task androidSourcesJar(type: Jar) {
        classifier = 'sources'
        from android.sourceSets.main.java.sourceFiles
    }
    artifacts {
        archives androidSourcesJar
    }
}

4. 根目录build.gradle添加maven仓库地址

repositories {
	maven {
		url "http://xxxxxxxx/release/" //TODO <------- 这个修改为正式的Maven仓库地址
	}
	maven {
		url "http://xxxxxxxx/snapshot/" //TODO <------- 这个修改为快照的Maven仓库地址
	}
}

5.实现Android Maven 快照上传依赖

lib1的build.gradle

ext.GROUP = "com.heiko.test"
ext.POM_ARTIFACT_ID = "lib1"
String versionName = android.defaultConfig.versionName
if ("release" != buildConfig.build_flag) {
    versionName += "-SNAPSHOT"
}
ext.VERSION_NAME = versionName
//引用gradle_upload.gradle
apply from: "${project.rootDir}/maven_upload.gradle"

lib2的build.gradle

ext.GROUP = "com.heiko.test"
ext.POM_ARTIFACT_ID = "lib2"
String versionName = android.defaultConfig.versionName
if ("release" != buildConfig.build_flag) {
    versionName += "-SNAPSHOT"
}
ext.VERSION_NAME = versionName
//引用gradle_upload.gradle
apply from: "${project.rootDir}/maven_upload.gradle"

6.上传Library到Maven长裤

添加上面的代码之后,我们点击sync,同步下代码
可以发现多了一个uploadArchivesGradle Task
Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖_第4张图片
我们双击运行,一段时间后,出现如下成功的提示,说明就上传到maven仓库成功了
Android Maven仓库搭建 - 实现自动化打包自动拉取最新maven依赖_第5张图片

7.在app上进行maven依赖

app模块的build.gradle

dependencies{
	configurations.all {
        resolutionStrategy.cacheDynamicVersionsFor 1,'days'
        resolutionStrategy.cacheChangingModulesFor 0,'seconds'
    }

	String lib1 = 'com.heiko.test:lib1:' + buildConfig.version_number
	if ("release" != buildConfig.build_flag) {
		lib1 += "-SNAPSHOT"
	}
	implementation (lib1) {
		changing = true
	}

	String lib2 = 'com.heiko.test:lib2:' + buildConfig.version_number
	if ("release" != buildConfig.build_flag) {
		lib2 += "-SNAPSHOT"
	}
	implementation (lib2) {
		changing = true
	}
}

这里需要注意的是cacheDynamicVersionsForcacheChangingModulesForchanging = true

  • cacheDynamicVersionsFor : 动态版本,你见过的像 3.+ 这种就是动态版本,它会取检查到的最高的版本号。又比如 latest.integration ,它也是动态版本
  • cacheChangingModulesFor : 变化模块,像 0.2-SNAPSHOT 这种后面带 SNAPSHOT 的版本
  • changing = true : 加了changing=true 就和添加标记SNAPSHOT后缀功能是一样的

8.进行使用

开发阶段

我们直接依赖源代码,方便实时编译调试,此时,IS_DEV标志位为true

IS_DEV这个标志位只在本地做修改,不上传到gitlab上,也就是说gitlab上这个值永远是false

if(IS_DEV.toBoolean()){
	//使用源码的依赖
	implementation project(path: ':lib1')
	implementation project(path: ':lib2')
} else {
	//使用maven的依赖
	String lib1 = 'com.heiko.test:lib1:' + buildConfig.version_number
	if ("release" != buildConfig.build_flag) {
		lib1 += "-SNAPSHOT"
	}
	implementation (lib1) {
		changing = true
	}

	String lib2 = 'com.heiko.test:lib2:' + buildConfig.version_number
	if ("release" != buildConfig.build_flag) {
		lib2 += "-SNAPSHOT"
	}
	implementation (lib2) {
		changing = true
	}
}

打develop包

当将代码上传到gitlab上,并合并到develop分支后,Jenkins会自动执行脚本打包
此时,IS_DEV标志位为false,buildConfigbuild_flagdevelop

打包流程为

1.执行 git pull 更新代码到最新
2.执行uploadArchives脚本上传Library到Maven仓库
3.执行assemble脚本进行打包,这时候因为build_flagdevelop,所以依赖的是快照的maven,会拉取到最新的快照依赖
4.复制文件到指定目录,修改文件名之类的操作

打生产包 (正式包)

当代码被合并到master分支,Jenkins会自动执行脚本打包
此时,IS_DEV标志位为false,buildConfigbuild_flag会被Jenkins自动修改为release
这个打包完成后,Maven依赖可以直接对外部团队提供了

打包流程为

1.执行 git pull 更新代码到最新
2.buildConfig的versionCodeversionName自动增加1
3.buildConfig的build_flag修改为release
4.执行uploadArchives脚本上传Library到Maven仓库
5.执行assemble脚本进行打包,这时候因为build_flagrelease,所以依赖的是正式的maven,会拉取到对应版本号的maven依赖,而对应版本号我们已经在前面步骤中自动+1了,所以不会冲突
6.buildConfig的build_flag修改回develop
7.执行git push上传代码
8.复制文件到指定目录,修改文件名之类的操作

至此,自动化打包maven的搭建我们就配置完毕了

其他

感谢
Android Studio处理SNAPSHOT依赖项
深踩Android Studio 缓存的坑及解决方法

你可能感兴趣的:(Android日常经验,Android,自动化打包,Maven,快照,jenkins)