Quarkus update in a gradle multi-module project

I’m ‘chalant’ about this, but it was the least worst option

The experimental quarkus update (or gradle quarkusUpdate) seems like a cool feature that really should graduate out of experimental. I’ve been happily using it in my personal projects and it works quite nicely under Linux conditions; Windows not so much. Sadly though, openrewrite the underlying plugin that is used by quarkus to do its thing doesn’t support gradle multi modules very well. I am, by no means, a gradle expert (who among us really is) and it seems that init scripts in a multi-module don’t run under the same conditions as a single module project (relentless banging on keys like a demented monkey hoping for a Shakespeare-esque moment ended in failure).

The reality here is that I have a java monorepo which is built using gradle; some of the parts are Quarkus based, some aren’t. I still wanted to use quarkus update since it isn’t always a simple edit of gradle.properties when doing the upgrade. This isn’t exciting work yet it might reduce toil for someone so here’s my solution. It’s usable and I’ve used it in to upgrade Quarkus from 3.10 to 3.12.x

  • First of all, write a wrapper script that runs quarkus update --dry-run and capture the recipe that it’s generated by parsing stdout
    • It will fail because something something “rewrite not defined as a configuration” (life is too short)
    • This relies on gradle not deleting the recipe when it fails (which seems brittle)
    • WARNING : apt does not have a stable CLI interface. Use with caution in scripts. springs to mind here.
set -eo pipefail

quarkus_args=()
if ! builtin type -f quarkus >/dev/null 2>&1; then
  echo "No Quarkus; nothing to do"
  exit 2
fi
if [[ -n "$1" ]]; then
  quarkus_args+=("--platform-version=$1")
fi
# This will fail with a exitcode=1, but we capture the recipe.
recipe=$(quarkus update --dry-run "${quarkus_args[@]}" 2>/dev/null | grep "OpenRewrite recipe generated" | cut -f 2 -d':' | sed -e "s/^[[:blank:]]*//" -e "s/[[:blank:]]*$//") || true
if [[ -n "$recipe" ]]; then
  if [[ "$DRY_RUN" != "true" ]]; then
    ./gradlew -Dorg.gradle.daemon=false -PquarkusUpdateConfig="$(realpath "$recipe")" rewriteRun
  else
    echo "Generated $recipe to update quarkus to $1"
  fi
fi
  • Now we can modify our root gradle project to apply the openrewrite plugin if -PquarkusUpdateConfig is set.
    • Most of the specifics are copied from the Qute template that quarkus itself uses to generate the initialisation script that fails to execute.
plugins{
  id 'org.openrewrite.rewrite' version '6.16.4' apply false
}

ext {
  quarkusUpdateConfig = project.findProperty('quarkusUpdateConfig') ?: ''
}

if (quarkusUpdateConfig != "") {
  apply plugin: "org.openrewrite.rewrite"
  repositories {
    mavenCentral()
  }
  dependencies {
    rewrite("org.openrewrite:rewrite-java")
    rewrite("io.quarkus:quarkus-update-recipes:1.0.18")
  }
  rewrite {
    configFile = quarkusUpdateConfig
    activeRecipe("io.quarkus.openrewrite.Quarkus")
    plainTextMask("**/*.adoc", "**/src/test/resources/__snapshots__/**/*.java", "**/*.kt", "**/*.md", "**/src/main/codestarts/**/*.java", "**/*.txt", "**/META-INF/services/**")
  }
}

Bonus Chatter

You might be wondering about the parsing of the arguments because quarkusUpdate doesn’t have to pay much attention to that if you’re always updating to the latest release. Also what’s all this DRY_RUN about? The answer is that of course we’re going to bind this into updatecli and into our preferred CI/CD environment to raise PRs and the like.

name: Update Quarkus

# Use maven repo rather than github-release to avoid the requirement for GITHUB_TOKEN
sources:
  quarkus:
    name: maven artifact release for quarkus
    kind: maven
    spec:
      repositories:
        - "repo1.maven.org/maven2"
      groupid: "io.quarkus.platform"
      artifactid: "quarkus-bom-quarkus-platform-descriptor"
      versionfilter:
        kind: semver
        pattern: "*"

targets:
  quarkusUpdate:
    name: Update Quarkus to ${{ source "quarkus" }}
    kind: shell
    sourceid: quarkus
    spec:
      shell: bash
      command: ./.ci/scripts/quarkus-update.sh
      environments:
        - name: PATH

© all-the-years. All rights reserved.

Powered by Hydejack v9.1.6