Commit Graph

161 Commits

Author SHA1 Message Date
Jamie Tanna baa71ca980 feat(manager/github-actions): support supabase/setup-cli version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:18 +01:00
Jamie Tanna 5673b25e10 feat(manager/github-actions): support pulumi/actions pulumi-version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:17 +01:00
Jamie Tanna efa75c7648 feat(manager/github-actions): support stCarolas/setup-maven maven-version
As Maven tags releases as maven-X.Y.Z rather than plain SemVer, we need to set a custom extractVersion.

As ranges can be used, we can treat it as Node-package-registry-style versioning.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:17 +01:00
Jamie Tanna 9cdc00d432 feat(manager/github-actions): support bufbuild/buf-setup-action version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:17 +01:00
Jamie Tanna 753efadea1 feat(manager/github-actions): support raven-actions/actionlint version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:16 +01:00
Jamie Tanna 13d1256a6d feat(manager/github-actions): support actions-rust-lang/setup-rust-toolchain toolchain
As the Action only uses the last `toolchain` as the active one, we can
only update that value.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:16 +01:00
Jamie Tanna 3574cf0c5c feat(manager/github-actions): support j178/prek-action prek-version
As this may be a SemVer range, we need to treat it as an npm version.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:16 +01:00
Jamie Tanna 53481c1c87 feat(manager/github-actions): support reviewdog/action-setup reviewdog_version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:16 +01:00
Jamie Tanna cf86fd0e85 feat(manager/github-actions): support astral-sh/ruff-action version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:15 +01:00
Jamie Tanna 225f87e669 feat(manager/github-actions): support biomejs/setup-biome version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:15 +01:00
Jamie Tanna 5eb960b3a8 feat(manager/github-actions): support abatilo/actions-poetry poetry-version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:15 +01:00
Jamie Tanna 6b48fc31df feat(manager/github-actions): support opentofu/setup-opentofu tofu_version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:14 +01:00
Jamie Tanna 31d7babcdc feat(manager/github-actions): support goreleaser/goreleaser-action version
As it allows for a range, we need to parse it as if it's npm versioning.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:14 +01:00
Jamie Tanna 3ce6d3a62a feat(manager/github-actions): support erlef/setup-beam's version inputs
setup-beam is a bit more complex, as it has multiple inputs, and
`erlang/otp` releases as `OTP-x.y.z`, so we need to specify a custom
`extractVersion`.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:14 +01:00
Jamie Tanna 4e450418be feat(manager/github-actions): support helm/kind-action's version inputs
kind-action is a bit more complex, as it has multiple inputs.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:30:13 +01:00
Jamie Tanna 7b8ac17c36 feat(manager/github-actions): support GitTools/actions/gitversion/setup's versionSpec
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:54 +01:00
Jamie Tanna e227af992e feat(manager/github-actions): support subosito/flutter-action's flutter-version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:54 +01:00
Jamie Tanna 6687887bb8 feat(manager/github-actions): support aquaproj/aqua-installer's aqua_version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:54 +01:00
Jamie Tanna e8a17adefe feat(manager/github-actions): support cycjimmy/semantic-release-action semantic_version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:54 +01:00
Jamie Tanna 347c642f1d feat(manager/github-actions): support cloudflare/wrangler-action wranglerVersion
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:53 +01:00
Jamie Tanna 9b7dfb9d8b feat(manager/github-actions): support peaceiris/actions-hugo's hugo-version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:53 +01:00
Jamie Tanna f417e2004f feat(manager/github-actions): support jfrog/setup-jfrog-cli's version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:53 +01:00
Jamie Tanna 84be57eadd feat(manager/github-actions): support helm/chart-releaser-action's version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:53 +01:00
Jamie Tanna 9266b6d05e feat(manager/github-actions): support azure/setup-kubectl's version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:52 +01:00
Jamie Tanna b4f9d9d607 feat(manager/github-actions): support snok/install-poetry's version
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 09:27:52 +01:00
Jamie Tanna d27e967632 feat(manager/github-actions): support terraform-linters/setup-tflint's tflint_version (#46034)
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 07:53:32 +00:00
Jamie Tanna 6c7e9faa7e feat(manager/github-actions): support extractions/setup-just's just-version (#46033)
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 07:53:31 +00:00
Jamie Tanna 3de36a8e43 feat(manager/github-actions): support gradle/actions/setup-gradle's gradle-version (#46032)
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 07:53:30 +00:00
Jamie Tanna 608b47ea2a feat(manager/github-actions): support hashicorp/setup-terraform's terraform_version (#46031)
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-15 07:53:29 +00:00
Michael Kriese 55a7341be2 test(manager): close long-tail branch coverage gaps (#45954)
* test(manager): close azure-pipelines, bundler and cocoapods gaps

Adds a pipeline whose step task is not versioned, so nothing is
extracted, and a gem lock line carrying no version, which is skipped.

Marks four guards that cannot be false: `extractContainer()` always
returns a dep, `getLockFilePath()` always returns a path, and the
cocoapods dep name, spec name and git account all derive from values
their enclosing check already proved present.

Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>

* test(manager): close cargo, composer and cpanfile gaps

Adds a composer repository map that disables something other than
packagist, which is dropped rather than recorded.

Marks five guards: the cargo warning only fires for a crate dep and its
retry only runs when a dep was already current, a gitlab rule without a
token never passes the auth check, and both cpanfile handlers run only
once their match produced a value.

Two implicit elses stay counted, in the cargo version resolver and the
composer repository mapper, since a coverage-ignore hint does not attach
to an `else if`.

Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>

* test(manager): close deps-edn, docker-compose and dockerfile gaps

Adds three extractions: a deps.edn alias whose value is not a map, a
compose extension carrying no image, and a dockerfile escape directive
naming a character other than a backtick, which leaves the default in
place.

Marks the deps-edn repository name check, since object keys are always
strings, and notes the repository spec chain, where a coverage-ignore
hint does not attach to an `else if`.

Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>

* test(manager/flux): close the flux coverage gaps

Adds two GitRepository resources whose url is ssh rather than http, one
pinned to a tag and one to a commit. Neither yields a source url, since
only http urls can be turned into one.

Marks the Kustomization image guard: the schema rejects an image without
a name, so `extractImage()` cannot return null there.

Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>

* test(manager): mark github-actions, gitlabci and glasskube guards

None of these six needs a test. A parsed action ref is either a docker
or a repository ref, `getDep()` always returns a dep for a job container
and a service, and the remaining three need a listed file that cannot be
read, a listed file that yields no deps, or a manifest whose
repositories match no name.

The glasskube resource kind chain stays counted, since a coverage-ignore
hint does not attach to an `else if`.

Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>

* test(manager): mark gomod and gradle-wrapper guards

Four guards that need setups no test provides: a removed dep that is not
added back, a go.mod the replace massaging leaves unchanged, and a
daemon-jvm file carrying no toolchain version. A parsed go directive
always yields a version.

The additional-dependency count chain stays counted, since a
coverage-ignore hint does not attach to an `else if`.

Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>

---------

Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io>
2026-09-15 07:10:10 +00:00
Jamie Tanna 3e099dd645 feat(manager/github-actions): support aws-actions/amazon-ecs-render-task-definition's image (#45940)
* feat(manager/github-actions): support aws-actions/amazon-ecs-render-task-definition's `image`

Per #43038, and following the existing pattern for Docker image
extraction.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

* fixup! feat(manager/github-actions): support aws-actions/amazon-ecs-render-task-definition's `image`

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

---------

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-14 14:42:54 +00:00
Sebastian Poxhofer 4b4d14ec00 feat(manager): pass extracted constraints to updateArtifacts (#45826)
* feat(manager): pass extracted constraints to updateArtifacts

`extractedConstraints` were collected during extraction but only ever read
by `fetch.ts` for the lookup. At artifact time every manager had to derive
the same tool constraints a second time, and when the updated package file
no longer carried the constraint there was nothing to fall back to.

`generateBranchConfig()` now merges the `extractedConstraints` of all
upgrades of a branch onto the branch config, which reaches `updateArtifacts()`
through `patchConfigForArtifactsUpdate()`. `UpdateArtifactsConfig` declares
the field and documents what it contains.

The new `resolveToolConstraint()` helper implements the ladder once:
user `constraints` > an optional artifact-time derivation > the extracted
value. The derivation is ranked above the extracted value on purpose: it
reads the package files as the branch changed them, so poetry (python is an
updatable dependency there), composer, pipenv (`pipenv` can be a dev
package) and pep621 (`requires-python` is an updatable dependency) would
otherwise regress to a stale constraint. pipenv, pep621 uv/pdm, poetry and
composer are migrated to the helper and keep their derivation.

Behaviour change: these managers now use the extract-time constraint as a
last resort instead of running unconstrained, for example on lock file
maintenance where pipenv deletes `Pipfile.lock` before deriving.

`execute-post-upgrade-commands.ts` is unaffected: it reads
`upgrade.constraints` per upgrade, and the extracted values are kept in a
separate field rather than folded into `constraints`, so post-upgrade task
tool constraints still come from user config only.

Not migrated, because their constraints are never extracted, so the
fallback would be dead code: bundler (`ruby`/`bundler`), pixi (`pixi`),
pep621 uv (`required-version`) and npm's node ladder, whose last step
already reads `package.json` engines.

* refactor(manager): resolve tool constraints through resolveToolConstraint()

Every manager now obtains the constraint of a tool it runs through
`resolveToolConstraint()` instead of reading `config.constraints` itself, so
the precedence "user config, then a value derived from the updated files, then
the constraints collected during extraction" applies everywhere. The helper
treats an empty string as not set at every step and accepts the
`PostUpdateConfig` shape, whose `constraints` may be `null`.

Behaviour changes that go beyond the new fallback to extracted constraints:

- `mix` applies its hardcoded erlang default only after the extracted
  constraint, so an erlang version collected at extraction can win over it.
- `kustomize` decides `HELM_EXPERIMENTAL_OCI` from the fully resolved helm
  constraint; `generateHelmEnvs()` takes that value instead of the config.
- `npm` (yarn): an upgrade of yarn without a new value now consults the user
  constraint before deriving one from package.json or the lock file.
- The "Using <tool> constraint from config" debug lines in bundler, composer,
  copier and pip-compile are gone, as the helper is the only reader of the
  config now.

Helpers that read the config synchronously became async: bundler
`getBundlerConstraint()`, copier `getPythonVersionConstraint()` and
`getCopierVersionConstraint()`, pip-compile `get*VersionConstraint()` and
`getToolVersionConstraint()`, gomod `deriveGoToolchainConstraints()` and
`getUpdateImportPathCmds()`, mise `getMiseLockToolConstraints()`. composer
`getPhpConstraint()` is removed.

Each converted manager has a test showing the extracted constraint reaching
the executed tool, and, where a derive callback exists, that the derived value
still wins over it.

* refactor(linters): add prefer-resolve-tool-constraint rule

Reports member reads and destructuring of `constraints` and
`extractedConstraints` from a manager config in `lib/modules/manager/**`, so
that tool constraints are resolved through `resolveToolConstraint()` in
`lib/modules/manager/util.ts` only. Writes and the same properties on package
files, which extraction has to populate, are not reported. The helper itself
and spec files are exempt in `.oxlintrc.json`.

* refactor(manager): inline thin resolveToolConstraint wrappers

Drop copier/utils.ts and the pip-compile getPipToolsVersionConstraint /
getUvVersionConstraint helpers, which only forwarded to
resolveToolConstraint(). Callers now call it directly.

* docs(development): note lock file maintenance in tool constraints section

* refactor(manager): address review on tool constraint resolution

composer only runs extractConstraints() when a user constraint is missing,
via Lazy. UpdateArtifactsConfig no longer re-declares constraints and
extractedConstraints, which ToolConstraintsConfig already provides.
2026-09-14 11:09:07 +00:00
Jamie Tanna 58cd82c060 feat(manager/github-actions): support actions/setup-java's java-version (#45878)
Where we are able to support Java distributions that follow a
straightforward release cadence, we opt these distributions in, and skip
others as `unsupported`.

As the Temurin/Adopt distributions can be reliably tracked by the
`java-version` Datasource, backed by Adoptium, we can support them.

We can also use the `java-package` key to look up whether we want a JRE
or JDK.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-14 08:07:26 +00:00
Jamie Tanna e6c6f2914a feat(manager/github-actions): support actions/setup-dotnet's dotnet-version (#45877)
In the case a multi-line `dotnet-version` is specified to install
multiple SDKs at once, we skip it as `invalid-version`, as we don't
currently have a way to update multiple values in the field.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-14 08:07:25 +00:00
Jamie Tanna 343fed8955 docs(manager/github-actions): generate one combined first-party and community table (#45875)
Similar to how we already generate a list of the community actions we
support, we should also generate which first-party Actions from GitHub
are supported, and simplify some of the wording in the docs.

Instead of duplicating this, we can instead move them into a single
section in the documentation.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-14 08:07:25 +00:00
Jamie Tanna 03906a7cbf refactor(manager/github-actions): don't duplicate parsing logic for first-party Actions (#45887)
* refactor(manager/github-actions): don't duplicate parsing logic for first-party Actions

Instead of having a separate set of Action parsing and their
configuration between first-party GitHub-owned Actions and those of
third-party Actions, we can merge them into a single collection.

This also leads to `https://<host>/` handling noted in #35777 now being
handled out-of-the-box, as it was already supported on third-party
actions.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

* fixup! refactor(manager/github-actions): don't duplicate parsing logic for first-party Actions

---------

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-14 08:07:24 +00:00
renovate[bot] b6ffadc70c docs: update references to astral-sh/setup-uv to v10.1.0 (main) (#45921)
docs: update references to astral-sh/setup-uv to v10.1.0

| datasource  | package            | from    | to      |
| ----------- | ------------------ | ------- | ------- |
| github-tags | astral-sh/setup-uv | v10.0.1 | v10.1.0 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-14 01:25:43 +00:00
Jamie Tanna 6580ef4f97 feat(manager/github-actions): support renovatebot/github-action renovate-image (#45873)
While looking at [0], I noticed that we didn't have support for our own
GitHub Action's configuration.

We can make sure that we support upgrading the `renovate-image` for
folks specifying an image (with optional digest) for the Renovate CLI
version to upgrade.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-11 10:47:21 +00:00
Jamie Tanna e4307d526a feat(manager/github-actions): support renovatebot/github-action's renovate-version (#45872)
While looking at [0], I noticed that we didn't have support for our own
GitHub Action's configuration.

We can make sure that we support upgrading the `renovate-version` for
the CLI version in use, whether it's quoted or unquoted (which YAML
parses as a number).

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

[0]: https://github.com/renovatebot/github-action/issues/1035
2026-09-11 10:47:21 +00:00
Adam Setch 6d67f70cd2 feat(manager/github-actions): extract expo GitHub actions' eas-version (#45846)
feat: github actions for expo cli version

Signed-off-by: Adam Setch <adam.setch@outlook.com>
2026-09-10 12:29:02 +00:00
renovate[bot] 9d74625d93 build(deps): update dependency prettier to v3.9.6 (main) (#45815)
* build(deps): update dependency prettier to v3.9.6

| datasource | package  | from  | to    |
| ---------- | -------- | ----- | ----- |
| npm        | prettier | 3.8.1 | 3.9.6 |

* chore: prettier fixes

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Kriese <michael.kriese@mend.io>
2026-09-09 13:50:03 +00:00
renovate[bot] 42cf188fdc chore(deps): update dependency astral-sh/setup-uv to v10 (main) (#45808)
chore(deps): update dependency astral-sh/setup-uv to v10

| datasource  | package            | from   | to      |
| ----------- | ------------------ | ------ | ------- |
| github-tags | astral-sh/setup-uv | v9.0.0 | v10.0.1 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-09 12:46:52 +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 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
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
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>
2026-09-03 07:42:45 +00:00
Jamie Tanna b62fe59594 fix: remove references to "bot" (#39305)
We dropped the "bot" from our terminology long ago, but it looks like
we've got some outdated docs + code that reference it.

We should remove this to keep things consistent.

A `fix`, as we're changing the commit author's name, and log lines.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-02 08:56:20 +00:00
Sebastian Poxhofer e0cec3dc95 refactor(lint): add types-location rule and enable it for lib/modules (#45497)
feat(lint): add `types-location` rule and enable it for `lib/modules`

Reviewers consistently ask for exported types to be moved into a
colocated `types.ts`. Add a `renovate/types-location` oxlint rule that
reports `export interface` / `export type` declarations outside such a
file, and turn it on across `lib/modules`.

Re-exports (`export type { X }`, `export type *`), file-local types, and
values (enums, classes, functions) are left alone. `schema.ts` files and
`schema/` directories are excluded via config, matching how
`zod-schema-location` is configured — inferred types belong next to the
schema they are derived from.

Relocating the 87 existing violations means:

- new `types.ts` files for the modules that had none
- `terragrunt/common.ts` folded into its `types.ts`, as it held nothing
  else
- `RangeBound` in `versioning/gradle/compare.ts` un-exported, since only
  a file-local interface referenced it
- `bazel-module/parser/fragments.ts` split from its inferred types, which
  now live in `parser/types.ts` and infer through a namespace import so
  each schema keeps its merged name
2026-08-27 19:52:09 +00:00
Sebastian Poxhofer 69e05233e8 feat(manager/github-actions): add workflow depType for reusable workflow calls (#45443)
* feat(manager/github-actions): add `workflow` depType for reusable workflow calls

A job-level `uses:` pointing at `owner/repo/.github/workflows/<file>.yml@<ref>`
calls a reusable workflow rather than running an action, but both got the
`action` depType, so `matchDepTypes` could not tell them apart.

Give a reference whose sub-path is exactly `.github/workflows/<file>.yml|.yaml`
the new `workflow` depType. Every other sub-path, such as
`github/codeql-action/init`, stays an action.

The existing depType-keyed sites now accept both values, so nothing else
changes behaviour: the `actions.lock` file records reusable workflow calls too,
and `helpers:pinGitHubActionDigests` pinned them before this split.

* Apply suggestions from code review

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
2026-08-25 11:52:05 +00:00
Sebastian Poxhofer 41da033756 refactor: remove escapeRegExp and replace with RegExp.escape (#45322) 2026-08-18 06:24:47 +00:00