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>
test(manager/terraform): close the terraform family coverage gaps
Adds two terraform extractions that no test covered: a lock file that
cannot be read, and one that holds no locks. Both leave the deps without
a locked version.
Marks three guards. The lockfile update path needs a change that also
satisfies the recorded constraints, `extractTFLintPlugin()` never
returns null, and only terragrunt's already-ignored default case leaves
its result unset.
Two implicit elses stay counted, in the terraform module extractor and
the tflint key parser: a coverage-ignore hint does not attach to an
`else if`, so they carry a plain note.
Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io>
test(manager/sbt,swift): close the sbt and swift coverage gaps
sbt is now fully covered by tests: a build definition referencing
symbols that were never defined, a resolver whose location is not a url,
a package file that yields nothing during a multi-file extract, and two
scala version strings that normalization leaves alone - a range and a
version with no patch part.
swift keeps two marks. `artifacts.ts` falls back to an empty depName
that extract always sets, and the null state in `extract.ts` is only
re-entered at a deps boundary. Its two `.package(` transitions stay
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/bazel): close the bazel branch coverage gaps
Adds two extractions that no test covered: a `go_repository` carrying
both a tag and a commit, which must not be marked digest-only, and a
`maven_install` artifact whose coordinate is not group:artifact:version.
Marks the rest. `parser.ts` guards are type narrowing over the parsed
fragment tree, where the else only happens if the parser hands back a
shape it never produces. In `artifacts.ts` only http rules reach
updateArtifacts, and the empty url list already returned earlier.
The digest branch in `rules/http.ts` stays counted: a coverage-ignore
hint does not attach to an `else if`, so it carries a plain note.
Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io>
refactor(maven-wrapper): avoid matching each line twice
`extractLineInfo` ran `line.match(regex)` only to re-run `regex.exec(line)`
on the same line immediately afterwards. None of the regexes are global,
so `exec` alone is equivalent and halves the regex work per line.
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>
Similar to how we already generate a list of the community actions we
support, we should also generate which first-party Actions from GitHub
are supported, and simplify some of the wording in the docs.
Instead of duplicating this, we can instead move them into a single
section in the documentation.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* refactor(manager/github-actions): don't duplicate parsing logic for first-party Actions
Instead of having a separate set of Action parsing and their
configuration between first-party GitHub-owned Actions and those of
third-party Actions, we can merge them into a single collection.
This also leads to `https://<host>/` handling noted in #35777 now being
handled out-of-the-box, as it was already supported on third-party
actions.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fixup! refactor(manager/github-actions): don't duplicate parsing logic for first-party Actions
---------
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fix(managers/pep621): use lowest locked version from uv
* reduce diff
* add file extension to import
* use correct file path in import
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
---------
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
While looking at [0], I noticed that we didn't have support for our own
GitHub Action's configuration.
We can make sure that we support upgrading the `renovate-image` for
folks specifying an image (with optional digest) for the Renovate CLI
version to upgrade.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
While looking at [0], I noticed that we didn't have support for our own
GitHub Action's configuration.
We can make sure that we support upgrading the `renovate-version` for
the CLI version in use, whether it's quoted or unquoted (which YAML
parses as a number).
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
[0]: https://github.com/renovatebot/github-action/issues/1035
* feat(manager/mise): support gitlab backend
Maps the mise `gitlab` backend (e.g. `gitlab:gitlab-org/cli`) to the gitlab-releases datasource, mirroring the github backend including version_prefix support.
* refactor(manager/mise): use optional instead of Nullish for tool options
TOML has no null type, so MiseToolOptions values are only ever a string or absent. .optional() models that exactly; Nullish only adds value for sources that can emit explicit null.
* fix(manager/mise): use RegExp.escape in gitlab backend
Main switched `createGithubToolConfig` from the `escapeRegExp` util to
`RegExp.escape` and dropped the import, which left the newly added
`createGitlabToolConfig` referencing an undefined symbol after the merge.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Michael Kriese <michael.kriese@mend.io>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>