Although we document that the `hostRules[].hostType` are
Platform/Datasource names, we don't currently provide a means to suggest
to the user what the values should be.
As there is currently no validation for these, we can provide them as a
suggestion, rather than an enum of all possible values, so we don't
introduce config validation mismatches.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
* refactor(config): require an option to document where it can be used
Now we have coverage of all of our repo config's `scopes` we can
refactor our types to make sure that:
- global self-hosted config could include `scopes`
- repo config must include `scopes`
This now allows us to relax the error checking in JSON schema
generation, as `scope` now will be required per the types.
To do this, we need to extract out a base type for global-only config.
As noted in #43020, an option which declares neither `parents` nor
`scopes` is treated as valid anywhere, which means a new option can
silently join that group by saying nothing.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
* fixup! refactor(config): require an option to document where it can be used
---------
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
* feat(json-schema): suggest the managers, datasources and categories we know
As per #40450, and similar to how we provide suggestions for `extends`
presets, we can suggest to an editor which values a `match*` option
usually takes, so they can be completed.
As these options allow a regex or a glob pattern, we can't use an
`enum`.
Instead, we give them `suggestedValues`:
- `matchManagers`, from the managers we support, with our custom
managers under the `custom.` prefix they're matched by
- `matchDatasources`, from the datasources we support
- `matchCategories`, from the categories a manager can be in
A pattern, or a value we don't know about, is still accepted.
We don't include these in the docs table, as it's unnecessary noise.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fixup! feat(json-schema): suggest the managers, datasources and categories we know
---------
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
As part of follow-up changes, we'll want to suggest values for options
other than `extends` - such as the managers, datasources and
categories a `match*` option takes, and the host types a `hostRules`
entry's `hostType` takes - which need the same `anyOf: [{enum}, items]`
shape we already build for suggesting presets.
We can first prefactor the way that we propose suggested values for
`extends` into a shape that we can re-use for other types, extracting a
`suggestValues` helper function, and building both the array and scalar
cases generically in `createSingleConfig`.
The scalar case isn't exercised by any option yet - the next two
commits each introduce one - so it's marked as such for coverage.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
We currently allow an option to be set to `null` when it defaults to it,
which means that our JSON schema's additional validation will reject the
two nullable options:
- `semanticCommitScope`, which the `default:semanticCommitScopeDisabled` preset sets to `null`
- `minimumReleaseAgeBuffer`
Instead, we should mark them as `nullable: true`, so we report the
correct types for our JSON schema, which then allows us to mark
`default:semanticCommitScopeDisabled` as well-formed against our JSON
schema.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
To have greater confidence in changes to our JSON schema will result in
the correct validation rules, we can test all internal presets against
the JSON schema.
This does lead to `default:semanticCommitScopeDisabled` failing
validation, as it is technically valid but our JSON schema reports it as
invalid, due to a type mismatch.
We'll fix this in a follow-up commit.
As `global:` presets are used in `globalExtends`, they need to be
validated against the global self-hosted config schema.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
When an option declares its `parents`, we add it to the `items` of each
of those parents, which only works for the parents which are an array of
configs, like `packageRules` or `hostRules`.
For the other parents which aren't - every manager, every update type,
`postUpgradeTasks`, `toolSettings`, `vulnerabilityAlerts` and
`customDatasources` - `items` is ignored, so none of their children are
validated:
```yaml
postUpgradeTasks:
# not reported, although it must be an array
commands: echo hi
# not reported, although it's not an allowed value
executionMode: bogus
```
We should instead declare the children on the schema being validated,
which differs depending on whether the parent is an array of configs, a
map of configs, or a config itself.
As `customDatasources` is a map of maps, we need to declare the children
on the values, rather than on the map.
This also means that we will reject a misconfigured custom datasource
which contains other Renovate config.
The option metadata is frozen, so we need to copy any
`additionalProperties` we're given before declaring children on it.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
* fix(json-schema): restrict all known object properties keys
As noted when declaring the values of our maps of values, we didn't have
our JSON schema restrict the keys of `statusCheckNames` and
`statusCheckWhen` to the status checks we know about in, although config
validation does correctly error on i.e.
```json
{
"statusCheckNames": {
"bogusCheck": "renovate/bogus"
}
}
```
We already generated the keys of an object for `constraints`,
`constraintsVersioning` and `installTools`, which was generated
specifically in the JSON Schema generation.
Rather than add another hardcoded case, we can add a new `properties`
type to config options, which the generator copies as it does the rest
of an option's metadata.
The keys are hidden from the docs tables, as the generated JSON is noise
next to a description which already says the keys match
`statusCheckNames`.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
* fixup! fix(json-schema): restrict all known object properties keys
getSupportedToolNames() returns Object.keys(allToolConfig), so every
name it yields is guaranteed to be a key of allToolConfig - meaning
getToolConfig(toolName) can never return undefined for it. The `if
(!toolConfig) continue;` guards in toolConstraintProperties() and
installToolProperties() were therefore dead code, which 100% coverage
enforcement was flagging as uncovered lines.
We can just remove them, and the now-unused toolConfig variable and
getToolConfig import along with them.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fixup! fix(json-schema): restrict all known object properties keys
Every entry in `additionalConstraintDefinitions` currently has a
`description`, so the `??` fallback in `additionalConstraintProperties`
is unreachable, which 100% branch coverage enforcement was flagging.
As the type still allows an entry without one, we should keep the
fallback rather than delete it - we can instead document why it's
currently unreachable with a `v8 ignore` comment, per
docs/development/best-practices.md.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
---------
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
As a follow-up to the previous change, we should make sure that these
config options have their `additionalProperties` defined explicitly.
As `statusCheckWhen`'s allowed values are now needed in two places, we
can share them from `config/types`, rather than redeclaring them in the
validation.
In a follow-up commit, we'll ensure that only valid key names can be
used for `StatusCheckWhen`'s object keys.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
Options like `secrets`, `registryAliases` and `productLinks` are a map
of user-chosen keys to simple values, but when we generate the JSON
Schema, we use a `$ref` to the root schema, in a similar way to options
that do have a nested Renovate config, like `force` or
`onboardingConfig`.
That means the keys of the map are validated as if they were config
options, so a perfectly valid config is reported as an error:
```yaml
secrets:
# must be boolean
enabled: a-secret
registryAliases:
# must be array
labels: https://example.com
```
As we already have `additionalProperties` defined, we can use these to
document the format of the body, instead of treating it as a Renovate
schema.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
As part of follow-up changes we'll fix how our JSON schema treats the
options which are an object. Before we do this, we should document how
we currently generate them.
Currently, if an object option:
- is not `freeChoice`
- nests a Renovate config i.e. `force`
- is a map of simple types i.e. `secrets`, `env`
then the JSON schema indicates that this is can take any root-level
options, which isn't correct.
Also, the children an option declares through its `parents` are
generated into `items`, which is only validated for the parents which
are an array.
This means that we error for valid config i.e.
```yaml
env:
automerge: "true" # incorrectly reports this must be boolean
```
but do not error for an invalid config i.e.
```yaml
postUpgradeTasks:
commands: echo hi # incorrectly does not report that this must be an array
```
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
As part of #43020, we're making an option's `parents` explicit, which
isn't possible without breaking the docs links that our JSON Schema
contains.
We previously incorrectly generated the `See also` link for an option,
by taking the first of its `parents` which isn't `.`, and assume the
option is documented under that parent, which isn't true for options
that can be valid in multiple places.
To fix this, we track which headings are output, and then linking to
them accordingly.
By fixing this, we see the following diffs:
```diff
-#packagerulesenabled
+#enabled
-#packagerulesfetchchangelogs
+#fetchchangelogs
-#ansiblemanagerfilepatterns
+#managerfilepatterns
```
We can also add a test to catch this breakage in the future.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
As part of follow-up changes, we want to fix how these links are
generated. Before we do this, we should cover how they're generated, so
there's a clearer diff.
When generating an option's `See also` link, we take the first of its
`parents` which isn't `.`, and assume the option is documented under
that parent, which isn't true for options that can be valid in multiple
places, which means we have 3 links that don't match anything.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
* docs/41127-parents-may-want-to-split-over-multiples-lines
* refactor(docs): sort parents alphabetically in table and add unit tests
* refactor(docs): table - use expect instead of assert
* refacto(docs) : remove unnecessary vitest import
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* refactor(docs): table - rename index so there are rowIndex and colIndex
* refactor(docs): rename config.test.ts to utils.test.ts
---------
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>