'With Gradle, how best to publish a multi-module project to an additional repository as a specific version?

I have this multi-module project structure

proj
├── subprojA
└── subprojB  [depends on subprojA]

Both subprojects are producing a java jar each. I want to do an extra publishing step where the 2 subproject jars would be given version "1.0.0-dev" and they would be pushed to MavenLocal.

It was relatively easy to publish using a new "publication" entity as these are designed to be able to override the project version (not shown, an additional trick to make each publication go to only their respective repo):

devlocal(MavenPublication) {
    from components.java
    version "1.0.0-dev"
    alias true // prevents error "Publishing is not able to resolve a dependency on a project with multiple publications that have different coordinates"
}

However - you guessed it - there is a problem with this. The new publication is "dumb" in the sense that subprojB would depend on the wrong version of subprojA - i.e. the actual project version not 1.0.0-dev. I want the extra publication jars to depend on one-another.

I discover this is not trivial, there are 2 approaches:

  • hack the POM metadata of this extra publication, by iterating through dependencies and changing their versions. This is a daunting task given the outrageous Groovy syntax
  • do something smarter involving a new configuration which declares dependencies with the right version 1.0.0-dev and is published as-is, however while this might be conceptually more natural, is likely even harder because it takes a Gradle artist to avoid the duplication of dependency declarations and putting together the publication, which is not as simple as "from components.java".

Which option is better and can anyone point to an example for either?

Edit: I did find an example for approach #1 here but after implementing it I realise it's not enough, as it only changes POM metadata whereas Gradle uses "Gradle module metadata". Not so lucky to find the same tweaks for Module metadata.



Solution 1:[1]

After much fighting with Gradle it turns out approach #1 requires to switch off "gradle module metadata" and have publication only publish POM files, which can be hacked to contain the right version for the deps. Starting Gradle 6, by default Gradle's own metadata is used instead of POM, which is retained for Maven interoperability. But this metadata seemingly cannot be edited during publication (it can only be edited during resolution in client projects - see this). So the (suboptimal) solution for now is to hack the POM like here and disable Gradle module metadata like this:

tasks.withType(GenerateModuleMetadata) {
    enabled = false
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 haelix