I have 2 lib modules : library
, library2
, and use android-maven-publish to publish my multi-modules android project with multi-productFlavors
build.gradle
in library:
apply plugin: 'com.android.library'
apply plugin: 'digital.wup.android-maven-publish'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "runner"
productFlavors {
sit {
dimension "runner"
}
dev {
dimension "runner"
}
uat {
dimension "runner"
}
prd {
dimension "runner"
}
}
}
dependencies {
...
implementation project(':android-library2')
}
apply from: '../publish.gradle'
build.gradle
in library2:
apply plugin: 'com.android.library'
apply plugin: 'digital.wup.android-maven-publish'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "runner"
productFlavors {
sit {
dimension "runner"
}
dev {
dimension "runner"
}
uat {
dimension "runner"
}
prd {
dimension "runner"
}
}
}
dependencies {
...
}
apply from: '../publish.gradle'
publish.gradle:
publishing.publications() {
android.libraryVariants.all { variant ->
"maven$project.archivesBaseName${variant.name.capitalize()}Aar"(MavenPublication) {
from components.findByName("android${variant.name.capitalize()}")
groupId 'com.android.saleshelp'
artifactId project.archivesBaseName + "-${variant.name.capitalize()}"
version android.defaultConfig.versionName
}
}
}
publishing.repositories {
mavenLocal()
}
when I run task publish
in library, I got the following error:
* What went wrong:
Could not determine the dependencies of task ':android-library2:publishMavenandroid-library2SitReleaseAarPublicationToMavenLocalRepository'.
> Publishing is not able to resolve a dependency on a project with multiple publications that have different coordinates.
Found the following publications in project ':android-library':
- Maven publication 'mavenandroid-libraryPrdDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-PrdDebug:1.0
- Maven publication 'mavenandroid-libraryPrdReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-PrdRelease:1.0
- Maven publication 'mavenandroid-libraryDevDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-DevDebug:1.0
- Maven publication 'mavenandroid-libraryDevReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-DevRelease:1.0
- Maven publication 'mavenandroid-libraryUatDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-UatDebug:1.0
- Maven publication 'mavenandroid-libraryUatReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-UatRelease:1.0
- Maven publication 'mavenandroid-librarySitDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-SitDebug:1.0
- Maven publication 'mavenandroid-librarySitReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-SitRelease:1.0
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
If I removed apply from: '../publish.gradle'
in build.gradle
of library2, task :library:publish
can be run successfully. But because of I want to publish library2
independently, so library2
must apply from: '../publish.gradle'
How can I do for this error? Thanks.
Environment: gradle 4.4 ~ 4.9-rc1
It is a known limitation of the maven-publish
plugin.
When a project dependency has multiple publications, the maven-publish
plugin can't choose them properly. In your case, when the maven-publish
plugin try to resolve implementation project(':android-library2')
, it can't decide what to write to the pom file, because the android-library2
project has multiple publications with different coordinates.
In Gradle 4.9-rc-1 was intruduced an alias property. If you mark all publication as alias and you have a main publication, then this can solve your problem. But in my opinion this does not solve your problem completely, because the maven publish plugin will write the main publication's coordinates into the pom file independent of product flavors.
If that does not help, then you can use the workaround in the original bug report.
I ran into the same problem, which appears to still be a limitation of maven-publish
. I found a workaround that works pretty well for me:
publishing {
repositories {
def repositoryName = 'X'
maven { name = repositoryName /* ... */ }
afterEvaluate {
def targetComponent = System.getProperty("targetComponent")
components.each { component ->
if (component.name != targetComponent) return
def appendage = component.name.replaceAll("[Rr]elease", "")
if (!appendage.isEmpty()) appendage = "-$appendage"
publications {
"${component.name}"(MavenPublication) {
from component
artifactId = project.name + appendage
}
}
publish.doFirst {
if (targetComponent == null)
throw new GradleException("Deployment requires specifying -DtargetComponent option")
}
}
}
}
}
Invoke with gradle project:publish -DtargetComponent=release
, or whatever other component you're trying to release.
Explanation: Gradle sees intra-workspace dependencies at the project
level, but it outputs to Maven repos at the component
level. Maven doesn't have this same project vs. component concept. This also means you can't specify, in a Gradle dependencies
block, which component of a Maven-style dependency you are looking for (since Maven doesn't really get that concept). The result: Gradle can't figure out how to write the POM file entry for an intra-workspace dependency with multiple publication
s.
Minimal problem example:
// a/build.gradle:
publications {
release(MavenPublication) { from components.release }
debug(MavenPublication) { from components.debug; artifactId = 'a-debug' }
}
// b/build.gradle:
dependencies {
project(':a') // ERROR: should this be 'group:b:1.0.0' or 'group:b-debug:1.0.0'?
}
The workaround works by having you indicate which component you want to deploy, across all projects, before configuration time. During configuration, Gradle only generates one publication per project, based on the component you flagged, adding the extra information Gradle needs to map intraproject deps to Maven-style deps. You only need to specify the command line argument when you want to deploy; the conditional is bound to the publish
task, so it only goes off if that task is actually invoked.
Limitations:
artifactId
; you could change this if you wanted togradle publish --dry-run
doesn't show meaningful resultsa:release
binds to b:release
and a:debug
binds to b:debug
)EDIT: I had called my task deploy
but renamed it to publish
when writing this answer. Turns out maven-publish
creates a task publish
automatically which does exactly what I wanted. I've updated the code snippet to reflect this.
EDIT2: Throw GradleException
instead; it's slightly more idiomatic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With