Files
renovate/lib/modules/manager/github-actions/known-actions/java-version-dynamic.ts
Jamie Tanna 967f480f6d fix(manager/github-actions): don't pin partial java-versions
As noted in #46249, `actions/setup-java` documents `java-version` as:

> Java version to install. Supports whole versions, semver ranges,
> early-access versions, and latest.

When the Java version is parsed using the versioning in
`workarounds:javaLTSVersions`, this leads to `11` looking older than
`11.0.32+101`, so Renovate then raises a PR to bump to a full version,
which isn't the intent.

Similar to the fix for mise in
5f5e58b822, we can use `semver-partial`
versioning for whole versions, so `11` stays `11` and only a new major
bumps it to `25`, and exempt `github-actions` from the preset rule that
would otherwise force the Java regex versioning back on.

The remaining documented forms (`21.x`, `>=21`, `21-ea`, `latest`) have
no version we could bump them to, so we skip them as
`unsupported-version` rather than mangling them.

`graalvm/setup-graalvm` reads the same datasource from its own
`java-version` input, so it gets the same treatment.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-16 14:14:43 +01:00

88 lines
2.7 KiB
TypeScript

import { z } from 'zod/v4';
import { regEx } from '../../../../util/regex.ts';
import { JavaVersionDatasource } from '../../../datasource/java-version/index.ts';
import type { PackageDependency } from '../../types.ts';
import type { ActionSchema, KnownActionConfig } from '../types.ts';
import { isPartialVersion, parsePartialValue } from './utils.ts';
// Distributions whose version numbering we can reliably track via the
// java-version datasource (which sources releases from Adoptium/Eclipse
// Temurin). Other distributions may not follow the same release cadence
// or versioning, so we don't attempt to track them.
const supportedJavaDistributions = new Set(['temurin', 'adopt']);
// A pinned Java version, i.e. what the java-version datasource can resolve
// exactly, such as `21.0.9` or `21.0.9+11.0.LTS`.
const exactJavaVersionRegex = regEx(/^\d+\.\d+\.\d+(?:[+-]\S+)?$/);
/**
* Parse a `java-version` input, which per actions/setup-java' and graalvm/setup-graalvm's docs, may be a version, a semver range, an early-access version or `latest`.
*
* A whole version (`21`, `21.0`) keeps their precision through `semver-partial` versioning.
*
* Exact versions are looked up as-is.
*
* Other forms of versions (`21.x`, `>=21`, `21-ea`, `latest`, ...) are skipped, as we can't provide a recommended bump at this time.
*/
export function parseJavaVersion(
version: string | undefined,
): PackageDependency {
if (
version &&
!isPartialVersion(version) &&
!exactJavaVersionRegex.test(version)
) {
return {
currentValue: version,
depType: 'uses-with',
skipStage: 'extract',
skipReason: 'unsupported-version',
};
}
return parsePartialValue(version);
}
const SetupJavaWith: ActionSchema = z
.object({
distribution: z.string().optional(),
'java-version': z.string().optional(),
'java-package': z.string().optional(),
})
.transform(
({
distribution,
'java-version': version,
'java-package': javaPackage,
}) => {
const packageName = javaPackage?.startsWith('jre')
? 'java-jre'
: 'java-jdk';
if (
!distribution ||
!supportedJavaDistributions.has(distribution.toLowerCase())
) {
return [
{
packageName,
depType: 'uses-with',
skipStage: 'extract',
skipReason: 'unsupported',
},
];
}
return [{ packageName, ...parseJavaVersion(version) }];
},
);
export const javaVersionDynamicActions: Record<string, KnownActionConfig> = {
// https://github.com/actions/setup-java
'actions/setup-java': {
datasource: JavaVersionDatasource.id,
packageName: '', // determined from `distribution`/`java-package` inputs
withSchema: SetupJavaWith,
},
};