* fix(manager): handle registryAliases with shell variable defaults
Allows `registryAliases` keys to contain shell-style variables with
empty (or other) defaults, e.g. `${DEPENDENCY_PROXY:-}` or
`${CI_REGISTRY:-}`. The same image string is then resolved both
online (variable expanded) and offline (variable empty).
Changes in `dockerfile/extract.ts` (used by `gitlabci` too):
* Match the alias key as either `${name}/...` (existing) or `${name}...`
when `name` already ends in a non-identifier boundary character such
as `}`. Bare-identifier keys like `$CI_REGISTRY` continue to require
the slash boundary so they no longer overmatch keys that begin with
the same prefix (e.g. `$CI_REGISTRY` vs `$CI_REGISTRY_IMAGE`).
* Use `ensureTrailingSlash` to handle alias values that already include
a trailing slash.
* Preserve the original `name` and path structure in `dep.depName`
instead of substringing only after the alias `value`. This keeps the
variable in the depName so it survives a `splitImageParts` round-trip
and the resulting branch name comes out clean.
Adds `sanitizeDepName` regex passes in
`lib/workers/repository/updates/flatten.ts` so any leftover
`${VAR}`/`${VAR:-...}` placeholder is stripped from the depName before
it becomes a branch name (otherwise we'd get
`renovate/${dependency_proxy}python-3.x` instead of
`renovate/python-3.x`).
Tests cover:
* `${VAR:-}/image` (with slash) and `${VAR:-}image` (no slash, requires
the boundary form).
* Overlapping prefixes: `$CI_REGISTRY` vs `$CI_REGISTRY_IMAGE`.
* Registry alias with port (`localhost:5000/repo`).
* `sanitizeDepName` strips `${VAR}` / `${VAR:-}` / bare `$VAR`.
Reproducer: https://github.com/Wayneoween/renovate-36293-repro
* revert(manager/gitlabci): keep regex group name as 'prefix'
Reverting the unrelated `prefix` -> `rawPrefix` rename in `depProxyRe`.
Per review on #36293, this rename is out of scope for the registry-alias
fix and just adds review surface.
* refactor(manager/dockerfile): narrow alias boundary check to '}'
Per review on #36293. The previous regex `/[^A-Za-z0-9_]$/` matched any
non-word ending, which is broader than the documented case (alias keys
ending in `}` from `${VAR}` / `${VAR:-...}`). Replace with a plain
`name.endsWith('}')` check, which also avoids re-building a regex on
every iteration of the alias loop.
Existing tests (`'variables with default and slash'`,
`'variables with default no slash'`, `'alias with digest only'`)
continue to exercise the `}`-boundary path; the `'overlapping prefixes'`
case continues to exercise the slash-only path.
* chore(manager/dockerfile): trim comment and TODO library/ strip edge
Per review on #36293:
* Drop the verbose explanation block above the depName-restore branch;
the spec rows already document the expected shape.
* Add a TODO above the `dep.depName?.startsWith(valueWithSlash)` guard
noting a pre-existing edge case: when the inner `getDep` strips a
`library/` prefix (or similar) the depName no longer starts with
`valueWithSlash`, so the alias-rooted depName is not restored. Out of
scope for this PR.
* fix(manager/dockerfile): handle empty registry alias value
- strip trailing slash after ${VAR} placeholders in sanitizeDepName
- treat an empty registry alias value as Docker Hub instead of '/'
- clarify registry alias docs wording
* refactor(manager/dockerfile): drop redundant alias boundary guard
- `matchedAtBoundary` is only read behind `!matchedWithSlash`
- add docker-compose test for `${VAR:-}` registry aliases
* test(manager/dockerfile): pin special-prefix registry alias behavior
`getDep` strips `library/`, `amd64/` and `arm64/` as special prefixes, so
an alias whose value is one of those loses its alias-rooted `depName`.
Both the slash form and the variable form behave this way on `main`.
* refactor(linters): add prefer-coerce-array rule
Refs #45217
`x ?? []` and `coerceArray(x)` say the same thing, but only the second
one is searchable and consistent. The rule flags a `??` whose default is
a bare `[]` literal; a non-empty default or an asserted `([] as Foo[])`
still passes.
Applying it across `lib/` surfaced three spots the helper cannot cover,
which keep `?? []` with a disable comment or a narrower fix:
- `package-files.ts` destructures a tuple, which `coerceArray()` widens
- `generate.spec.ts` defaults `matchAll()`, an iterator rather than an array
- `mise/upgradeable-tooling.ts` declares a `Record` return, so its
`?? []` fallback was wrong to begin with and becomes `coerceObject()`
* refactor(platform/github): hoist the GHE version header lookup
`Object.entries(...).find()` returns a tuple, and defaulting it with
`?? []` only to destructure the second element reads as an array
default when it is not one. Name the found entry instead, which drops
the `?? []` rather than routing a tuple through `coerceArray()`.
* refactor(oxlint): enable func-style
Enable the built-in func-style rule as ["warn", "declaration"] so that
named functions are written as function declarations instead of arrow or
function expressions assigned to variables, matching the convention in
docs/development/best-practices.md (Functions section). Inline arrow
callbacks are unaffected; prefer-arrow-callback continues to cover the
callback direction.
Severity is "warn" instead of "error" as a fallback: a repo-wide run
found 196 pre-existing violations (70 in spec files, 126 in production
code), exceeding the 80-violation fix threshold for this change, so no
violations were fixed here. Follow-up work can convert the offenders
(largest clusters: lib/modules/versioning/ruby, lib/util/cache/package,
lib/modules/versioning/maven, lib/modules/versioning/gradle) and then
raise the rule to "error". Note oxlint 1.72 also supports an
allowTypeAnnotation option if typed consts should remain arrows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(linter): enforce func-style at error
* refactor(func-style): convert const-arrow functions to declarations in with-cache spec and ruby versioning
* refactor(func-style): convert const-arrow functions to declarations in maven/gradle modules
* refactor(func-style): convert const-arrow functions to declarations in remaining versioning modules
* refactor(func-style): convert const-arrow functions to declarations in platform modules
Discriminated-union closures (ensureCommentRemoval byTopic/byContent
helpers in github, gitlab, bitbucket, bitbucket-server) needed the
narrowed field passed explicitly as a parameter, since function
declarations are hoisted and lose the outer if-narrowing that inline
arrow-function closures previously relied on.
* refactor(func-style): convert const-arrow functions to declarations across util/manager/datasource modules
One case (logger/renovate-logger.ts logOnceFn) is kept as an arrow
function with a documented oxlint-disable: it is stored on
this.logger.once[level] and relies on lexically-bound this, which a
hoisted function declaration would not preserve.
* refactor(func-style): convert remaining const-arrow test helpers to declarations
get-updated.spec.ts: hoisted expectPipCompilePackageAndLockFile to
module scope (it only closes over the module-level pipCompile mock)
and added a documented oxlint-disable for vitest/expect-expect on its
caller test, since oxlint's expect-expect check does not trace
assertions through an externally-defined helper function.
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Enable the unicorn/prefer-at rule as error in .oxlintrc.json and fix all
43 pre-existing violations (arr[arr.length - 1] -> arr.at(-1)) via oxlint
autofix. Where .at() widened the type to T | undefined, non-null
assertions were added at sites where surrounding logic guarantees the
element exists (length guards, split results), preserving the original
runtime behavior and typing.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix(npm): remove old dependency when replacement exists
* Add coverage ignore comments
* Simplify implementation
* Rename to removeAsString
* Move it after replaceAsString
* Improve test case
* Improve error message of replaceAsString
* Fix coverage
* Fix coverage again
* Only remove dependency at depType like replaceAsString
* Refactor tests
* Fix tsc
* fix(npm): skip update when replacement dependency already exists
* Simplify else
* Avoid returning an error
* fix(flatten): skip replacement updates when a sibling dependency already exists
* Revert the other changes
* Also handle it in the Dependency Dashboard
* Filter out earlier
* Try some other way
* Try fix dep dashboard
* Try fix again
* Extract helper
* Improve some stuff
* Improve assertion
* Remove misleading comment
* Address review comments
When we're preparing the final, flattened, list of branches to prepare
updates for, we're not filtering out any dependencies that have a
`skipReason` in them.
In the case that, as part of future changes like #42510, a `skipReason`
may be added after the `lookup` phase, we can still get PRs raised even
when they shouldn't be.
We already filter out `enabled=false`, so we should make sure to also
filter anything with a `skipReason`.
* test: add additional case for attestation changes
* fix: correctly warn when an attestation is missing
As noted in #37258, when a package registry had previously seen an
attestation for authenticity of a given package release, Renovate should
warn if future updates then lose authenticity.
Our previous attempt at this didn't quite pass around the current
package's attestation, which results in no warnings.
Given recent supply chain attacks where an attestation was removed (such
as Axios in MSC-2026-3522), we should make sure that this logic does
work correctly, and flags to our users.
In the future, we'll add more checks and a failing status check.
By introducing `hasAttestation` in the `LookupUpdate`, this can now be
matched on with `matchJsonata`, as well as providing visibility in the
`packageFiles with updates` log line.
* fixup! fix: correctly warn when an attestation is missing
> Run `pnpm run jest
> lib/workers/repository/process/lookup/index.spec.ts` and handle any test
> failures - the implementation is correct, so update the tests
Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
* test: clarify that we don't check for intermediate releases
Which we'll look to improve as part of future changes.
* chore: fix typo
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---------
Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Moves datasource, manager, platform and versioning code from lib/ into new lib/modules/
BREAKING CHANGE: External tools must update paths to datasource, manager, platform and versioning
Lock file maintenance was broken as various managers rely on the
`isLockFileMaintenance` update flag to be set. This was not the
case as its config is generated afterwards (without the is*
auto-propagation).
Resets any language or manager` additionalBranchPrefix` values to empty string. Add the `compatibility:additionalBranchPrefix` prefix to restore previous behavior.
BREAKING CHANGE: Removal of default `additionalBranchPrefix` values will cause branch names to change for docker/helm/buildkite/cargo/homebrew.
Removes code which ensured rules with updateTypes always ran last and therefore had higher priority.
Closes#4482
BREAKING CHANGE: Package Rules will be evaluated in the order they are configured, instead of evaluating rules with updateTypes last.