scijava / pom-scijava

Friendly base POM for all SciJava-based software
https://imagej.net/BOM
The Unlicense
24 stars 33 forks source link

Gradle catalog + platform #268

Closed elect86 closed 3 months ago

elect86 commented 4 months ago

Gradle Catalog and Platform properly generated and the corresponding artifacts get added alongside the main publication

We'd still need to verify whether this version does matter or less, we'll see with a snapshot publications maybe?

Another cool thing Gradle Platform can do is aligning to boms as well, like here

api(platform("com.fasterxml.jackson:jackson-bom:" + 
    libs.com.fasterxml.jackson.core.jacksonCore.get().version))

But we need to coordinate this, there are other boms which may be interesting, such as jakarta.jakartaee-bom and tons of google ones, which is a mess for someone like me which is not familiar..

elect86 commented 4 months ago

Just pushed a working sketch of plugins to enforce a pure declarative Gradle build script

plugins under declarative, all the different test under declarative-playground

It's based on the current wip of Gradle

elect86 commented 4 months ago

so, together with @jjohannes, we clean up the project the best possible

the only build directory isn't possible to move is .gradle

I tested mvn install and looks fine

ctrueden commented 4 months ago

@elect86 Thank you for continuing to work on this! And @jjohannes thank you for reviewing!

Here is the current error happening on CI:

java.io.IOException: Cannot run program "./gradlew" (in directory "/home/runner/work/pom-scijava/pom-scijava/target/gradle-scijava"): error=2, No such file or directory

With 5a514ac3113c192ec7b2e19e63fd5ec1d43360b7 I tried to be very explicit about the intended working directory, but even then the same error persists. So more investigation is needed.

elect86 commented 4 months ago

I have no idea why the CI is so problematic... locally mvn install works absolutely fine with ./gradlew on linux..

elect86 commented 4 months ago

with an ls it work fine ./gradlew... wth

elect86 commented 4 months ago

So, here Maven runs Gradle just fine, we can see it start downloading the distro

And here the task is executed

> Task :generateCatalogAndPlatform

However, after a while the task gets executed once again here

and a third time here

and then the crash happens after a while here

elect86 commented 4 months ago

SO post

elect86 commented 3 months ago

The problem lies somewhere in the complexity of the CI

here and here

ctrueden commented 3 months ago

@elect86 and I spoke earlier today about the issue maybe being the mavenEvaluate function calls, which invoke mvn ... exec:exec. The purpose of mavenEvaluate is not to actually run the build, but rather only evaluate expressions, typically to get the values of Maven properties and so forth. The build script uses it to obtain the SCM URL for the project, as well as the project version, and version of the maven-gpg-plugin (to decide whether a particular build hack is needed).

While it does seem like quite a coincidence that the Gradle-specific logic is triggered multiple times, and there are three "extra" invocations of mvn in the ci-build.sh script, the mavenEvaluate function is not actually the culprit. On the CI, we see the message:

  --> maven-gpg-plugin version OK: 3.1.0

which gets printed after all three of the mavenEvaluate calls happen... but it not until the main build (== Building the artifact locally only ==) that the Gradle logic is invoked for the first time. And that time it works, including installation of the gradle-generated artifacts into the local Maven repository cache.

No, the issue is that the Gradle platform/catalog logic happens again as part of the integration testing, a.k.a. the "mega melt": a subsequent step to ensure that all component versions work together as advertised. To reproduce the problem locally, you can invoke tests/run.sh from a pom-scijava working copy.

Specifically, the script performs the following (slightly simplified) commands to set up a temporary doctored pom-scijava parent for use with local testing:

mkdir -p target
cp pom.xml target/pom.xml
mvn -B -f target/pom.xml versions:set -DnewVersion=999-mega-melt
mvn -B -f target/pom.xml install

It seems Maven sets the CWD and ${basedir} to match the directory of the pom.xml file passed via the -f flag.

To fix, I changed the mvn ... install line, which was running through the Maven lifecycle including the attempted gradle catalog+platform generation, to mvn ... install:install, which runs only the install goal itself, which in the case of the mega-melt is all that's needed: we just need the special 999-mega-melt version of the POM to be available locally as a parent for the individual components that will be rebuilt. 9ce8ddd357ea84aeac1d3fc39349fed5f117ad72

Once I fixed that initial issue, there still remained another problem, however. The pom-scijava POM is intended as the parent POM for downstream components. As currently written, any project extending this updated version of pom-scijava inherits the exec-maven-plugin execution that tries to launch gradle. We do not want this; the gradle execution is supposed to occur only for the pom-scijava build itself, not builds of downstream components that extend it. I implemented a workaround with 9cd90000e55bd5d79911c152ae1adadd5e04a357, which wraps the gradle catalog+platform generation into a profile that gets activated only when a scijava-gradle directory is present in the project basedir. That way, when building pom-scijava itself, the gradle build runs, and when using pom-scijava as a parent in other projects, it does not (unless they happen to have a file called scijava-gradle in their basedir, which is highly unlikely).

elect86 commented 3 months ago

Awesome, thanks for taking care of this

So now, can it be merged? Can we test it with a snapshot publication?

elect86 commented 3 months ago

thanks dear