javamavenpom.xmlparent-pomrenovate

How to get renovate to update the java version in my pom.xml


I want renovate to keep my Java versions in my pom.xml updated. I had a look on the information in the renovate docs and it seems like it should work out of the box:
https://docs.renovatebot.com/java/#lts-releases
https://docs.renovatebot.com/presets-workarounds/#workaroundsjavaltsversions

My renovate config looks like this:

 {
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "packageRules": [
    {
      "matchPackageNames": [
        "maven-wrapper"
      ],
      "enabled": false
    }
  ],
  "configMigration": true,
  "extends": [
    "config:recommended",
    "group:allNonMajor",
    ":approveMajorUpdates"
  ]
}

And my pom looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>demo</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/>
    </parent>
    <groupId>demo</groupId>
    <artifactId>demo-service</artifactId>
    <version>0.70.2-SNAPSHOT</version>
    <name>demo-service</name>
    <description>Demo project</description>
    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>${jib-maven-plugin.version}</version>
                <configuration>
                    <from>
                        <image>eclipse-temurin:${java.version}-alpine</image>  <----
                    </from>
                    ....
            </plugin>
        </plugins>
    </build>
</project>

I'm overwriting the Java version that the Spring Boot Starter Parent uses with <java.version>17</java.version>, I also use this to determine the version of the eclipse Temurin base image in JIB.

Renovate won't pick up this dependency/version. What am I doing wrong? There also are no related logs in the debug output.

Update: Thanks to @Gaël J I created a feature request in the renovate project.


Solution

  • I came up with a silly workaround for what I wanted.
    Be aware that this is specifically configured to only get the LTS versions like 17, 21 without the patch versions like 21.0.3+9 as I only need the starting number of the release.

    I call the Adoptium API to get a list of all LTS versions of Java using a custom data source and a custom manager in Renovate:

      "customDatasources": {
        "custom_java": {
          "defaultRegistryUrlTemplate": "https://api.adoptium.net/v3/info/available_releases",
          "format": "json",
          "transformTemplates": [
            "{ \"releases\": $map(available_lts_releases, function($v) { { \"version\": $string($v) } }) }"
          ]
        }
      },
      "customManagers": [
        {
          "description": "Parse and change the java version form pom.xml",
          "customType": "regex",
          "datasourceTemplate": "custom.custom_java",
          "depNameTemplate": "java",
          "packageNameTemplate": "",
          "fileMatch": [
            "(^|/)pom\\.xml$"
          ],
          "matchStrings": [
            "<java.version>(?<currentValue>[0-9]+)<\/java.version>"
          ]
        }
      ]
    

    How it works step by step:

    The custom datasouce calls an Adoptium API that returns all LTS Java versions. "defaultRegistryUrlTemplate" "https://api.adoptium.net/v3/info/available_releases",
    This results in the response:

    {
        "available_lts_releases": [
            8,
            11,
            17,
            21
        ],
        "available_releases": [
            8,
            11,
            16,
            17,
            18,
            19,
            20,
            21,
            22
        ],
        "most_recent_feature_release": 22,
        "most_recent_feature_version": 23,
        "most_recent_lts": 21,
        "tip_version": 23
    }
    

    Which then gets transformed to a format that Renovate understands using JSONata:

    "transformTemplates": [
        "{ \"releases\": $map(available_lts_releases, function($v) { { \"version\": $string($v) } }) }"
    ]
    

    Result:

    {
      "releases": [
        {
          "version": "8"
        },
        {
          "version": "11"
        },
        {
          "version": "17"
        },
        {
          "version": "21"
        }
      ]
    }
    
    

    Using this JSON array, Renovate knows what versions are available.
    Now we need to create a custom manager that uses the custom datasource:

      "customManagers": [
        {
          "description": "Parse and change the java version form pom.xml",
          "customType": "regex",
          "datasourceTemplate": "custom.custom_java",
          "depNameTemplate": "java",
          "packageNameTemplate": "",
          "fileMatch": [
            "(^|/)pom\\.xml$"
          ],
          "matchStrings": [
            "<java.version>(?<currentValue>[0-9]+)<\/java.version>"
          ]
        }
      ]
    

    The custom manager uses a simple regex to parse and replace the currently used Java version from the pom.xml

    "fileMatch": [
        "(^|/)pom\\.xml$"
    ],
    "matchStrings": [
        "<java.version>(?<currentValue>[0-9]+)<\/java.version>"
    ]
    

    and it gets new versions from the custom datasource

    "datasourceTemplate": "custom.custom_java",