New publishing model best practices for multi-project builds and generated POM


(steve) #1

What is considered best practice for new publishing model in multi-project builds where root project sets up the publication in a subprojects closure and each subproject needs to affect value(s) in the POM? Specific values I am thinking of here are name and description. Gradle POM generation already handles the different artifact names across the projects.

Should each subproject just do the following snippet individually?

publications {
    mavenCustom(MavenPublication) {
        pom.withXml {
            asNode()
                    .appendNode( 'name', "This (sub)project's specific name" )
                    .appendNode( 'description', "This (sub)project's specific description" )
        }
    }
}

Or is there a way to define POM name/description on the subprojects (as prooperties, etc) and have that available when the root project runs its subprojects{} closure?

Other options?


(steve) #2

Actually I found that you cannot have each subproject attempt to access that named publication. That leads to errors : “Publication with name ‘main’ added multiple times”

So each reference (once in the root project’s subprojects closure and then in the subproject build script) attempts to add the publication. So that option is not really an option…


#3

You can access a project properties directly in the ‘publishing’ block, even if it’s defined in a ‘subprojects’ block. (The ‘publishing’ block is evaluated lazily on first access):

subprojects {
  apply plugin: 'maven-publish'
    version = '1.0'
  group = 'myorg'
    publishing {
    publications {
      maven(MavenPublication) {
        pom.withXml {
          asNode().appendNode("name", project.name)
          asNode().appendNode("custom", project.custom)
          asNode().appendNode("description", project.description)
        }
      }
    }
  }
}
  project('projectA') {
  description = "Project A"
  ext.custom = "custom value"
}

You can also further customise the publication directly in a project, like this:

project('projectA') {
  publishing {
    publications {
      maven {
        // Do subproject-specific stuff here
     }
  }
}

You’ll see that no type is given to the ‘maven’ publication, signifying it is an accessor.

Note that ‘publications’ is a PublicationContainer, which leverages the newly added PolymorphicDomainObjectContainer support. No doubt that more documentation and examples are required to clarify the usage of this new type of model element.