version has a default (latest), so real workflows commonly omit it
from with: entirely rather than passing an empty string.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
graalvm/graalvm-ce-builds still alternates between jdk- and graal-
prefixed tags for current-era releases, so extractVersion matches both
rather than jdk- alone.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
As the repo publishes per-SDK/component release tags i.e.
`sdk/typescript/v0.21.9`, `helm/chart/v0.21.9`), we need to specify
`extractVersion` to extract the version as we need.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
As Maven tags releases as maven-X.Y.Z rather than plain SemVer, we need to set a custom extractVersion.
As ranges can be used, we can treat it as Node-package-registry-style versioning.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
As the Action only uses the last `toolchain` as the active one, we can
only update that value.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
setup-beam is a bit more complex, as it has multiple inputs, and
`erlang/otp` releases as `OTP-x.y.z`, so we need to specify a custom
`extractVersion`.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* test(manager): close azure-pipelines, bundler and cocoapods gaps
Adds a pipeline whose step task is not versioned, so nothing is
extracted, and a gem lock line carrying no version, which is skipped.
Marks four guards that cannot be false: `extractContainer()` always
returns a dep, `getLockFilePath()` always returns a path, and the
cocoapods dep name, spec name and git account all derive from values
their enclosing check already proved present.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(manager): close cargo, composer and cpanfile gaps
Adds a composer repository map that disables something other than
packagist, which is dropped rather than recorded.
Marks five guards: the cargo warning only fires for a crate dep and its
retry only runs when a dep was already current, a gitlab rule without a
token never passes the auth check, and both cpanfile handlers run only
once their match produced a value.
Two implicit elses stay counted, in the cargo version resolver and the
composer repository mapper, since a coverage-ignore hint does not attach
to an `else if`.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(manager): close deps-edn, docker-compose and dockerfile gaps
Adds three extractions: a deps.edn alias whose value is not a map, a
compose extension carrying no image, and a dockerfile escape directive
naming a character other than a backtick, which leaves the default in
place.
Marks the deps-edn repository name check, since object keys are always
strings, and notes the repository spec chain, where a coverage-ignore
hint does not attach to an `else if`.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(manager/flux): close the flux coverage gaps
Adds two GitRepository resources whose url is ssh rather than http, one
pinned to a tag and one to a commit. Neither yields a source url, since
only http urls can be turned into one.
Marks the Kustomization image guard: the schema rejects an image without
a name, so `extractImage()` cannot return null there.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(manager): mark github-actions, gitlabci and glasskube guards
None of these six needs a test. A parsed action ref is either a docker
or a repository ref, `getDep()` always returns a dep for a job container
and a service, and the remaining three need a listed file that cannot be
read, a listed file that yields no deps, or a manifest whose
repositories match no name.
The glasskube resource kind chain stays counted, since a coverage-ignore
hint does not attach to an `else if`.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(manager): mark gomod and gradle-wrapper guards
Four guards that need setups no test provides: a removed dep that is not
added back, a go.mod the replace massaging leaves unchanged, and a
daemon-jvm file carrying no toolchain version. A parsed go directive
always yields a version.
The additional-dependency count chain stays counted, since a
coverage-ignore hint does not attach to an `else if`.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
---------
Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* feat(manager/github-actions): support aws-actions/amazon-ecs-render-task-definition's `image`
Per #43038, and following the existing pattern for Docker image
extraction.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fixup! feat(manager/github-actions): support aws-actions/amazon-ecs-render-task-definition's `image`
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
---------
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* 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.
Where we are able to support Java distributions that follow a
straightforward release cadence, we opt these distributions in, and skip
others as `unsupported`.
As the Temurin/Adopt distributions can be reliably tracked by the
`java-version` Datasource, backed by Adoptium, we can support them.
We can also use the `java-package` key to look up whether we want a JRE
or JDK.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
In the case a multi-line `dotnet-version` is specified to install
multiple SDKs at once, we skip it as `invalid-version`, as we don't
currently have a way to update multiple values in the field.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>