* fix(config/validation): allow only capturing `currentDigest` in Custom Managers As reported in #45665, it was previously possible - through a preset prior to 44.60.1 - to specify a Custom Manager (in this case, with Regex) that only captured the `currentDigest` for a dependency. This causes config validation in a repository, but as it appears to be valid - with `currentValue` defaulting to `latest` - we should make it possible to use either `currentValue` or `currentDigest`. * fixup! fix(config/validation): allow only capturing `currentDigest` in Custom Managers
With customManagers using JSONata queries you can configure Renovate so it finds dependencies in JSON, TOML and YAML files, that are not detected by its other built-in package managers.
Renovate uses the jsonata package to process the file content using the queries, after the content has been parsed into json format.
For more on the jsonata query language, read the jsonata query language site.
The JSONata manager is unique in Renovate, because:
- It can be used with any
datasource - It can be configured via JSONata queries
- You can create multiple "JSONata managers" in the same repository
If you have limited managers to run within enabledManagers config option, you need to add "custom.jsonata" to the list.
Required Fields
The first two required fields are managerFilePatterns and matchStrings:
managerFilePatternsworks the same as any managermatchStringsis aJSONatacustom manager concept and is used for configuring a jsonata queries
Information that Renovate needs about the dependency
Before Renovate can look up a dependency and decide about updates, it must have this info about each dependency:
| Info type | Required | Notes | Docs |
|---|---|---|---|
| Name of the dependency | Yes | ||
datasource |
Yes | Example datasources: npm, Docker, GitHub tags, and so on. | Supported datasources |
Version scheme to use. Defaults to semver-coerced. |
Yes | You may set another version scheme, like pep440. |
Supported versioning schemes |
fileFormat |
Yes | Must be either json, yaml or toml. |
Configuration Options |
Required fields to be present in the resulting structure returned by the jsonata query
You must:
- Capture the
currentValueorcurrentDigestof the dependency or use thecurrentValueTemplateorcurrentDigestTemplatetemplate field - Capture the
depNameorpackageName. Or use a template field:depNameTemplateandpackageNameTemplate - Capture the
datasource, or use thedatasourceTemplatetemplate field
Optional fields you can include in the resulting structure
You may use any of these items:
depType, or use thedepTypeTemplatetemplate fieldversioning, or the useversioningTemplatetemplate field. If neither are present, Renovate defaults tosemver-coercedextractVersion, or use theextractVersionTemplatetemplate fieldregistryUrl, or use theregistryUrlTemplatetemplate field. If it's a valid URL, it will be converted to theregistryUrlsfield as a single-length arrayindentation. Must be empty, or whitespace. Else Renovate restes onlyindentationto an empty string
Usage
When you configure a JSONata manager, use the following syntax:
{
"customManagers": [
{
"customType": "jsonata",
"fileFormat": "json",
"managerFilePatterns": ["<file match pattern>"],
"matchStrings": ["<query>"],
...
}
]
}
Overwrite the <query> placeholder text with your JSONata query.
The JSONata query transforms the content to a JSON object, similar to this:
[
{
"depName": "some_dep",
"currentValue": "1.0.0",
"datasource": "docker",
"versioning": "semver"
}
]
Creating your Renovate JSONata manager config is easier if you understand JSONata queries. We recommend you follow these steps:
- Read the official JSONata query language docs
- Check our example queries below
- You're ready to make your own config
Alternatively, you can use "trial and error" to a working config by adjusting our examples.
YAML files are parsed as multi-document files, even those that have only one document.
YAML parsing
To show how the JSONata manager parses YAML, below is an example YAML file and the corresponding parsing to JSON.
YAML:
production:
packages:
version: 1.2.3
package: foo
test:
metadata:
- version: 4.5.6
package: bar
---
development:
author: Renovate
JSON:
[
{
"production": {
"packages": {
"version": "1.2.3",
"package": "foo"
}
},
"test": {
"metadata": [
{
"version": "4.5.6",
"package": "bar"
}
]
}
},
{
"development": {
"author": "Renovate"
}
}
]
Example queries
Below are some example queries for the generic JSON manager. You can also use the JSONata test website to experiment with queries.
{
"production": [
{
"version": "1.2.3",
"package": "foo"
}
],
"development": [
{
"version": "4.5.6",
"package": "bar"
}
]
}
Query:
production.{ "depName": package, "currentValue": version }
{
"production": [
{
"version": "1.2.3",
"package": "foo"
}
],
"development": [
{
"version": "4.5.6",
"package": "bar"
}
]
}
Query:
*.{ "depName": package, "currentValue": version }
{
"foo": {
"version": "1.2.3"
},
"bar": {
"version": "4.5.6"
}
}
Query:
$each(function($v, $n) { { "depName": $n, "currentValue": $v.version } })
{
"packages": [
{
"version": "1.2.3",
"package": "foo"
},
{
"version": "4.5.6",
"package": "bar"
}
]
}
Query:
packages.{ "depName": package, "currentValue": version }
{
"packages": ["foo@1.2.3", "bar@4.5.6"]
}
Query:
$map($map(packages, function ($v) { $split($v, "@") }), function ($v) { { "depName": $v[0], "currentVersion": $v[1] } })
{
"customManagers": [
{
"customType": "jsonata",
"fileFormat": "json",
"managerFilePatterns": ["/package.json/"],
"matchStrings": [
"$each(dependencies, function($v, $k) { {\"depName\":$k, \"currentValue\": $v, \"depType\": \"dependencies\"}})",
"$each(devDependencies, function($v, $k) { {\"depName\":$k, \"currentValue\": $v, \"depType\": \"devDependencies\"}})",
"$each(optionalDependencies, function($v, $k) { {\"depName\":$k, \"currentValue\": $v, \"depType\": \"optionalDependencies\"}})",
"{ \"depName\": \"pnpm\", \"currentValue\": $substring(packageManager, 5), \"depType\": \"packageManager\"}"
],
"datasourceTemplate": "npm"
}
]
}
packages:
- version: 1.2.3
package: foo
Query:
packages.{ "depName": package, "currentValue": version }
packages:
- version: 1.2.3
package: foo
---
packages:
- version: 1.2.5
package: bar
Query:
packages.{ "depName": package, "currentValue": version }
[[packages]]
version = "1.2.3"
package = "foo"
[[packages]]
version = "1.2.2"
package = "bar"
Query:
packages.{ "depName": package, "currentValue": version }