Commit Graph

27161 Commits

Author SHA1 Message Date
Jamie Tanna 5ee51fdf39 fix(deps): promote tar to a prod dependency (#45699)
Thanks to reports in #40250 and #45697, the release of
795d083264 broke Renovate users, as the
`tar` dependency isn't treated as a prod dependency.

We need to make sure to promote it up.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
44.64.1
2026-09-04 14:32:57 +00:00
Adam Setch 10c5232778 feat(preset): @octokit group preset (#45643)
Signed-off-by: Adam Setch <adam.setch@outlook.com>
44.64.0
2026-09-04 12:36:35 +00:00
Punsoong Khut 795d083264 feat(datasource): add APK datasource support (#40250)
* feat(datasource): add APK datasource support

* remove missing manager link for now

* lint docs

* update tests

* replace binary fixtures

* fix coverage

* Update lib/modules/datasource/apk/readme.md

Co-authored-by: Jamie Tanna <github@jamietanna.co.uk>

* Apply suggestion from @viceice

Co-authored-by: Michael Kriese <michael.kriese@gmx.de>

* use tar instead of tar-stream

* use codeBlock

* add ignore back

* make method private

* use an async extract instead of list

* add usage example

* stream apkindex download and parse line-by-line

* refactor(datasource): address review comments on APK datasource

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: sync pnpm-lock.yaml after merge

Co-authored-by: Cursor <cursoragent@cursor.com>

* test: remove ignored lines

As they seem to be covered, anyway.

* fixup! Merge remote-tracking branch 'origin/HEAD' into apk-datasource

* fixup! fixup! Merge remote-tracking branch 'origin/HEAD' into apk-datasource

* lint: use `node:` prefix

* Update lib/modules/datasource/apk/index.ts

Co-authored-by: Michael Kriese <michael.kriese@gmx.de>

* refactor(datasource/apk): use asTimestamp millis instead of new Date

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(datasource/apk): rename uncached method to _getPackages

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(datasource/apk): encode registry URL parts as query parameters

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(datasource/apk): reject invalid registry URLs, skip caching empty indexes

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(datasource/apk): throw on unparseable registry URL and drop unset sourceUrl support

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(datasource/apk): show how registry URL parameters build the index URLs

Co-authored-by: Cursor <cursoragent@cursor.com>

* Apply suggestions from code review

Co-authored-by: RahulGautamSingh <rahultesnik@gmail.com>

* fix(datasource/apk): keep credentials and port in component URLs

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(datasource/apk): extract APKINDEX by basename and key packages by name

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(datasource/apk): report a version served by two components only once

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Jamie Tanna <github@jamietanna.co.uk>
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Jamie Tanna <jamie.tanna@mend.io>
Co-authored-by: RahulGautamSingh <rahultesnik@gmail.com>
44.63.0
2026-09-04 12:25:21 +00:00
Jamie Tanna 8abbd14fe6 fix(config/validation): allow only capturing currentDigest in Custom Managers (#45671)
* fix(config/validation): allow only capturing `currentDigest` in Custom Managers

As reported in #45665, it was previously possible - through a preset
prior to 44.60.1 - to specify a Custom Manager (in this case, with
Regex) that only captured the `currentDigest` for a dependency.

This causes config validation in a repository, but as it appears to be
valid - with `currentValue` defaulting to `latest` - we should make it
possible to use either `currentValue` or `currentDigest`.

* fixup! fix(config/validation): allow only capturing `currentDigest` in Custom Managers
44.62.2
2026-09-04 11:30:15 +00:00
Tiago Novo 7f71c26283 fix(datasource): use release-level registryUrl in postprocessRelease (#45096)
When a datasource uses the 'merge' registryStrategy (e.g. maven),
mergeRegistries() tags each release with the registryUrl of the repo
that actually reported it. postprocessRelease() ignored this and used
the first configured/default registryUrl instead, causing the Maven
datasource to probe the wrong repository for release verification.
If the artifact didn't exist in that first repo, the release was
wrongly rejected and no update was proposed, even though a valid
release existed in another configured repository.
2026-09-04 11:23:50 +00:00
Robert 4db863563a fix(versioning/nuget): bare exact version bypasses ignoreUnstable (#45087)
fix(versioning/nuget): bare exact version pin resolves currentVersion to a pre-release, bypassing ignoreUnstable
2026-09-04 11:18:27 +00:00
Jonah Snider 5f5e58b822 fix(presets): fix javaLTSVersions not preserving partial semver for mise Java versions (#44899)
* fix(presets): fix javaLTSVersions not preserving partial semver for mise Java versions

Signed-off-by: Jonah Snider <jonah@jonahsnider.com>

* test(presets): remove obsolete type assertion

Signed-off-by: Jonah Snider <jonah@jonahsnider.com>

* test(presets): type package rule result

Signed-off-by: Jonah Snider <jonah@jonahsnider.com>

---------

Signed-off-by: Jonah Snider <jonah@jonahsnider.com>
2026-09-04 11:15:21 +00:00
Žiga Magajna 69bc2dde90 fix(manager/mix): run mix commands from the lock file's directory (#44971) 2026-09-04 11:06:40 +00:00
ntsk 9d1070091a fix(manager/pep621): support array form of tool.uv.sources (#44970)
* test(manager/pep621): cover array uv sources

* fix(manager/pep621): support array uv sources

* test(manager/pep621): cover unknown source fallback
2026-09-04 11:06:07 +00:00
Sebastian Poxhofer 05e1271376 test: use expect().resolves instead of awaiting inside expect (#45672)
Enables the vitest/prefer-expect-resolves oxlint rule and applies its
autofix across the spec suite.
2026-09-04 10:40:46 +00:00
Sebastian Poxhofer 300e3a616c test: shrink oversized fixtures to representative examples (#45666)
* test: reduce oversized expectation literals to representative examples

* test: shrink oversized fixtures instead of trimming assertions

Cut the real-world fixtures down to a representative set of entries that still covers every parser shape, and assert the complete output again with a single toEqual.
2026-09-04 10:40:45 +00:00
Sebastian Poxhofer 0ff377b688 test(linters): forbid file-based snapshot matchers (#45661)
* test(linters): forbid file-based snapshot matchers

* test(linters): drop inline snapshot recommendation

* test(linters): assert on relevant sections instead of full bodies
2026-09-04 10:28:56 +00:00
Sebastian Poxhofer df8c4051ff test(core): replace file snapshots with explicit assertions (#45660)
* test(core): replace file snapshots with explicit assertions

* test(core): replace inline snapshots with explicit assertions

* test(core): assert on relevant sections instead of full bodies

* test(core): drop assertions implied by full equality

* test(core): address review feedback

* test(core): use resolves instead of awaiting inside expect
2026-09-04 10:28:55 +00:00
Sebastian Poxhofer 762ac01133 test(platform): replace file snapshots with explicit assertions (#45684)
* test(manager): replace file snapshots with explicit assertions

* test(manager): replace inline snapshots with explicit assertions

* test(manager): assert on relevant sections instead of full bodies

* test(manager): drop assertions implied by full equality

* test(manager): address review feedback

* test(manager): assert depType and versioning in the regex matcher

* test(bundler): replace file snapshots with explicit assertions

* test(bundler): replace inline snapshots with explicit assertions

* test(bundler): drop assertions implied by full equality

* test(bundler): address review feedback

* test(npm): replace file snapshots with explicit assertions

* test(npm): replace inline snapshots with explicit assertions

* test(platform): replace file snapshots with explicit assertions

* test(platform): replace inline snapshots with explicit assertions

* test(platform): assert on relevant sections instead of full bodies

* test(platform): address review feedback

* test(platform): use resolves instead of awaiting inside expect
2026-09-04 10:28:54 +00:00
Gauke Teijema e10ef79236 fix(bump-versions): collect bumpVersions from all upgrades, not just upgrades[0] (#44809)
* fix(bump-versions): collect bumpVersions from all upgrades, not just upgrades[0]

* chore: add test for duplicate bumpversion configs

* chore: use suggested safeStringify

* chore: use coerceArray
44.62.1
2026-09-04 10:09:28 +00:00
Sergei Zharinov 09ff8d22b6 test: Validate minimumReleaseAge is ignored for security updates (#44272)
* test: validate minimumReleaseAge does not apply to security updates

* test: add end-to-end coverage for security-update minimumReleaseAge bypass

Drive the real vulnerability flow (appendVulnerabilityPackageRules) through the
real lookupUpdates, instead of only simulating the generated packageRule. Also
reword the inline comment and use luxon/asTimestamp for timestamps.

* test: fix type-check on e2e lookup config

Cast the spread config to satisfy partial() overload resolution, matching the
existing `getConfig() as never` idiom in the lookup spec.

* test: drop redundant inline lookup test in favor of end-to-end coverage

The simulated lookup test hand-built the security packageRule; the end-to-end
test plus the generated-rule assertion in vulnerabilities.spec.ts cover the same
behavior against the real flow, so the inline test added no unique coverage.

* test(vulnerability): align lookup config types
44.62.0
2026-09-04 09:31:58 +00:00
Jamie Tanna fe9ce38e2a feat(replacements): add replacement for OpenSSF Scorecard Docker images (#45597)
As per #45568 the OpenSSF Security Scorecard project is moving from the
Google Container Registry (GCR) to the GitHub Container Registry
(GHCR)[0].

This may not work if users are on 5.5.0, as [0] notes that it already
existed prior to the migration, but otherwise we shouldn't need to
specify a version, given it's a like-for-like replacement.

[0]: https://github.com/ossf/scorecard/issues/5208

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-04 09:24:16 +00:00
Sebastian Poxhofer f4fa861457 test(npm): replace file snapshots with explicit assertions (#45658)
* test(npm): replace file snapshots with explicit assertions

* test(npm): replace inline snapshots with explicit assertions
2026-09-04 06:36:41 +00:00
Sebastian Poxhofer 5a9c0852bf test(bundler): replace file snapshots with explicit assertions (#45657)
* test(bundler): replace file snapshots with explicit assertions

* test(bundler): replace inline snapshots with explicit assertions

* test(bundler): drop assertions implied by full equality

* test(bundler): address review feedback
2026-09-04 06:36:40 +00:00
Sebastian Poxhofer 2fc46bdcfa test(manager): replace file snapshots with explicit assertions (#45656)
* test(manager): replace file snapshots with explicit assertions

* test(manager): replace inline snapshots with explicit assertions

* test(manager): assert on relevant sections instead of full bodies

* test(manager): drop assertions implied by full equality

* test(manager): address review feedback

* test(manager): assert depType and versioning in the regex matcher
2026-09-04 06:36:39 +00:00
renovate[bot] a01be618a0 build(deps): update dependency p-map to v7.0.7 (main) (#45678)
build(deps): update dependency p-map to v7.0.7

| datasource | package | from  | to    |
| ---------- | ------- | ----- | ----- |
| npm        | p-map   | 7.0.6 | 7.0.7 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
44.61.6
2026-09-03 23:25:19 +00:00
renovate[bot] 894a4a6f4b chore(deps): update dependency @biomejs/biome to v2.5.11 (main) (#45676)
chore(deps): update dependency @biomejs/biome to v2.5.11

| datasource | package        | from   | to     |
| ---------- | -------------- | ------ | ------ |
| npm        | @biomejs/biome | 2.5.10 | 2.5.11 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
44.61.5
2026-09-03 21:25:16 +00:00
renovate[bot] af68f3722f build(deps): update dependency markdown-it to v14.3.1 (main) (#45675)
build(deps): update dependency markdown-it to v14.3.1

| datasource | package     | from   | to     |
| ---------- | ----------- | ------ | ------ |
| npm        | markdown-it | 14.3.0 | 14.3.1 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-03 21:24:57 +00:00
Jack Myers a744f0d8b6 fix(github): model GitHub hosts explicitly (#45605)
* refactor(github): model GitHub hosts explicitly

* refactor(github): move `isGithubEnterpriseServer()` to utils

* test(github): cover version-gated features with unknown GHES version
44.61.4
2026-09-03 18:27:01 +00:00
Jamie Tanna c2a4f4942f docs: add warning to checkedBranches
As we'll follow-up in #45668.
44.61.3
2026-09-03 16:03:26 +01:00
Jamie Tanna 4530b9e8c2 fix(workers/repository): ensure internal checks are applied when a rebase is requested
Previously, if we ticked the checkbox for a PR that's open, but has
pending updates, we recreate the branch with the latest version,
regardless of whether it's `pending` or not.

This can lead to cases where we accidentally bring an update that's not
passed `minimumReleaseAge` into the branch.

To prevent this, we can make sure that we only treat a Dependency
Dashboard checkbox/PR rebase request as consent for an update when it is
the new `unpend` check, or when using `checkedBranches`.

For visibility, we both log an INFO and `ensureComment` on the PR to
indicate why this branch isn't being updated past the version we're
currently proposing (which may change from the rebase update, but won't
include a pending version).

The comment is removed once a requested rebase is applied, and is only
removed when rebases are requested, avoiding unnecessary platform
requests on non-rebase updates.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 16:03:26 +01:00
Jamie Tanna bb8c9cbc7f refactor(workers/repository): add a separate check for "don't make this branch as pending"
As part of follow-up changes, we're looking to correct behaviour when
rebasing a given open PR, where the PR includes a set of pending
changes.

Before we do this, we can refactor the dependency dashboard to add a new
`unpend` check type, to say "create a branch, even though I know the
branch is pending status checks".

Previously, this section would share `approvePr` alongside other checks,
which may not make sense.

As `approvePr` currently forces PR creation, we need to treat `unpend`
similarly, so we don't create the branch, but not the PR when i.e.
`prCreation=approval`.

As the Dashboard is being re-rendered, a checkbox that was previously
checked (before this version of Renovate) will need re-checking.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 16:03:26 +01:00
Jamie Tanna f1c39b202a refactor(workers/repository): extract a type for the Dependency Dashboard checks
As part of future changes, we're adding a new type of checkbox for the
Dependency Dashboard.

Before we do this, we can extract an enum for the known types.

We don't touch `dependencyDashboardChecks` itself, as that also includes
`configMigrationCheckboxState`, which isn't related to the per-branch
checks.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 16:03:26 +01:00
oliverpool 0bfd189a2e fix: skip empty post upgrade task (#45227)
* tests: empty postUpgradeTasks should be skipped

* fix: skip empty post-upgrade task

* check: prettier
2026-09-03 14:39:12 +00:00
Langning Zhang 80ed949229 fix(manager/gitlabci): support ~latest component refs (#45234) 2026-09-03 14:34:50 +00:00
Sebastian Poxhofer f4ab79f2a5 test(datasource): replace file snapshots with explicit assertions (#45655)
* test(datasource): replace file snapshots with explicit assertions

* test(datasource): replace inline snapshots with explicit assertions

* test(datasource): drop assertions implied by full equality

* test(datasource): address review feedback
2026-09-03 14:31:08 +00:00
Birger Johan Nordølum 19e4cdc47f fix(lookup): preserve current compatibility (#45171)
* fix: preserve current compatibility after lookup

* fix: expose current compatibility in lookup result

* test: preserve current compatibility after lookup

* test: preserve compatibility through fetch

* test: isolate current compatibility regression

* test: isolate current compatibility regression

* test: isolate current compatibility regression

* test: isolate current compatibility regression
2026-09-03 14:29:15 +00:00
jeffreyzant fa7abab44e fix(manager/npm): massage out lockstep siblings pinning the replaced version (#45085)
* fix(manager/npm): massage out lockstep siblings pinning the replaced version

When updating an npm dependency, the package-lock massage deletes only
node_modules/<depName> before running npm install. Lockstep monorepo
siblings (e.g. vue -> @vue/server-renderer) that exact-pin the updated
dependency stay in the lock at the old version. npm then places the
fresh dependency into the hole, keeps the stale sibling (it still
satisfies its own demanding edges), and hard-fails with ERESOLVE on the
sibling's exact peer pin.

Also massage out lock entries whose dependencies/peerDependencies pin
the updated dependency to exactly the version being replaced, so npm
re-resolves the whole family in lockstep. The version guard keeps the
deletion precise: range pins and unrelated exact pins are untouched.

See discussion 44664.

* fix(manager/npm): address review feedback

- drop unreachable packages guard, wrap deletion loop instead
- flatten sibling check with early continue
- match exact pins per field, including optionalDependencies
- inline lockfile fixture, cover all three pin paths
2026-09-03 14:28:04 +00:00
RahulGautamSingh c5f50ddca6 docs: clarify prCreation=not-pending fallback and no-check caveat (#44889) 44.61.2 2026-09-03 12:57:01 +00:00
Colden Cullen 029663d169 fix(manager/flux): strip templates from resource files (#43198)
This allows flux resources to be checked when inside helm templates.
2026-09-03 12:51:18 +00:00
Marius b22f58045e fix(manager): Handle variables with default values in registry aliases (#36293)
* 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`.
2026-09-03 12:43:47 +00:00
Dharma Teja Thoutam 40fce9aba7 fix(gerrit): resolve relative submodule URLs for nested project paths (#44667)
* fix(gerrit): resolve relative submodule URLs for nested project paths

* Fix tests after rebase

---------

Co-authored-by: Felipe Santos <felipe.santos@ericsson.com>
2026-09-03 12:41:31 +00:00
renovate[bot] ff36228e54 chore(deps): update dependency lint-staged to v17.4.1 (main) (#45664)
chore(deps): update dependency lint-staged to v17.4.1

| datasource | package     | from   | to     |
| ---------- | ----------- | ------ | ------ |
| npm        | lint-staged | 17.3.0 | 17.4.1 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-03 11:18:21 +00:00
Kyle Welch 3228cc72b4 docs: document GitLab auth for private Go modules (#44371)
Private GitLab projects need a `hostType: "go"` host rule with a username and password so Renovate can authenticate the go-get request it uses to resolve a module's source repository. Without it GitLab returns a truncated go-import path for the unauthenticated request and the version lookup 404s.

Came up in discussion #37624 after the resolution change in #36963.
2026-09-03 11:18:15 +00:00
Sebastian Poxhofer 3412de84ce refactor(linters): enable oxlint rule prefer-named-capture-group (#44714)
* refactor(lint): enable oxlint prefer-named-capture-group at error

Numbered capture groups (m[1], $1) break silently when a regex is
edited and group order shifts. Named groups (?<name>...) make intent
explicit and accesses (m.groups.name) resilient to reordering.

This enables the built-in eslint rule prefer-named-capture-group,
surfacing 321 pre-existing unnamed-group violations across ~121
files to be burned down incrementally in follow-up commits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(versioning): name capture groups for prefer-named-capture-group

Burns down all prefer-named-capture-group violations in
lib/modules/versioning/. Unused capture groups (only reachable via
.test() or whole-match) become non-capturing (?:...); groups whose
value is read become named (?<name>...), with accesses rewritten to
match.groups!.<name> (or destructured from .groups!) instead of
positional match[n]/$n so a future edit that reorders groups cannot
silently break the reader.

Two cases needed extra care to preserve behavior:
- semver/common.ts and poetry/patterns.ts split() on a regex whose
  capture group is relied upon by String.prototype.split to keep the
  separator in the output array; the group is kept capturing and
  named, not converted to non-capturing.
- hashicorp/convertor.ts's semverRegex is only ever embedded via
  .source into a named `(?<version>...)` group elsewhere and never
  matched directly, so its internal groups are safe to make
  non-capturing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(datasource): name capture groups for prefer-named-capture-group

Burns down all prefer-named-capture-group violations under
lib/modules/datasource/. Same treatment as the versioning module:
unused groups become non-capturing, used groups get names, and
positional match[n] reads move to match.groups!.<name>.

docker/ecr.ts and pypi/common.ts keep their positional destructuring
(`const [, region] = ...`, `!!m &&`) working unchanged since a named
capture group is still addressable by its numeric index in
JavaScript — only pypi/common.ts's access was rewritten to
m.groups!.owner for clarity since it read a single group directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(platform): name capture groups for prefer-named-capture-group

Burns down all prefer-named-capture-group violations under
lib/modules/platform/. Uses the repo's established idiom of
`match.groups?.<name>` after an optional-chained exec()/match() (see
bitbucket/index.ts hostnameWithoutApiPrefix, gerrit/utils.ts
extractSourceBranch) and `$<name>` in String.replace replacement
strings. Unused groups (markdown/HTML massaging regexes matched only
to be stripped) become non-capturing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(manager): name capture groups in ansible-galaxy for prefer-named-capture-group

Burns down prefer-named-capture-group violations in
lib/modules/manager/ansible-galaxy/. newBlockRegEx and blockLineRegEx
dropped their unused outer wrapping group (only the inner key/value
groups were ever read) and named the key/value groups; nameMatchRegex's
remaining unused groups (protocol/user-info/port alternatives) become
non-capturing since only source/hostname/depName/version are read via
.groups. Accesses in collections.ts and roles.ts move from
lineMatch[2]/lineMatch[3] to lineMatch.groups!.key/value.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(manager): name capture groups for prefer-named-capture-group (batch 1)

Burns down prefer-named-capture-group violations across the first
alphabetical slice of lib/modules/manager/ (ansible through mix).
Used groups get names with accesses rewritten to match.groups!.<name>
(or $<name> in replacement strings); groups whose value is never read
become non-capturing (?:...). Two String.split() call sites
(git-submodules/extract.ts, meteor/extract.ts) keep the established
"named group still readable positionally from the split() result
array" idiom instead of restructuring the destructuring.

bazel/rules/go.ts and buildpacks/extract.ts dockerRef verified
byte-for-byte equivalent before/after via a quick node script since
several nested groups collapsed to non-capturing at once.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(manager): name capture groups for prefer-named-capture-group (batch 2)

Burns down prefer-named-capture-group violations across the remaining
alphabetical slice of lib/modules/manager/ (npm through terragrunt).
Same treatment as batch 1: used groups get names with accesses moved
to match.groups!.<name> or $<name> replacement strings; unused groups
(wrapping alternations, quantifier repetition groups only consumed via
.test(), or values never read from a match) become non-capturing.

terraform/extractors/others/modules.ts and terragrunt/modules.ts share
near-identical URL-parsing regexes (github/bitbucket/git/azure-devops
ref matchers) — the same set of always-unused `depth=`/`&depth=`
query-string groups is converted to non-capturing in both files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(config): name capture groups for prefer-named-capture-group

Burns down prefer-named-capture-group violations in lib/config/.
Used groups get names with replacement strings switched from $1/$2 to
$<name>; the unused separator group in schedule-migration.ts's
afterBeforeRegex becomes non-capturing. presets/parse.ts keeps
assigning through the already-declared `repo` variable rather than
array-destructuring the exec() result, matching this file's existing
style for the other named-group regexes just above it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(util): name capture groups for prefer-named-capture-group

Burns down prefer-named-capture-group violations across lib/util/ and
lib/logger/. Same treatment as previous batches: named groups for
values that are read (via $<name> replacement strings, .groups!.<name>,
or destructured from .groups), non-capturing groups where nothing reads
the captured value (e.g. semantic.ts's angular-commit .test()-only
regex). www-authenticate.ts's tokenizer entries each get their own
named group but keep accessing the match generically via match[1],
since a positionally-indexed named group is still readable by index.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(workers): name capture groups for prefer-named-capture-group

Burns down prefer-named-capture-group violations in lib/workers/.
Used groups get names with $<name> replacement strings; unused
wrapper/alternation groups (e.g. semantic-commit-message.ts's optional
scope/issue wrappers, release-notes.ts's date-heading and
horizontal-rule matchers that are only probed with .search()/replaced
wholesale) become non-capturing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* refactor(test,tools): name capture groups for prefer-named-capture-group

Finishes the prefer-named-capture-group burndown: test/, tools/, and
vitest.config.mts. Groups whose value is read get names ($<name>
replacement strings or .groups.<name> access); groups only used via
.test()/.search() or that feed a .match(/…/g) call (whose return value
is the array of whole matches, not captured groups) become
non-capturing.

This is the last remaining slice of pre-existing violations, so the
rule (already enabled at error repo-wide) now passes with zero
findings across the whole codebase.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RxHFNsSworLcv23xXk9Hk

* fix prettier failure

* refactor(lint): use a named capture group in `v8-ignore-no-count`

New rule from main trips the newly enabled `prefer-named-capture-group` oxlint rule.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-03 09:54:40 +00:00
Abizer 7a6e7b2880 fix(azure): filter pull request queries by Renovate author (#45359)
* implement plan

* add tests

* fix initialization order

* cast contexts to WebApi for type safety in authHandler checks

* fix(azure): scope PR filtering to effective credentials (#1)

* fix(azure): scope PR filtering to effective credentials

* fix(azure): address authentication review feedback

* fix: reorder import statements

* Address review comments

* fetch renovate user id in initPlatform

---------

Co-authored-by: Sergei Zharinov <zharinov@users.noreply.github.com>
44.61.1
2026-09-03 08:26:18 +00:00
Jamie Tanna 210bf42b89 docs(tool-calling): centralise AWS configuration (#45586)
As we've got some duplication, we should centralise this into a specific
page under "tool calling".
2026-09-03 08:25:17 +00:00
Michael Kriese c97111e37e fix(util/exec): disable execa rejection (#45651) 2026-09-03 08:20:45 +00:00
Sebastian Poxhofer 6e03e8326f refactor(linters): add rule to enforce inline single use fixtures (#45230)
* feat(lint): add renovate/prefer-is-helpers and renovate/prefer-is-object rules

Flag ad-hoc type checks that have @sindresorhus/is equivalents:
- .filter(Boolean) -> .filter(isTruthy)
- typeof x === 'string' -> isString(x)
- x === null || x === undefined -> isNullOrUndefined(x) (and negation)

The typeof x === 'object' shape lives in a separate suggestion-only rule
(renovate/prefer-is-object, kept at warn) because isObject()/isPlainObject()
are not drop-in equivalents: null, arrays and functions behave differently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: fix renovate/prefer-is-helpers violations

Replace ad-hoc type checks with @sindresorhus/is helpers across lib/:
- 13x .filter(Boolean) -> .filter(isTruthy)
- 36x typeof x ==/!== 'string' -> isString(x) / !isString(x)
- 6x x === null || x === undefined -> isNullOrUndefined(x) (and negation)

Promote renovate/prefer-is-helpers to error now that the codebase is clean.
renovate/prefer-is-object stays at warn: its 15 remaining sites guard
parsed YAML/JSON or unknown values where isObject()/isPlainObject() are
not provably equivalent (null/array/function semantics).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: enforce renovate/prefer-is-object at error level

Resolve the 15 remaining warnings and raise the rule from warn to error:

- Migrate 10 sites to isObject() where the guarded value provably cannot
  be a function (parsed YAML/JSON, typed exec command arguments, or
  test-controlled fixtures): helm-values, woodpecker, bun, pre-commit
  managers, exec utils, file package cache, and the github http spec.
  In the bun manager this also fixes a latent crash where a null
  `workspaces` value would throw on the `in` operator.
- Keep 5 sites as reasoned oxlint-disable comments where excluding
  functions is load-bearing: the byte-exact fingerprint canonicalizer
  (2), the circularity walker, the zod result guard, and the generic
  hasKey helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(lint): add renovate/inline-single-use-fixtures rule

In spec files, a module-scope const fixture that is referenced from
exactly one it()/test() block should be inlined into that test so the
test is self-contained. The rule is a warn-level nudge (naming for
clarity is a valid exception) with no autofix (moving code is risky).

Uses oxlint jsPlugins scope analysis (getDeclaredVariables) for exact,
shadowing-safe reference counting and bails out conservatively: only
top-level non-exported single-declarator consts with multiline,
non-function initializers whose every reference sits inside the callback
function of one and the same test call are flagged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: inline single-use spec fixtures into their tests

Fix 26 renovate/inline-single-use-fixtures warnings in specs where the
move is mechanical and value-preserving: codeBlock fixtures were
re-indented uniformly (codeBlock strips the common indentation, so the
produced string is unchanged) and Fixtures.get() calls resolve relative
to the spec file, so relocating them inside the test body has no effect.

The remaining 59 warnings are left for per-site judgment, as the rule is
a warn-level nudge by design.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: inline remaining relocation-safe single-use spec fixtures

Move the 24 remaining single-use module-scope fixtures whose initializer
is a codeBlock tagged template or a Fixtures accessor call into the one
it() block that uses them. Both shapes are value-preserving to relocate:
codeBlock strips the common leading indentation, so the uniformly
re-indented templates produce identical strings, and Fixtures.get()
resolves relative to the spec file, not the call site's position in it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(lint): enforce inline-single-use-fixtures as error

Narrow the rule to the initializer shapes where moving the declaration
into the test body is provably value-preserving and unambiguously an
improvement: codeBlock/stripIndent tagged templates (indentation-
normalizing, so re-indenting is safe) and Fixtures accessor calls
(resolve relative to the spec file). Plain object/array literals,
untagged template literals (whose leading-newline formatting would need
ugly re-indentation) and arbitrary call expressions remain per-site
judgment calls and are no longer flagged.

With the rule reduced to true defects and all remaining violations
inlined, bump it from warn to error in the spec override block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: inline contents of fixtures relocated into single-use tests

The previous commits moved single-use module-scope Fixtures.get() consts
into their one it() block, which only relocated the file indirection.
Replace those relocated Fixtures.get() calls with the fixture file's
actual content — codeBlock tagged templates for text fixtures — so the
tests are self-contained, and delete the fixture files that no longer
have any references. Relocated fixtures too large to inline comfortably
(terraform-provider releases, sbt private-variable file, nuget v2 pkg
list, bundled package-lock) keep their Fixtures.get() calls.

Value preservation was verified by unchanged vitest results for every
touched spec; all consumers parse the content, so codeBlock's trailing
newline normalization is behavior-neutral.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: inline remaining large single-use fixtures

Inline the four Fixtures.get() sites that were previously exempted for
size, so every single-use fixture is now inlined regardless of size:

- nuget v2_withoutProjectUrl.xml -> codeBlock (served via http mock)
- terraform-provider releaseBackendIndexGoogleBeta.json -> plain object
  literal passed to the nock reply
- npm locked-dependency bundled.package-lock.json -> codeBlock JSON
  string (consumed as raw lockFileContent)
- sbt private-variable-dependency-file.scala -> codeBlock

All consumers parse the content, so codeBlock's trailing-newline
normalization is behavior-neutral; vitest results are unchanged for
every touched spec, including the two pre-existing nuget failures.

The nuget, terraform-provider and sbt fixture files have no remaining
references and are deleted. bundled.package-lock.json is kept because
package-lock/get-locked.spec.ts still reads it via Fixtures.getJson().

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: keep large bundled package-lock fixture in a file

The bundled package-lock.json inlined into the "fails remediation if
bundled" test is ~150 KB (~4,400 lines); inlining it as a codeBlock
hurts readability more than it helps. Read it via Fixtures.get inside
the test block instead — the inline-single-use-fixtures rule permits a
Fixtures.get() call in test scope, and the fixture file is still present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
44.61.0
2026-09-03 07:42:45 +00:00
Eyal Zekaria 0e90c69f91 perf(package-rules): avoid re-cloning invariant packageRules array on every rule match (#44781)
perf(package-rules): avoid re-cloning packageRules array on every rule merge

applyPackageRules() merges each matching rule via mergeChildConfig(),
which deep-clones the entire accumulated config — including the
invariant packageRules array itself. On repos with many dependency
instances and large rule arrays (e.g. vulnerabilityAlerts force-rules
embedding advisory texts), this cloning dominates the whole run
(observed at ~66% of total CPU in a production profile).

Exclude packageRules from the working config while rules are applied
and restore it afterwards, preserving the previous merge semantics for
rules that themselves carry nested packageRules, and for null/empty/
absent inputs.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-03 07:41:06 +00:00
Pete Steyert-Woods 2fc1b5ce67 feat(datasource/orb): use REST API instead of graphql-unstable (#45205)
* refactor(datasource/orb): use REST API instead of graphql-unstable

Switch the orb datasource from the `graphql-unstable` GraphQL endpoint to
the stable CircleCI REST API (`GET /api/v3/orb/packages?filter[name]=`).

The single REST call returns the same fields the datasource needs
(`is_private`, `home_url`, and the nested `orb_versions` with
`created_at`), so behaviour is unchanged for public and private orbs on
circleci.com. Missing orbs are now detected via an empty `data` array
rather than a null `orb` field.

* convert to zod schema

* refactor(datasource/orb): use nullish helper and schema-side transform

Address review feedback:
- use the Nullish schema helper for optional attributes
- catch([]) so orb_versions is never null/undefined
- move the data transform (isPrivate, releases) into the schema; the
  homepage fallback stays in the datasource since it needs the requested
  packageName

* refactor(datasource/orb): drop snapshot and use toEqual assertion

* refactor(datasource/orb): change assertion to deepnullish

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>

---------

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
2026-09-03 07:19:11 +00:00
Jamie Tanna 4732da7d2b fix(util/host-rules): apply the admin's headers over a repository's
As part of changes we've recently made to the merging of
`hostRules[].headers`, it highlighted that a repository - or a preset
it extends - could lead to a header an admin has configured for one host
to be sent to another.

This happened due to the way we additively merged i.e.
`Object.assign({}, ...matchedHeaders)`.

This doesn't require the repository to know a credential is being
set (for a specific host), or to act maliciously - any header of their
own for that host is enough to bring the administrator's masked one
back, with nothing logged or failing to show it happened.

To fix this, we can:

- apply admin headers last, as they are "trusted"
- stop repositories from being able to unset an admin-set header
- retain the existing logic for the "most specific rule" being used
- make sure that `trusted` isn't a field that could be injected by a
  repository, and make sure we explicitly only set it where we know
  we're using self-hosted administrator config
- make `filterAllowedHeaders` drop `headers` if every header name was
  denied, so `{}` isn't returned and used to suppress headers when
  merged

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
44.60.1
2026-09-03 08:01:41 +01:00
Jamie Tanna c98f4f71c8 fix(util/host-rules): enforce allowedHeaders within add()
We previously enforced `allowedHeaders` by making sure that each
`hostRules.add()` call had `filterAllowedHeaders`.

This isn't super future proofed, and although we could add a linting
rule, we should instead enforce this by making sure that
`hostRules.add()` applies the filtering.

This also catches cases like host rules from `.npmrc` which wasn't
currently being filtered - albeit there was no means to bypass
`allowedHeaders`.

Moving `filterAllowedHeaders` into `lib/util` removes a dependency from
the global bootstrap and `config-validator` importing from
`lib/workers/repository/init/`.

While doing so, we can also make sure that:

- we log only one WARN for global `hostRules` being invalid, rather than
  once per `repositories[]`
- `renovate-config-validator` validates a global config file's
  `hostRules` against that file's own `allowedHeaders`, like a real run
  would after parsing it

Co-authored-by: Claude Fable 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 08:01:41 +01:00
Jamie Tanna 3d56c38cf6 fix(util/host-rules): merge headers across matching rules
Previously, if there was a `hostRule[].headers` value for a given host
set in both global self-hosted configuration and repo config, the repo
config would overwrite /all/ headers set by the admin.

To resolve this, we can now correctly merge the keys, with the repo
config taking priority.

This still only takes into account the `allowedHeaders`, so a repository
cannot bypass admin settings.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 08:01:41 +01:00
Jamie Tanna 432bb00cd2 fix(workers/global): enforce allowedHeaders for the admin's own hostRules
For some time, admin configuration for `hostRules[].headers` was
enforced through `allowedHeaders`, but no validation feedback was given
to administrators, as it was silently ignored when `applyHostRule` runs.

To provide visibility to administrators who were setting headers that
were silently being ignored, we can instead provide validation at the
time we set our global host rules.

In a future change, we'll align the behaviour of `allowedHeaders` and
`allowedEnv` to make it so admin-controlled `hostRules` aren't bound by
the `allowedHeaders` flag.

We can also make it clear in the documentation that this is the
behaviour.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 08:01:41 +01:00