// 打印所有组件名
components.all {
println "it: " + it.name
}
/**
* 打包源码
*/
task sourcesJar(type: Jar) {
archiveClassifier = "sources"
from android.sourceSets.main.java.srcDirs
}
1/maven-publish
注意事项:因为组件仅在 afterEvaluate 阶段创建,所以必须使用 afterEvaluate() 生命周期方法配置发布
release 正式包
apply plugin: 'maven-publish'
afterEvaluate {
publishing {
publications {
release(MavenPublication) {
from components.release
groupId = GROUP_ID
artifactId = ARTIFACT_ID
version = VERSION
}
}
}
}
debug 测试包
apply plugin: 'maven-publish'
afterEvaluate {
publishing {
publications {
debug(MavenPublication) {
from components.debug
groupId = GROUP_ID
artifactId = ARTIFACT_ID
version = VERSION
}
}
}
}
allVariants 全部版本包
apply plugin: 'maven-publish'
afterEvaluate {
publishing {
publications {
android.libraryVariants.all { variant ->
"${variant.name}Aar"(MavenPublication) {
from components.findByName("${variant.name}")
groupId = GROUP_ID
artifactId = ARTIFACT_ID
version = VERSION + "-${variant.name}"
}
}
}
}
}
moreMaven 多 maven
注意事项:默认包含本地 maven(mavenLocal() | ~/.me/repository)
apply plugin: 'maven-publish'
afterEvaluate {
publishing {
publications {
......
}
repositories {
maven {
// 第二个必须显示指定 name
name = "MavenOfProject"
url = uri("$rootDir/repo/")
}
}
}
}
上述代码可以直接添加到 lib 项目的 build.gradle
文件底部, 也可以独立到一个 upload.gradle
文件里在 lib 项目的 build.gradle
文件底部引入
引入方式:
// maven库配置
ext {
USERNAME = "xxx"
PASSWORD = "xxx"
GROUP_ID = "com.xxx.xxx"
ARTIFACT_ID = "xxx"
VERSION = "1.0.0"
}
apply from: "$rootDir/upload.gradle"
Sync Now
项目编译完成后就可以看到下图所示:
- publish 全部打包上传 (所有variants,所有 maven,不包含本地)
- publishAll…ToXXXRepository 打包指定 maven 的所有 variants
- publishDebug… 上传 debug 版本
- publishRelease… 上传 release 版本
- publishToMavenLocal 上传到本地Maven缓存中(通常为$ USER_HOME / .m2 / repository)
2/maven (已过时)
2.1/关键词说明
2.1.1/defaultPublishConfig
android.defaultPublishConfig
控制项目默认发布版本, 默认值是release
2.1.2/打包 aar
maven 的默认上传任务根据android.defaultPublishConfig
的值决定, 默认情况下是 bundleReleaseAar, 也就是上传 release 版本的 aar 包
当然 maven 上传的 aar 是可以修改的, 前提是需要先打包指定的 aar, 然后添加到artifacts
中2.1.3/包含打包的任务
包含打包的任务有: bundleXXXAar和 assembleXXX 系列, 打包所有版本就只有assemble
任务可以做到
如果项目设置了productFlavors
, 在打包发布指定flavors + debug/release
版本时就需要依赖bundle + Flavor + Debug/ReleaseAar
也可以是assemble + Flavor + Debug/Release
2.1.4/artifacts
artifacts 可以理解为要打包的文件, 默认情况下包含xxx.aar
xxx 为项目名, aar 版本为默认版本
artifacts 的配置是增量模式, 可以同时定义在所有任务外部和任务内部, 在任务外部就是全局配置, 发布时合并外部和内部的配置
当发布指定版本 aar 的时候先需要添加到 artifacts 中, 如果定义了多个发布 task 里面都添加了指定版本的 aar 可能会出现 aar 重复或找不到的问题, 所以 task 内部的 aar 最好用 doLast{} 进行隔离, 等到 task 执行的时候再添加 ```groovy artifacts { archives sourcesJar }
// or task xxx(type: Upload) { … repositories { maven… { … doLast { artifacts { archives sourcesJar archives file: file(“build/outputs/aar/xxx.aar”) // 也可以通过 task 来获取 aar archives bundleXXXAar } } … } } }
<a name="ZjUP4"></a>
#### 2.1.5/pom
`.pom` 文件是项目的配置文件包含项目信息和依赖配置信息, 有时候在发布指定版本的 aar 时需要定制 pom 文件里的依赖配置信息
```groovy
// 默认版本, 默认版本不支持 withXml 操作
pom.groupId = GROUP_ID
pom.artifactId = ARTIFACT_ID
pom.version = VERSION + "-SNAPSHOT"
// 指定版本 variantName
pom(variantName).groupId = GROUP_ID
pom(variantName).artifactId = ARTIFACT_ID
pom(variantName).version = VERSION + "-SNAPSHOT"
pom(variantName).withXml {
...
}
pom.withXml 就是配置 .pom
文件
// variantName 为指定版本, 可不设置(默认), 发布指定版本时需要设置
pom(variantName).withXml {
// 添加依赖节点的闭包
def addNode = { rootNode, list ->
list.each {
if (null != it.group) {
def dependency = rootNode.appendNode('dependency')
dependency.appendNode('groupId', it.group)
dependency.appendNode('artifactId', it.name)
dependency.appendNode('version', it.version)
dependency.appendNode('scope', 'compile')
}
}
}
// 创建根节点
def rootNode = asNode().appendNode('dependencies')
// 查询所有 implementation, api, compile 依赖
def implementations = configurations.findByName("implementation").allDependencies
// 查询所有 variantNameImplementation, api, compile 依赖
def variantNameImplementations = configurations.findByName("${variantName}Implementation").allDependencies
// 遍历添加依赖节点
addNode(rootNode, implementations)
addNode(rootNode, variantNameImplementations)
}
2.1.6/mavenInstaller/mavenDeployer
mavenInstaller
发布到本地默认 maven 库, 通过 mavenLocal()
库引用, 无需设置 URL
task xxx(type: Upload) {
...
repositories {
mavenInstaller {
...
}
}
}
使用方式:
第一种方式: 在根目录的 build.gradle 添加配置
...
allprojects {
repositories {
...
mavenLocal()
...
}
}
...
第二种方式: 在 module 的 build.gradle 添加配置
...
android {
...
repositories {
...
mavenLocal()
...
}
...
}
...
mavenDeployer
发布到指定 maven 库, 通过 URL 指定 maven 地址
// 以项目根目录下的 /repo/release 目录作为 maven 仓库
def URL_LOCAL = uri("$rootDir/repo/release")
// 以私服作为 maven 仓库
def URL_REMOTE = "http://xxx/repo/release"
task xxx(type: Upload) {
...
repositories {
mavenDeployer {
...
repository(url: URL_REMOTE/URL_LOCAL) {
// 设置用户名, 密码, 没有可以不添加
authentication(userName: USERNAME, password: PASSWORD)
}
...
}
}
}
使用方式与 mavenInstaller 类似, mavenLocal() 修改为 maven { url: xxx }
maven {
url 'http://x.x.x.x:8081/repository/'
credentials {
username 'xxx'
password 'xxx'
}
}
2.2/非默认版本/多版本
有时会因为业务的需要分出多种版本, 在发布其他非默认版本时需要做一些配置
2.2.1/发布指定版本
task xxx(type: Upload) {
...
repositories {
maven...... {
...
def variantName = "debug"
def variantBaseName = "debug"
def buildTypeName = "debug"
def fileName = "${project.name}-${variantBaseName}.aar"
doLast {
artifacts {
archives bundleDebugAar
}
}
addFilter(variantName) { artifact, file ->
def artifactName = artifact.name
def artifactType = artifact.type
if ("aar" == artifactType) {
return artifactName == fileName
} else {
true
}
}
pom(variantName).groupId = GROUP_ID
pom(variantName).artifactId = ARTIFACT_ID + "-" + variantBaseName
pom(variantName).version = VERSION
pom(variantName).withXml {
// 添加依赖包节点的闭包
def addNode = { rootNode, list ->
list.each {
if (null != it.group) {
def dependency = rootNode.appendNode('dependency')
dependency.appendNode('groupId', it.group)
dependency.appendNode('artifactId', it.name)
dependency.appendNode('version', it.version)
dependency.appendNode('scope', 'compile')
}
}
}
// 创建根节点
def rootNode = asNode().appendNode('dependencies')
def implementations = configurations.findByName("implementation").allDependencies
def variantImplementations = configurations.findByName("${buildTypeName}Implementation").allDependencies
addNode(rootNode, implementations)
addNode(rootNode, variantImplementations)
}
}
}
}
2.2.2/发布全部版本
发布全部版本原理同单个版本基本一致, 主要区别在于通过读取版本配置信息进行遍历发布
// 创建并发布所有变体
task xxx(type: Upload) {
dependsOn "assemble"
...
repositories {
maven...... {
...
android.libraryVariants.all { variant ->
def variantName = variant.name
def variantBaseName = variant.baseName
def buildTypeName = variant.buildType.name
def fileName = "${project.name}-${variantBaseName}.aar"
doLast {
artifacts {
archives file: file("build/outputs/aar/${fileName}")
}
}
addFilter(variantName) { artifact, file ->
def artifactName = artifact.name
def artifactType = artifact.type
if ("aar" == artifactType) {
return artifactName == fileName
} else {
true
}
}
pom(variantName).groupId = GROUP_ID
pom(variantName).artifactId = ARTIFACT_ID + "-" + variantBaseName
pom(variantName).version = VERSION
pom(variantName).withXml {
// 添加依赖包节点的闭包
def addNode = { rootNode, list ->
list.each {
if (null != it.group) {
def dependency = rootNode.appendNode('dependency')
dependency.appendNode('groupId', it.group)
dependency.appendNode('artifactId', it.name)
dependency.appendNode('version', it.version)
dependency.appendNode('scope', 'compile')
}
}
}
// 创建根节点
def rootNode = asNode().appendNode('dependencies')
def implementations = configurations.findByName("implementation").allDependencies
def variantImplementations = configurations.findByName("${buildTypeName}Implementation").allDependencies
addNode(rootNode, implementations)
addNode(rootNode, variantImplementations)
}
}
}
}
}
2.2.3/完整示例代码
apply plugin: 'maven'
// 打包源码
task sourcesJar(type: Jar) {
group = 'uploadMaven'
archiveClassifier = "sources"
from android.sourceSets.main.java.srcDirs
}
// 压缩生成归档文件
task packZip(type: Zip) {
group = 'uploadMaven'
archiveBaseName = project.name
archiveAppendix = VERSION
archiveClassifier = "all"
archiveExtension = "zip"
// 打包根路径
from project.projectDir.absolutePath
// 输出路径
// destinationDir = project.projectDir.absoluteFile
exclude '**.zip'
exclude '**.iml'
exclude '**/**.iml'
exclude 'build/**'
exclude '.idea/**'
exclude '.gradle/**'
exclude 'gradle/**'
exclude '**/build/**'
exclude 'repo/**'
}
artifacts {
archives sourcesJar
archives packZip
}
def URL_LOCAL = uri("$rootDir/repo/")
def URL_REMOTE = "http://x.x.x.x:8081/repository/"
task upload2Local(type: Upload) {
group = "uploadMaven"
configuration = configurations.archives
uploadDescriptor = true
repositories {
mavenInstaller {
pom.groupId = GROUP_ID
pom.artifactId = ARTIFACT_ID
pom.version = VERSION
}
}
}
task uploadDebug2Project(type: Upload) {
dependsOn "bundleDebugAar"
group = "uploadMaven"
configuration = configurations.archives
uploadDescriptor = true
repositories {
mavenDeployer {
repository(url: URL_LOCAL)
def variantName = "debug"
def variantBaseName = "${project.name}-${variantName}"
def fileName = "${project.buildDir}/outputs/aar/${variantBaseName}.aar"
artifacts {
archives file: file(fileName)
}
addFilter(variantName) { artifact, file ->
def artifactName = artifact.name
def artifactType = artifact.type
if ("aar" == artifactType) {
return variantBaseName == artifactName
} else {
true
}
}
pom(variantName).groupId = GROUP_ID
pom(variantName).artifactId = ARTIFACT_ID + "-" + variantName
pom(variantName).version = VERSION
pom(variantName).withXml {
// 添加依赖包节点的闭包
def addNode = { rootNode, list ->
list.each {
if (null != it.group) {
def dependency = rootNode.appendNode('dependency')
dependency.appendNode('groupId', it.group)
dependency.appendNode('artifactId', it.name)
dependency.appendNode('version', it.version)
dependency.appendNode('scope', 'compile')
}
}
}
// 创建根节点
def rootNode = asNode().appendNode('dependencies')
def implementations = configurations.findByName("implementation").allDependencies
def variantImplementations = configurations.findByName("${variantName}Implementation").allDependencies
addNode(rootNode, implementations)
addNode(rootNode, variantImplementations)
}
}
}
}
task uploadAll2Remote(type: Upload) {
dependsOn "assemble"
group = "uploadMaven"
configuration = configurations.archives
uploadDescriptor = true
repositories {
mavenDeployer {
// 无需密码
repository(url: URL_LOCAL)
// 需要密码
repository(url: URL_LOCAL) {
authentication(userName: "xxx", password: "xxx")
}
android.libraryVariants.all { variant ->
def variantName = variant.name
def variantBaseName = "${project.name}-${variantName}"
def fileName = "${project.buildDir}/outputs/aar/${variantBaseName}.aar"
artifacts {
archives file: file(fileName)
}
addFilter(variantName) { artifact, file ->
def artifactName = artifact.name
def artifactType = artifact.type
if ("aar" == artifactType) {
return variantBaseName == artifactName
} else {
true
}
}
pom(variantName).groupId = GROUP_ID
pom(variantName).artifactId = ARTIFACT_ID + "-" + variantName
pom(variantName).version = VERSION
pom(variantName).withXml {
// 添加依赖包节点的闭包
def addNode = { rootNode, list ->
list.each {
if (null != it.group) {
def dependency = rootNode.appendNode('dependency')
dependency.appendNode('groupId', it.group)
dependency.appendNode('artifactId', it.name)
dependency.appendNode('version', it.version)
dependency.appendNode('scope', 'compile')
}
}
}
// 创建根节点
def rootNode = asNode().appendNode('dependencies')
def implementations = configurations.findByName("implementation").allDependencies
def variantImplementations = configurations.findByName("${variantName}Implementation").allDependencies
addNode(rootNode, implementations)
addNode(rootNode, variantImplementations)
}
}
}
}
}
2.3/注意事项
// 发布脚本用户名密码配置
repositories {
mavenDeployer {
repository(url: URL_LOCAL) {
authentication(userName: "xxx", password: "xxx")
}
}
}
// 项目配置脚本用户名密码配置
allprojects {
repositories {
maven {
credentials {
username 'xxx'
password 'xxx'
}
url URL_LOCAL
}
}
}
3/不同阶段的命名方案
- 规划:版本名 + “-SNAPSHOT”
- 测试:版本名 + “-debug(1..n)”
- 发布:版本名
测试阶段,为了更快的编译速度可以发布到本地默认的 maven 库。测试完成后再发布到 maven 私服
4/其它
task pVariant() {
doLast {
android.libraryVariants.all { variant ->
println ">>>>>>>>> name: ${variant.name}"
println ">>>>>>>>> baseName: ${variant.baseName}"
println ">>>>>>>>> flavorName: ${variant.flavorName}"
println ">>>>>>>>> buildTypeName: ${variant.buildType.name}"
}
}
}