* feat(versioning): comparator ranges for the regex scheme The regex versioning orders versions by the release array built from its captured groups (major, minor, patch, build, revision) but matches every range by exact equality, so a comparator range in `allowedVersions` (`<=1.2.3` and friends) never resolves against a regex-versioned dependency. Add a scheme-independent comparator parser (`generic-range.ts`) and wire it into the regex scheme's `isValid`/`matches`/`getSatisfyingVersion`/ `minSatisfyingVersion`, evaluating each `<`, `<=`, `>`, `>=`, `=`, `==` term through the scheme's own `_compare`. A pattern that captures a `-ee.N` suffix as an ordered `build` component then resolves `<=X-ee.0` correctly, where npm `semver` cannot: as a prerelease the suffix breaks the range, as build metadata it is ignored, and a four-part release is not valid semver. The parser defers operand validation and comparison to the caller, so it stays independent of npm `semver` (used by the semver family) and consistent with the scheme's own ordering. Dependency values stay exact tags, so `supportsRanges` remains `false`. * test(versioning): cover regex ordering by capture-group name, not position Add a calendar-versioning case (`YYYY.DD.MM`) showing comparison follows the `major`/`minor`/`patch` capture-group names in precedence order, not their left-to-right position: naming the month `minor` and the day `patch` sorts by year, then month, then day even though the day is the middle field. Also reword the readme, which described this as "the same capture-group ordering" and read as positional, to state the major/minor/patch precedence explicitly. * refactor(versioning): declare RangeComparator in types.ts The `renovate/types-location` rule requires an exported type to live in a colocated `types.ts`, so `RangeComparator` is declared there and `generic-range.ts` imports it.
Regular Expression Versioning is designed to be a flexible fallback versioning approach if Renovate's other versioning schemes don't do the job.
The regex scheme makes use of Regular Expression capture groups.
The valid capture groups for regex versioning are:
major,minor, andpatch: at least one of these must be provided. When determining whether a package has updates, these values will be compared in the standard semantic versioning fashion. If any of these fields are omitted, they will be treated as if they were0-- in this way, you can describe versioning schemes with up to three incrementing values.build: this capture group can be used after you've already used themajor,minorandpatchcapture groups and need a fourth version part.buildupdates are handled likepatchupdates.revision: this capture group can be used after you've already used thebuildcapture groups and need a fifth version part.revisionupdates are handled likepatchupdates.prerelease: this value, if captured, will mark a given release as a prerelease (e.g. unstable). If this value is captured and you have configured"ignoreUnstable": true, the given release will be skipped.compatibility: this value defines the "build compatibility" of a given dependency. A proposed Renovate update will never change the specified compatibility value. For example, if you are pinning to1.2.3-linux(andlinuxis captured as the compatibility value), Renovate will not update you to1.2.4-osx.
The compatibility concept was originally introduced for Docker versioning but sometimes package authors may use/misuse suffixes to mean compatibility in other versioning schemes.
Important: all capture groups must contain only purely numeric values.
Even if there is a string prefix which is identical in all available versions, it must not be part of the capture group. For example a build capture group containing r4 cannot be evaluated as number; Renovate cannot compare the build in this case. The capture group must be 4 instead.
Here is an example of using regex versioning to correct behavior of the guava Maven package, which misuses suffixes as compatibility indicators:
{
"packageRules": [
{
"matchPackageNames": ["com.google.guava:guava"],
"versioning": "regex:^(?<major>\\d+)(\\.(?<minor>\\d+))?(\\.(?<patch>\\d+))?(-(?<compatibility>.*))?$"
}
]
}
Here is another example, this time for handling python Docker images, which use both pre-release indicators as well as version suffixes for compatibility:
{
"packageRules": [
{
"matchDatasources": ["docker"],
"matchPackageNames": ["python"],
"versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(?<prerelease>[^.-]+)?(-(?<compatibility>.*))?$"
}
]
}
Here is another example, this time for handling Bitnami Docker images, which use build and revision indicators as well as version suffixes for compatibility:
{
"packageRules": [
{
"matchDatasources": ["docker"],
"matchPackageNames": ["bitnami/**", "docker.io/bitnami/**"],
"versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(?:-(?<compatibility>.+)(?<build>\\d+)-r(?<revision>\\d+))?$"
}
]
}
Here is another example, this time for handling ghcr.io/linuxserver/tautulli Docker images, which use major and build indicators with string prefixes:
{
"packageRules": [
{
"matchDatasources": ["docker"],
"matchPackageNames": ["ghcr.io/linuxserver/tautulli"],
"versioning": "regex:^v(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-ls(?<build>.+)$"
}
]
}
Here is another example, this time for handling ghcr.io/linuxserver/openssh-server Docker images, which use patch, build and revision indicators with string prefixes:
{
"packageRules": [
{
"matchDatasources": ["docker"],
"matchPackageNames": ["ghcr.io/linuxserver/openssh-server"],
"versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)_p(?<patch>\\d+)-r(?<build>\\d)-ls(?<revision>.+)$"
}
]
}
The regex scheme also accepts a comparator range wherever a version is matched against a constraint, such as allowedVersions and matchCurrentVersion, evaluated with the scheme's own version comparison: the major, minor, and patch capture groups are compared in that order of precedence, regardless of where they appear in the pattern. For example, calendar versioning YYYY.DD.MM (day before month) sorts correctly by capturing the month as minor and the day as patch, so comparison follows year, then month, then day.
The supported operators are <, <=, >, >=, = and ==, and several comparators separated by whitespace or a comma are combined with logical AND.
Because the comparison uses the scheme's own ordering rather than npm semver, a numeric suffix captured as build is ordered correctly, where semver would treat it as a prerelease and reject the range.
For example, to hold a GitLab EE image at or below a required upgrade stop, capture the -ee suffix as a numeric build group and cap it with allowedVersions:
{
"packageRules": [
{
"matchDatasources": ["docker"],
"matchPackageNames": ["gitlab/gitlab-ee"],
"versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)-ee\\.(?<build>\\d+)$",
"allowedVersions": "<=19.1.2-ee.0"
}
]
}