Files
Sebastian Poxhofer 4b4d14ec00 feat(manager): pass extracted constraints to updateArtifacts (#45826)
* feat(manager): pass extracted constraints to updateArtifacts

`extractedConstraints` were collected during extraction but only ever read
by `fetch.ts` for the lookup. At artifact time every manager had to derive
the same tool constraints a second time, and when the updated package file
no longer carried the constraint there was nothing to fall back to.

`generateBranchConfig()` now merges the `extractedConstraints` of all
upgrades of a branch onto the branch config, which reaches `updateArtifacts()`
through `patchConfigForArtifactsUpdate()`. `UpdateArtifactsConfig` declares
the field and documents what it contains.

The new `resolveToolConstraint()` helper implements the ladder once:
user `constraints` > an optional artifact-time derivation > the extracted
value. The derivation is ranked above the extracted value on purpose: it
reads the package files as the branch changed them, so poetry (python is an
updatable dependency there), composer, pipenv (`pipenv` can be a dev
package) and pep621 (`requires-python` is an updatable dependency) would
otherwise regress to a stale constraint. pipenv, pep621 uv/pdm, poetry and
composer are migrated to the helper and keep their derivation.

Behaviour change: these managers now use the extract-time constraint as a
last resort instead of running unconstrained, for example on lock file
maintenance where pipenv deletes `Pipfile.lock` before deriving.

`execute-post-upgrade-commands.ts` is unaffected: it reads
`upgrade.constraints` per upgrade, and the extracted values are kept in a
separate field rather than folded into `constraints`, so post-upgrade task
tool constraints still come from user config only.

Not migrated, because their constraints are never extracted, so the
fallback would be dead code: bundler (`ruby`/`bundler`), pixi (`pixi`),
pep621 uv (`required-version`) and npm's node ladder, whose last step
already reads `package.json` engines.

* refactor(manager): resolve tool constraints through resolveToolConstraint()

Every manager now obtains the constraint of a tool it runs through
`resolveToolConstraint()` instead of reading `config.constraints` itself, so
the precedence "user config, then a value derived from the updated files, then
the constraints collected during extraction" applies everywhere. The helper
treats an empty string as not set at every step and accepts the
`PostUpdateConfig` shape, whose `constraints` may be `null`.

Behaviour changes that go beyond the new fallback to extracted constraints:

- `mix` applies its hardcoded erlang default only after the extracted
  constraint, so an erlang version collected at extraction can win over it.
- `kustomize` decides `HELM_EXPERIMENTAL_OCI` from the fully resolved helm
  constraint; `generateHelmEnvs()` takes that value instead of the config.
- `npm` (yarn): an upgrade of yarn without a new value now consults the user
  constraint before deriving one from package.json or the lock file.
- The "Using <tool> constraint from config" debug lines in bundler, composer,
  copier and pip-compile are gone, as the helper is the only reader of the
  config now.

Helpers that read the config synchronously became async: bundler
`getBundlerConstraint()`, copier `getPythonVersionConstraint()` and
`getCopierVersionConstraint()`, pip-compile `get*VersionConstraint()` and
`getToolVersionConstraint()`, gomod `deriveGoToolchainConstraints()` and
`getUpdateImportPathCmds()`, mise `getMiseLockToolConstraints()`. composer
`getPhpConstraint()` is removed.

Each converted manager has a test showing the extracted constraint reaching
the executed tool, and, where a derive callback exists, that the derived value
still wins over it.

* refactor(linters): add prefer-resolve-tool-constraint rule

Reports member reads and destructuring of `constraints` and
`extractedConstraints` from a manager config in `lib/modules/manager/**`, so
that tool constraints are resolved through `resolveToolConstraint()` in
`lib/modules/manager/util.ts` only. Writes and the same properties on package
files, which extraction has to populate, are not reported. The helper itself
and spec files are exempt in `.oxlintrc.json`.

* refactor(manager): inline thin resolveToolConstraint wrappers

Drop copier/utils.ts and the pip-compile getPipToolsVersionConstraint /
getUvVersionConstraint helpers, which only forwarded to
resolveToolConstraint(). Callers now call it directly.

* docs(development): note lock file maintenance in tool constraints section

* refactor(manager): address review on tool constraint resolution

composer only runs extractConstraints() when a user constraint is missing,
via Lazy. UpdateArtifactsConfig no longer re-declares constraints and
extractedConstraints, which ToolConstraintsConfig already provides.
2026-09-14 11:09:07 +00:00
..
2024-04-11 13:23:20 +00:00

Renovate supports updating Helm Chart references in:

  • requirements.yaml files, for Helm v2
  • Chart.yaml files, for Helm v3

The helmv3 manager defines this default registryAlias:

{
  "registryAliases": {
    "stable": "https://charts.helm.sh/stable"
  }
}

If you use repository aliases in your Helm charts then you must set an registryAliases object in your configuration file so Renovate knows where to find the repository. Alias values must be properly formatted URIs.

If you need to change the versioning format, read our versioning documentation to learn more.

Private repositories and registries

To use private sources in your Helm charts, you must set the password and username you use to authenticate to the private source. For this you use a custom hostRules array.

OCI registries

{
  hostRules: [
    {
      // Global login
      matchHost: 'registry.gitlab.com',
      hostType: 'docker',
      username: '<some-username>',
      password: '<some-password>',
    },
    {
      // For repository string oci://registry.gitlab.com/user/oci-helm-test
      matchHost: 'https://registry.gitlab.com/user/oci-helm-test',
      hostType: 'docker',
      username: '<some-username>',
      password: '<some-password>',
    },
  ],
}

Helm repository

{
  hostRules: [
    {
      // Global login for 'gitlab.com' if using Helm
      matchHost: 'gitlab.com',
      hostType: 'helm', // this is optional, but else the credentials will be used for all requests matching `matchHost`
      username: '<some-username>',
      password: '<some-password>',
    },
    {
      // Specific repository
      matchHost: 'https://gitlab.com/api/v4/projects/xxxxxxx/packages/helm/stable',
      hostType: 'helm', // this is optional
      username: '<some-username>',
      password: '<some-password>',
    },
  ],
}

Subchart archives

To get updates for subchart archives put helmUpdateSubChartArchives in your postUpdateOptions configuration. Renovate now updates archives in the /charts folder.

{
  "postUpdateOptions": ["helmUpdateSubChartArchives"]
}