The prefix.dev branch was selected by string-prefix matching the whole
registry URL, which misses forms that are the same host (`http://`, a
bare `https://prefix.dev`) while the deprecated `fast.prefix.dev` alias
needed a second literal alongside it.
Compare the parsed hostname instead, in a `common.ts` helper so the host
list lives in one place. No behaviour change for the URL shapes that
already matched.
* feat(npm): extract devEngines.runtime and devEngines.packageManager
Adds extraction for the npm devEngines field
(https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines)
covering both single-object and array forms. Uses dot-notated depTypes
("devEngines.runtime", "devEngines.packageManager") consistent with
"pnpm.overrides", and reuses the existing engines/packageManager
datasource resolution. Items without a version are skipped.
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(npm): update devEngines.runtime and devEngines.packageManager versions
Adds an update path for the new devEngines depTypes. Handles both the
single-object form and the array form (the array element is identified
via managerData.devEnginesIndex set at extraction time). Uses the same
anchored search-and-verify approach as the existing replaceAsString
(indexOf("devEngines") + dequal check), so unrelated occurrences of the
same version string elsewhere in the file are not touched.
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(npm): skip lockedVersion and apply @yarnpkg/cli for devEngines deps
Extends the locked-versions post-extract step to cover the new
devEngines depTypes:
- devEngines.runtime and devEngines.packageManager are added to the
npm-lock skip list (mirrors the engines/packageManager/volta handling
added in #38598)
- devEngines.packageManager with depName "yarn" gets the @yarnpkg/cli
packageName fallback when the project is on Yarn 2+, matching the
existing behavior for engines / packageManager
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(npm): harden devEngines handling against malformed input
- Register devEngines.runtime and devEngines.packageManager in
knownDepTypes (matches the existing pnpm.overrides pattern)
- Guard against null/non-object array elements in devEngines.* during
extraction so malformed JSON does not throw
- Use JSON.stringify when interpolating versions into the source search
string, so any future versions containing JSON-escaped characters are
matched correctly
- Add an extraction test for a mixed array containing a null item, a
valid entry, and a version-less entry
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(npm): set hasPackageManager when devEngines.packageManager is an array
The previous hasPackageManager check used isNonEmptyObject which returns
false for arrays. Now that the array form of devEngines.packageManager
is actually extractable and updatable, the corepack post-update step
needs to be triggered for those users as well. Introduces a shared
hasDevEnginesPackageManager helper and uses it from both
extractPackageJson and extractPackageFile.
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(npm): require at least one non-empty array item for hasPackageManager
Align the array branch of hasDevEnginesPackageManager with the
single-object branch by requiring at least one non-empty object item.
Previously, an array containing only null/empty entries would set
hasPackageManager to true and trigger corepack post-update even though
no usable item exists. Add coverage for the empty-array and
only-invalid-items cases.
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(npm): document hasPackageManager semantics for stray-key array items
Make the chosen semantic explicit: an array element with arbitrary keys
but no `name` (e.g. `[{ foo: 'bar' }]`) still sets hasPackageManager to
true, mirroring the pre-existing single-object behavior. The extract
step independently filters out items lacking `name`/`version`.
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(npm): cover dequal rejection in devEngines array update
Adds a test where two devEngines.packageManager array items share the
same version string. The first source-level match belongs to the wrong
index, so the dequal verification rejects it and the loop continues to
the correct occurrence. This exercises the false branch of the dequal
check in updateDevEnginesDependency.
Refs #38067.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(node): list devEngines.runtime as a supported field for Node.js
The npm manager now updates the version inside devEngines.runtime in
package.json, so include it in the file-support list alongside engines
and volta.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Apply the comment changes suggested in the code review
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* test(npm): cover devEngines update error path instead of ignoring it
Remove the v8 ignore on the updateDevEnginesDependency catch and add a
test that reaches it with invalid JSON, matching how the main
updateDependency catch is covered.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(npm): drop unnecessary spread fallback in devEngines managerData
Object spread ignores null/undefined, so the `?? {}` fallback is
redundant. Removing it satisfies the oxlint no-unnecessary-spread-fallback
rule that now runs in CI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(npm): type devEnginesIndex on NpmManagerData
Declare devEnginesIndex on NpmManagerData so the value no longer needs a
`as number | undefined` cast when reading it back during update.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(node): document package manager version fields
List packageManager and devEngines.packageManager separately from the Node.js runtime file support entries.
Co-authored-by: Codex <noreply@openai.com>
* feat(npm): support Bun and Deno devEngines runtimes
* fix(npm): preserve Corepack hashes in devEngines
* test(npm): use partial helper for devEngines fixture
Co-authored-by: Codex <noreply@openai.com>
* fix(npm): warn on invalid devEngines update state
Co-authored-by: Codex <noreply@openai.com>
* fix(npm): include devEngines in extracted tool constraints
Co-authored-by: Codex <noreply@openai.com>
* fix(npm): prefer devEngines over volta for package manager versions
Co-authored-by: Codex <noreply@openai.com>
* fix(npm): update Yarn binaries for devEngines package manager upgrades
Co-authored-by: Codex <noreply@openai.com>
* fix(npm): recognize devEngines package managers for Yarn catalogs
Co-authored-by: Codex <noreply@openai.com>
* fix(npm): exclude devEngines from Yarn locked versions
Co-authored-by: Codex <noreply@openai.com>
* refactor(npm): reuse Bun extraction for devEngines runtime
Co-authored-by: Codex <noreply@openai.com>
* test(npm): cover Yarn devEngines manifest preservation and grouped updates
Co-authored-by: Codex <noreply@openai.com>
* refactor(npm): pass packageJsonResult directly to hasDevEnginesPackageManager
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* test(npm): simplify malformed devEngines fixture
Co-authored-by: Codex <noreply@openai.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Codex <noreply@openai.com>
Similar to changes in d8705054b0, we
should make sure that when there is an annotated Git tag (on GitHub) we
use the tag's `tagger.date` by using the `queryTags()`, and then using
the latest date, instead of relying on the GO module proxy's `Time`
field.
We can use an example from `github.com/kr/pretty@v0.3.1`, whose tag was
created some weeks after the commit it points to.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* feat(manager/mise): support remote `include` entries
* feat(manager/mise): support digest pinning of `include` refs via comment hints
* feat(manager/mise): support git references of remote task files
* fix(manager/mise): use gitlab-tags for gitlab.com references
* refactor(manager/mise): only support `# <version>` and `# <branch>` hints
* refactor(manager/mise): parse git references with parseGitUrl
* feat(manager/mise): support http and Azure DevOps ssh git references
* refactor(manager/mise): separate remote reference datasources from backends
* docs(manager/mise): add tag ref example for remote includes
`GetReleasesConfig`, `GetPkgReleasesConfig`, `GetDigestInputConfig` and
`DigestConfig` re-declared the same fields independently and the registry
glued two of them with an internal intersection, spreading the whole lookup
config into every `getReleases()` call. Introduce `RegistryUrlsConfig` for
the registry URL inputs, extend the per-registry types into the index-level
ones, and pass datasources an explicit projection so implementations cannot
depend on undeclared fields.
* refactor(datasource): stop double-caching releases at the index level
15 datasources set `caching = true`, which makes the registry wrapper in
`lib/modules/datasource/index.ts` store every `getReleases` result under
`datasource-releases-<id>` for 15 minutes, while their own `cached()`
wrapper already stores the same result under `datasource-<id>` with a
longer TTL and stale-fallback. Drop `caching` from those 15; the four
that rely on the index cache alone (dart-version, flutter-version,
maven, pypi) keep it.
`caching` is documented as requiring the datasource to return the
`isPrivate` flag, and none of these 15 ever set it, so the index layer
was caching private results unconditionally. The remaining `cached()`
layer honours `cachePrivatePackages` as before.
Also fix two cache-key/registry defects found alongside:
- `galaxy-collection` declares `registryStrategy = 'hunt'` but keyed its
cache on the package name only, so a `null` from the first hunted
registry was replayed for the second one. The registry URL is now part
of the key, which invalidates existing entries once.
- `typst` ignores `config.registryUrl` and always reads its default
registry, so it now sets `customRegistrySupport = false`. A configured
`registryUrls` for typst is now warned about and ignored instead of
being silently dropped.
* Merge branch 'main' into secustor/refactor/datasource-remove-index-caching
* fix(datasource): document `first` as the default registry strategy
The `hunt` JSDoc claimed to be the default for an undefined
`registryStrategy`, but the `Datasource` base class sets `first`, so the
`?? 'hunt'` fallback in the registry was only reachable from a test double.
Make the field required on `DatasourceApi`, move the "default" note to
`first`, drop the fallback, and delete the five overrides that restated the
base default.
* refactor(datasource): make `postprocessRelease` an optional method
`getDigest` is already optional on `DatasourceApi` and detected with a
presence check, but `postprocessRelease` was required and satisfied by a
no-op in the base class that the caller had to recognise by prototype
identity. Declare it optional like `getDigest`, delete the no-op, and test
for the method instead.
* refactor(datasource): drop the function form of `defaultRegistryUrls`
The `() => string[]` form has had no production user since it was added in
#15856; only the registry spec doubles used it, and four datasources index
into the field as an array. Narrow the type to `string[]`, collapse the
registry URL resolution to one path, and rewrite the spec doubles as plain
arrays.
`getDigest` is already optional on `DatasourceApi` and detected with a
presence check, but `postprocessRelease` was required and satisfied by a
no-op in the base class that the caller had to recognise by prototype
identity. Declare it optional like `getDigest`, delete the no-op, and test
for the method instead.
* fix(datasource): document `first` as the default registry strategy
The `hunt` JSDoc claimed to be the default for an undefined
`registryStrategy`, but the `Datasource` base class sets `first`, so the
`?? 'hunt'` fallback in the registry was only reachable from a test double.
Make the field required on `DatasourceApi`, move the "default" note to
`first`, drop the fallback, and delete the five overrides that restated the
base default.
* test(datasource): set registryStrategy on the object-literal datasource doubles
`registryStrategy` is required on `DatasourceApi` since this PR, and the two
object-literal doubles added with the GraalVM datasource (#40497) did not set
it, which failed the type check.
As we're now managing them via a `afterEach` in `test/setup.ts`, we can
remove any entries in tests themselves.
We don't update overrides of an outer hook or cases where there are more
explicit `clear()`s.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* Allow leading zeros in semver-coerced versioning for CalVer support
Make semver-coerced versioning more permissive by allowing leading zeros, i.e. supporting calendar versioning.
* Apply batched suggestions from code review
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* Don't use look-ahead or look-behind regex
* Capture group should be named
* Instead of adding the parameter everywhere, create a local function which handles this.
---------
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* fix(manager/mise): commit native dependency sidecars with the lock file
`mise lock` pins npm and Python tool dependencies in sidecar lock files
under `.mise/locks/` and records each sidecar's path and digest in
`mise.lock`. Only `mise.lock` was returned as an artifact, so a version
change committed a lock file pointing at a sidecar directory that was
never added, and `mise install --locked` failed.
Return the sidecar files that `mise lock` modified, created or deleted,
using the same sidecar location rules as mise.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(manager/mise): cover local lock files in getSidecarDir
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(manager/helmv3): share generateHelmEnvs with kustomize
Move kustomize's generateHelmEnvs into helmv3/common.ts and delete the
kustomize copy. The merged function always sets the three HELM_*
path variables and sets HELM_EXPERIMENTAL_OCI unless a helm
constraint is present and proves helm >= 3.8 (which ignores the
variable).
Behaviour change: kustomize now sets HELM_EXPERIMENTAL_OCI when the
helm constraint is unknown (previously it only set it for a known
constraint below 3.8). helmv3 and helmfile now omit the variable
once a resolved helm constraint proves helm >= 3.8.
* refactor(manager/helmv3): share OCI registry login helper with helmfile
Extract a shared generateRegistryLoginCmd(name, registry) helper in
helmv3/common.ts that strips the oci:// prefix, derives the host and
looks up the matching host rule before delegating to generateLoginCmd.
helmv3/artifacts.ts and helmfile/artifacts.ts now both call this
helper instead of each building a RepositoryRule inline, removing the
stale oci:// TODO. helmfile/utils.ts loses its duplicate
generateRegistryLoginCmd, and its unrelated isOCIRegistry(repository)
(checking the oci flag) is renamed to isOciRepositoryFlagSet so it no
longer collides in name with helmv3/oci.ts's prefix-based
isOCIRegistry(string), which helmfile/extract.ts also imports.
Addresses audit finding M8. Generated `helm registry login` commands
are unchanged, proved by the existing artifacts specs passing with
their original expectations untouched.
* fix(manager): share one local Helm chart path check
helmfile, flux, fleet and terraform each decided differently whether a Helm chart reference points at a local path. fleet and terraform used terraform's checkIfStringIsPath, whose regex was unanchored with unescaped dots, so it matched any string containing a slash followed by a non-slash character.
Add isLocalChartPath to helmv3/utils.ts with helmfile's prefix check and use it in all four managers. This drops the fleet to terraform dependency and removes checkIfStringIsPath, which had no other users.
* refactor(manager/helm-requirements): reuse helmv3 alias and repository helpers
Replace the duplicated alias-resolution and repository-classification logic in helm-requirements/extract.ts with the shared isAlias, resolveAlias and parseRepository helpers from helmv3/utils.ts (audit finding M9). Behaviour is unchanged: same skipReasons, same registryUrls, same handling of a missing repository or missing registryAliases config.
* refactor(manager/dockerfile): add an options form of getDep for CI managers
`getDep()` gains an overload taking a `GetDepOptions` object with
`specifyReplaceString`, `registryAliases` and `depType`, replacing the
opaque boolean second positional argument at the CI manager call sites.
The positional form keeps working for all other callers.
Migrated: bitbucket-pipelines, droneci, circleci, github-actions,
azure-pipelines and woodpecker.
Behaviour changes:
- azure-pipelines container resources now honour `registryAliases`, which
`extractContainer()` previously ignored
- woodpecker dependencies now carry `depType: 'docker'`, matching the
other CI managers
* refactor(manager/woodpecker): do not set depType on docker image deps
* refactor(manager/dockerfile): drop the positional getDep signature
* refactor(manager/helm-requirements): reuse helmv3 alias and repository helpers
Replace the duplicated alias-resolution and repository-classification logic in helm-requirements/extract.ts with the shared isAlias, resolveAlias and parseRepository helpers from helmv3/utils.ts (audit finding M9). Behaviour is unchanged: same skipReasons, same registryUrls, same handling of a missing repository or missing registryAliases config.
* refactor(workers): assemble the per-dependency lookup config in one place
The extracted constraints were merged with the same spread twice in
`fetch.ts`, once per package file and once per dependency, and
`constraintsVersioning` only at the package file level. Both levels now go
through `mergeExtractedConstraints()`, and `PackageDependency` gained the
`constraintsVersioning` which only `PackageFileContent` had.
The datasource `defaultConfig` was applied in `fetch.ts` before the lookup and
again in `flatten.ts` afterwards, because `Object.assign(dep, upd)` only copies
the `UpdateResult` fields back onto the dependency. Both call
`applyDatasourceDefaultConfig()` now. Persisting the merged defaults on the
dependency instead would have moved them into another precedence layer of
`flatten.ts`, which merges them over the update config, so the defaults keep
being applied twice.
Behaviour change: a `constraintsVersioning` set on a dependency by a manager is
now honoured, below the package file and the repository config. No manager sets
it yet.
* refactor(workers): normalise depName and packageName once after extraction
`massageDepNames()` only copied `packageName` into a missing `depName`, so the
opposite fallback was applied again in `fetch()` and re-derived at seven worker
call sites.
Extraction now normalises both directions once, via an exported
`normalizeDepNames()`, which also takes over the `depName` trimming that
`fetch()` used to do. Every consumer downstream of extraction reads the field it
wants directly: `fetch()`, the dependency dashboard, the auto-replace deps
signature, the attestation PR note, the commit body table, the OSV lookup and
the rollback PR note.
Both places which re-extract a package file outside the extract phase -
`checkBranchDepsMatchBaseDeps()` and `checkForPendingVersions()` - call
`normalizeDepNames()` on the freshly parsed deps first, so their names stay
comparable with the deps that went through extraction.
In-manager fallbacks are left alone: they run before extraction normalises the
names.
No behaviour change.
* Apply suggestion from @secustor
* refactor(workers): assemble the per-dependency lookup config in one place
The extracted constraints were merged with the same spread twice in
`fetch.ts`, once per package file and once per dependency, and
`constraintsVersioning` only at the package file level. Both levels now go
through `mergeExtractedConstraints()`, and `PackageDependency` gained the
`constraintsVersioning` which only `PackageFileContent` had.
The datasource `defaultConfig` was applied in `fetch.ts` before the lookup and
again in `flatten.ts` afterwards, because `Object.assign(dep, upd)` only copies
the `UpdateResult` fields back onto the dependency. Both call
`applyDatasourceDefaultConfig()` now. Persisting the merged defaults on the
dependency instead would have moved them into another precedence layer of
`flatten.ts`, which merges them over the update config, so the defaults keep
being applied twice.
Behaviour change: a `constraintsVersioning` set on a dependency by a manager is
now honoured, below the package file and the repository config. No manager sets
it yet.
* refactor(config): move applyDatasourceDefaultConfig next to getManagerConfig
Importing config/utils from the datasource module made tools/generate-imports.mjs load config options before manager-default-configs.generated.ts exists, breaking install in CI.
* test(manager/gomod): normalise dep names before running the lookup
* test(manager/gomod): explain why dep names are normalised
* test(workers): give the jsonata base dep a packageName like extraction does
* refactor(workers): assemble the per-dependency lookup config in one place
The extracted constraints were merged with the same spread twice in
`fetch.ts`, once per package file and once per dependency, and
`constraintsVersioning` only at the package file level. Both levels now go
through `mergeExtractedConstraints()`, and `PackageDependency` gained the
`constraintsVersioning` which only `PackageFileContent` had.
The datasource `defaultConfig` was applied in `fetch.ts` before the lookup and
again in `flatten.ts` afterwards, because `Object.assign(dep, upd)` only copies
the `UpdateResult` fields back onto the dependency. Both call
`applyDatasourceDefaultConfig()` now. Persisting the merged defaults on the
dependency instead would have moved them into another precedence layer of
`flatten.ts`, which merges them over the update config, so the defaults keep
being applied twice.
Behaviour change: a `constraintsVersioning` set on a dependency by a manager is
now honoured, below the package file and the repository config. No manager sets
it yet.
* refactor(config): move applyDatasourceDefaultConfig next to getManagerConfig
Importing config/utils from the datasource module made tools/generate-imports.mjs load config options before manager-default-configs.generated.ts exists, breaking install in CI.
* Apply suggestion from @secustor
* refactor(config): drop any from applyDatasourceDefaultConfig
* refactor(versioning/poetry): accept PEP 440 specifiers instead of a lookup special case
`filterVersions()` carried a poetry-shaped branch: when `allowedVersions` was no
valid poetry range but a valid PEP 440 specifier, it matched releases with the
pep440 versioning instead. Poetry accepts PEP 440 specifiers, so the poetry
versioning is where that belongs: `isValid()` falls back to `pep440.isValid()`
and `matches()` to `pep440.matches()` for a range poetry's own syntax cannot
express, and the three versioning imports leave `filter.ts`.
The `config.versioning !== npmVersioning.id` guard on the semver fallback is
dropped as well: npm's `isValid()` is `validRange()` over a normalisation which
only rewrites x-ranges, so it accepts everything `semver.validRange()` accepts
(checked over 163k generated ranges) and the fallback was already unreachable
for npm versioning.
Behaviour changes:
- Poetry `isValid()` now accepts PEP 440 specifiers such as `!=1.2.3` or
`>=2.6, !=3.0.*, <4`, which it used to reject. The poetry manager is
unaffected, because it tests pep440 before poetry when picking a versioning.
- Poetry `matches()` now answers those ranges through pep440 everywhere, not
only for `allowedVersions`.
- For poetry versioning, an `allowedVersions` which is an invalid poetry range
but valid as both a semver range and a PEP 440 specifier is now matched by
pep440 rather than semver, because the pep440 fallback moved ahead of the
semver one.
* fix(versioning/poetry): route every PEP 440-only range to pep440
CI caught `python` versioning's `isLessThanRange('1.9.0', '== 2.7.*')` throwing
`Invalid comparator: ==`: since poetry `isValid()` accepts PEP 440 specifiers,
the python wrapper dispatched that range to poetry, whose npm-based
`isLessThanRange()` cannot parse it. Only `matches()` had the pep440 fallback.
`isLessThanRange()`, `getSatisfyingVersion()`, `minSatisfyingVersion()` and
`getNewValue()` now delegate to pep440 for ranges poetry's own syntax cannot
express, and `subset()` answers `undefined` for them instead of throwing.
The `python` versioning's `poetry.isValid(range) ? poetry : pep440` ternaries
became dead code (poetry now answers every valid range itself, and both modules
receive the same invalid ranges), so the module is `{ ...poetry, isBreaking }`.
The poetry spec also gains rows for three branches nothing covered before: an
unparsable candidate in `getSatisfyingVersion()` / `minSatisfyingVersion()`,
and `getNewValue()` with the `*` range, for which npm's implementation returns
`null`.
* test(versioning/poetry): keep the new spec rows clear of main's coverage rows
main's #46252 appended rows to the same minSatisfyingVersion, getSatisfyingVersion and getNewValue tables, which made the stacked PR conflict with main. Those rows are adopted verbatim at the table ends and the pep440 rows move into the middle of each table, so both sides merge cleanly.
* refactor(workers/lookup): move the gomod pseudo-version check into the go datasource
The only manager-name check in `lookupUpdates()` relabelled an update between
two Go pseudo-versions as a `digest` update (#29034). Knowing that
`v0.0.0-<timestamp>-<commit>` identifies a commit rather than a release belongs
to the Go ecosystem, so `DatasourceApi` gains an optional `isPseudoVersion()`,
`GoDatasource` implements it, and the lookup asks the datasource instead of the
manager. The gomod manager's own `v0.0.0-` check calls the same helper.
Behaviour change: the relabelling is keyed on the `go` datasource instead of the
`gomod` manager, so it now also applies to the other managers using that
datasource (bazel, mise, ocb), and no longer applies to a `gomod` dependency
whose datasource was overridden to something else. The recognised
pseudo-version form is unchanged: only the `v0.0.0-` prefix, not every form
matched by `GoDatasource.pversionRegexp`.
* refactor(workers/lookup): ask the go-mod-directive versioning about pseudo-versions
Review feedback: version predicates are the domain of `lib/modules/versioning`,
not of the datasource API. `isPseudoVersion()` now lives in the
`go-mod-directive` versioning (the Go versioning module) and the optional
`DatasourceApi.isPseudoVersion?()` hook is gone. The lookup worker and the gomod
manager import the versioning helper directly.
Because the lookup no longer asks the datasource, the predicate has to be exact:
it matches the anchored `v0.0.0-<timestamp>-<commit>` shape (with the optional
pre-release segment `GoDatasource.pversionRegexp` also allows) instead of the
`v0.0.0-` prefix, so that no manager or datasource gating is needed. The forms
derived from tags (`v1.2.3-0.…`) stay unrecognised, as before.
* refactor(workers/lookup): keep the pseudo-version relabelling limited to gomod
Review feedback: the move of the predicate into the versioning module should
not widen which dependencies get relabelled. The `config.manager === 'gomod'`
condition is back in front of the `isPseudoVersion()` checks, so the lookup
behaves as on main.
* refactor(workers/lookup): ask the gomod versioning about pseudo-versions
Review feedback: the pseudo-version predicate has nothing to do with the `go`
directive, so it moves from `go-mod-directive` to the new `gomod` versioning,
which is the home for Go module version helpers (#44184).
The lookup worker and `gomod/update.ts` use its `isUntaggedPseudoVersion()`,
which is `isPseudoVersion()` limited to `v0.0.0-` pseudo-versions, so which
dependencies are relabelled or written directly stays as on main.
`go-mod-directive` is unchanged against main again.
* fix(workers/lookup): treat pseudo-versions of major version modules like v0 ones
Review feedback: Go writes a pseudo-version without a base release as
`vX.0.0-<time>-<commit>`, with the major version of the module path, so a
`/v2` module without releases gets `v2.0.0-…`. Only `v0.0.0-` was
recognised, so an update between two such pseudo-versions was not relabelled
as a digest update (#29034), and gomod/update.ts wrote the bare commit
instead of the new pseudo-version.
The lookup and the update now use `isPseudoVersion()` from the `gomod`
versioning, and `isUntaggedPseudoVersion()` is gone. The go datasource only
returns pseudo-versions for modules without releases, which always have that
form, so nothing else changes. The lookup keeps its `config.manager ===
'gomod'` condition.
* refactor(workers/lookup): drop the guards around isPseudoVersion()
Review feedback: `isPseudoVersion()` now accepts an undefined version, so
the lookup and gomod/update.ts pass their optional values to it directly.
* feat(versioning): add a `gomod` versioning
First step of #44184: a versioning for Go modules that behaves like `semver`
for now and is not the default anywhere yet, so it can be tried on repositories
before the `go` datasource switches to it.
It exports `isPseudoVersion()`, which follows `IsPseudoVersion()` from
golang.org/x/mod/module and recognises all three pseudo-version forms, as the
place for Go version helpers that do not belong to the `go` directive's
`go-mod-directive` versioning.
* refactor(versioning/gomod): accept an undefined version in isPseudoVersion()
Review feedback on #46145: the callers check optional values such as
`upgrade.newValue`, so `isPseudoVersion()` takes `undefined` and answers
`false` for it, and they no longer need their own guard.
* refactor(versioning/gomod): return early for an undefined version in isPseudoVersion()
fix(rubygems): preserve release timestamps for native gems
Include non-ruby platform suffixes when hashing release metadata so the identifiers match the RubyGems compact index. This prevents valid metadata from falling back to versions-only results and blocking minimum-release-age checks.
Cover generic, native, and absent platforms, cache reuse, mismatched platforms, and mixed-platform package lookups.
Go writes a placeholder pseudo-version for a module whose `replace`
directive points to a local path, with the major version of the module
path, such as `v2.0.0-00010101000000-000000000000` for a `/v2` module.
#41521 only skipped `v0.0.0-00010101000000-000000000000`, so Renovate
still looked up replaced `/v2` modules and proposed updates for them, such
as `v2.8.0` for oapi-codegen's `examples/go.mod`.
Any `vX.Y.Z-00010101000000-000000000000` is now skipped.
The Platform interface declared getBranchStatusCheck's context
parameter as string | null | undefined with a TODO questioning the
type (#22198). Every one of the nine concrete platform
implementations (azure, bitbucket, bitbucket-server, codecommit,
forgejo/gitea, gerrit, github, gitlab) already typed it as string, and
scm-manager was the lone holdout with the wider type. All three
callers (artifacts.ts, status-checks.ts, validate.ts) already narrow
to string before calling.
Narrow the interface and scm-manager's implementation to string, and
update the scm-manager spec that passed null to pass a string
instead. No runtime behaviour change.
Finding: P11
The `Platform` interface declared `addLabel?` and `commitFiles?`, but no
implementation defined `addLabel` and nothing called `platform.commitFiles`
through the platform proxy. `scm-manager/index.ts` also exported
`getRepoForceRebase`, but the interface method is `getBranchForceRebase?`,
so that export was never reached through the platform proxy either; its
only reference was its own spec.
- Removed `addLabel?` and `commitFiles?` from the `Platform` interface.
GitHub's `commitFiles` remains a plain module export, already consumed
directly by `GithubScm.commitAndPush` in github/scm.ts.
- Removed the dead `getRepoForceRebase` export and its spec block from
scm-manager.
- `CommitFilesConfig` stays imported in types.ts; `PlatformScm.commitAndPush`
still uses it.
No behaviour change. Finding P9 from the platform module refactoring audit.
* refactor(datasource): stop double-caching releases at the index level
15 datasources set `caching = true`, which makes the registry wrapper in
`lib/modules/datasource/index.ts` store every `getReleases` result under
`datasource-releases-<id>` for 15 minutes, while their own `cached()`
wrapper already stores the same result under `datasource-<id>` with a
longer TTL and stale-fallback. Drop `caching` from those 15; the four
that rely on the index cache alone (dart-version, flutter-version,
maven, pypi) keep it.
`caching` is documented as requiring the datasource to return the
`isPrivate` flag, and none of these 15 ever set it, so the index layer
was caching private results unconditionally. The remaining `cached()`
layer honours `cachePrivatePackages` as before.
Also fix two cache-key/registry defects found alongside:
- `galaxy-collection` declares `registryStrategy = 'hunt'` but keyed its
cache on the package name only, so a `null` from the first hunted
registry was replayed for the second one. The registry URL is now part
of the key, which invalidates existing entries once.
- `typst` ignores `config.registryUrl` and always reads its default
registry, so it now sets `customRegistrySupport = false`. A configured
`registryUrls` for typst is now warned about and ignored instead of
being silently dropped.
* Merge branch 'main' into secustor/refactor/datasource-remove-index-caching
refactor(manager/helm-requirements): reuse helmv3 alias and repository helpers
Replace the duplicated alias-resolution and repository-classification logic in helm-requirements/extract.ts with the shared isAlias, resolveAlias and parseRepository helpers from helmv3/utils.ts (audit finding M9). Behaviour is unchanged: same skipReasons, same registryUrls, same handling of a missing repository or missing registryAliases config.
As noted in #46343, upstream mise renamed a large number of `pipx`
registry entries to use the `pypi` backend instead, e.g. `ansible`
went from `pipx:ansible` to `pypi:ansible`.
This was caught during code review, but we should add something to
automagically catch this, by making sure that none of the backends in
use on an updated `mise registry` is unknown to Renovate.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
As we have a `conda` Datasource, we should support the `conda` backend
in mise.
This appears to have been missed from earlier implementations in the
mise manager.
(cherry picked from commit 8fa353f04ae1fe30d05eee0df60d0ca4749fdc1c)
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* feat(datasource): add GraalVM version datasource with support for JDK and JRE releases
* feat(datasource): add GraalVM version datasource with support for JDK and JRE releases
* feat(datasource): add GraalVM version datasource with support for JDK and JRE releases
* feat(datasource): add GraalVM version datasource with support for JDK and JRE releases
* feat(datasource): add GraalVM version datasource with support for JDK and JRE releases
* add coverage
* fix
* fix
* fix
* code cov
* code cov
* code cov
* refactor(datasource): integrate GraalVM into java-version datasource
Merges graalvm-version datasource into java-version as a unified multi-vendor
Java distribution datasource. Implements vendor-based modular architecture with
routing layer for Adoptium (Eclipse Temurin) and Oracle GraalVM.
Architecture:
- Vendor-specific handlers (adoptium.ts, graalvm.ts) with routing in index.ts
- Vendor-aware system detection with different arch/os mappings per vendor
- Custom registry support for GraalVM's mise-java API
- Adoptium remains the default registry for backwards compatibility
Package names:
- New explicit: adoptium-jdk, adoptium-jre, oracle-graalvm-jdk, oracle-graalvm-jre
- Legacy (map to Adoptium): java, java-jdk, java-jre
Changes:
- Created adoptium.ts and graalvm.ts vendor handlers
- Enhanced common.ts with vendor detection and vendor-specific system mappings
- Updated index.ts with routing layer and custom registry support
- Merged test suites with comprehensive coverage for both vendors
- Updated mise manager integration to use JavaVersionDatasource
- Removed graalvm-version datasource directory
All 65 datasource tests and 93 mise manager tests passing.
* fix
* test(datasource): add coverage for non-HttpError paths in java-version
* fix(datasource): remove dead code and add coverage for java-version
Remove unreachable HttpError handling from _getReleases catch block
since both getAdoptiumReleases and getGraalvmReleases handle HttpError
internally. Add test for the graalvmRegistryUrl fallback when
registryUrl is undefined.
* fix(datasource): address review comments for GraalVM datasource
- Remove unused 'datasource-graalvm-version' cache namespace
- Convert MiseJavaRelease interface to Zod schema and derive type from it
- Use http.getJson() with the Zod schema in getGraalvmReleases instead
of getJsonUnchecked, letting the schema handle invalid/empty responses
- Update getGraalvmReleases test mock to use getJson
* docs: remove unused datasource-graalvm-version from cacheTtlOverride docs
* fix(datasource): preserve Adoptium config typing
* fix(datasource): harden GraalVM release parsing
* fix(datasource): address GraalVM review feedback
* test: cover GraalVM mise package mapping
* test(datasource): cover default GraalVM registry fallback
* test(datasource): cover legacy registry resolution
* test(datasource): type legacy datasource mocks
* fix(datasource): harden GraalVM defaults and responses
* refactor(datasource): use function-only registry accessors
* test(datasource): cover registry accessor functions
* test: restore coverage exclusions
* chore: retrigger CI checks
Every datasource that caches its releases hand-wrote the same
`withCache({ namespace: `datasource-${id}`, ... }, () => this._getReleases(config))`
wrapper, repeating the namespace literal and using underscore-prefixed
method names that `docs/development/best-practices.md` discourages.
Add `Datasource.cacheNamespace` (derived from the datasource id) and a
protected `Datasource.cached()` helper that defaults `namespace` to it,
exporting `CachedOptions` from `with-cache.ts`. Migrate 29 datasources
onto the helper, dropping their namespace literals, the static
`cacheNamespace` field in `github-digest`, and renaming the wrapped
`_getX` methods to `fetchX`.
Behaviour change: `golang-version` used the constant cache key `'all'`
while declaring `customRegistrySupport = true`, so a custom registryUrl
shared the cache entry with the default one. The key is now
`${config.registryUrl}`, which invalidates existing entries once.
Seven datasources (bitbucket-tags, bitbucket-server-tags,
gitlab-releases, gitea-tags, gitea-releases, forgejo-tags,
forgejo-releases) declared DatasourceApi metadata fields
(defaultRegistryUrls, releaseTimestampSupport/Note,
sourceUrlSupport/Note) as class `static readonly` instead of
instance fields. The contract (DatasourceApi, datasource.ts) reads
these off the instance, so the base class defaults silently applied
instead. Convert them to instance fields (`override readonly`, the
terraform-module pattern), keeping a static array only where a
static helper (or lib/modules/datasource/go/) still needs it, backed
by `override readonly defaultRegistryUrls = <Class>.defaultRegistryUrls`.
Delete the redundant `static readonly registryStrategy = 'first'`
(gitlab-releases, bitbucket-tags) and `static readonly
customRegistrySupport = true` (bitbucket-tags), which only matched
the base default by coincidence.
Replace the dead 'validates datasource' test in
lib/modules/datasource/index.spec.ts, which filtered out every
class-based datasource before validating (all 82 are class-based), with
a metadata contract test over getDatasources(): no listed metadata
name may be declared as a static-only property, releaseTimestampNote
requires releaseTimestampSupport, and sourceUrlNote requires
sourceUrlSupport !== 'none'.
Behaviour changes:
- These 7 datasources now report a real defaultRegistryUrls (or
releaseTimestampSupport/sourceUrlSupport) to the registry
(lib/modules/datasource/index.ts), so requests without an explicit
registryUrl now go through the registry-URL resolution and
getRegistryReleases package-cache path instead of calling
getReleases directly. getDigestConfig now receives a resolved
registryUrl instead of undefined for these datasources.
- Generated docs (tools/docs/datasources.ts,
tools/docs/minimum-release-age.ts) will render the real
"Release timestamp support" / "Source URL support" values and list
these datasources under minimumReleaseAge support, instead of "No".
* fix(extract): pass vulnerability alert state to managers
Managers cannot tell whether vulnerability remediation is active, so they
cannot decide to extract dependencies which are only useful to a security
update, e.g. transitive dependencies in a lock file.
Add `hasVulnerabilityAlertsRules` to `ExtractConfig`, derived from any
vulnerability source: `osvVulnerabilityAlerts`, or platform alerts, which
are turned into `isVulnerabilityAlert` package rules during init.
The flag is part of the extraction fingerprint, so cached extract results
are invalidated when it changes.
* refactor: drop redundant JSDoc on hasVulnerabilityAlertsRules
* docs(manager): document hasVulnerabilityAlertsRules on ExtractConfig
* fix(extract): omit hasVulnerabilityAlertsRules from fingerprint when false
Keeps the extract config hash unchanged for repositories which have no
vulnerability alerts, so they do not re-extract once on upgrade.
* fix(versioning): use BigInt to avoid integer precision loss in gradle, maven and loose
* fix(versioning): preserve exact update types
* Update lib/modules/versioning/maven/index.ts
* fix(versioning): satisfy func-style and prefer-at lint rules
* treat missing loose version section as zero in isSame
* fix coverage
* revert unrelated custom-manager rangeStrategy change
---------
Co-authored-by: Sergei Zharinov <zharinov@users.noreply.github.com>
As noted in #46343, upstream mise renamed a large number of `pipx`
registry entries to use the `pypi` backend instead, e.g. `ansible`
went from `pipx:ansible` to `pypi:ansible`.
As we didn't previously recognise `pypi` as a backend, we'd silently
stop updating those dependencies when we updated the mise registry
in #46343.
As the `pypi` uses the same tool syntax as `pipx`, we can share the
existing implementation.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>