vanniktech / gradle-maven-publish-plugin

A Gradle plugin that publishes your Android and Kotlin libraries, including sources and javadoc, to Maven Central or any other Nexus instance.
https://vanniktech.github.io/gradle-maven-publish-plugin
Apache License 2.0
1.31k stars 120 forks source link

Automatic BOM constraints collection #591

Open swankjesse opened 1 year ago

swankjesse commented 1 year ago

In Okio we love this plugin!

We use it to publish a BOM with Okio’s own dependencies. This build file used to look like this:

dependencies {
  constraints {
    api(projects.okio)
    api(projects.okioFakefilesystem)
    if (kmpJsEnabled) {
      // No typesafe project accessor as the accessor won't exist if kmpJs is not enabled.
      api(project(":okio-nodefilesystem"))
    }
  }
}

Unfortunately, this caused us to publish an incomplete BOM (issue). In particular, our dependencies lists okio but not okio-jvm (sample incomplete module file). This is particularly problematic for us as we switched from being a JVM library to a multiplatform library.

It also means we have to remember to add subprojects to our okio-bom/build.gradle.kts file when they are added. We forgot to add our okio-assetfilesystem artifact when we added that. Whoops!

To address this I made a helper function collectBomConstraints() that collects up all the artifacts that belongs in the BOM and adds them. Our BOM build file now looks like this:

collectBomConstraints()

Would you be interested in having a similar function in this plugin? I’m happy to contribute it, or have y’all write your own, or build upon the function in Okio (PR). Note that the Okio implementation is incomplete; it only knows how to collect targets of the types needed by Okio.

Thanks again!

gabrielittner commented 1 year ago

I'm generally open to adding something like this. My only concern would be project isolation incompatibility in the future because of rootProject.subprojects {}. Maybe the function in the plugin could be addBomConstraints(project: Project) and then consumers can do either do rootProject.subprojects { addBomConstraints(it) } on their side or call it manually with specific projects.

swankjesse commented 1 year ago

Oooh good catch. Interrogating the project graph is gonna be bad for development, especially if it happens when we’re not actively building a BOM.

How does the publish plugin coordinate multiple independent subprojects for closing the release? I assume it aggregates that somehow, though maybe it has an easier time because it can operate like a finalize task.

The ultimate API for this would automatically add all published projects to the BOM without additional setup.

gabrielittner commented 1 year ago

The task to create the staging repo is tied to SonatypeRepositoryBuildService which means that Gradle will enforce that only one of those tasks will run at a time. We'll then keep the id of the created repo in the build service and the create task will no-op if there already is one. Unfortunately not helpful for doing something at config time like here.