3830 Commits

Author SHA1 Message Date
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
Joseph Petersen 93afa9fc42 fix(github): respect automergeStrategy with platform automerge (#44563)
* fix(github): respect automerge strategy with platform automerge

* docs(automerge): clarify GitHub platform strategy

* docs(automerge): generalize platform strategy behavior
2026-08-26 15:17:13 +00:00
Jamie Tanna 021612414c fix(lint): use parseInt over Number (#45472)
* fix(lint): use `parseInt` over `Number`

As a code review comment that comes up every so often, we can add a
linting rule to enforce this check.

This also fixes any existing usages.

As this could be breaking, we can release it as a `fix`.

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

* fixup! fix(lint): use `parseInt` over `Number`

* fixup! fix(lint): use `parseInt` over `Number`

---------

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-26 13:02:26 +00:00
Jamie Tanna a9c8f7431f fix(lint): extend prefer-is-helpers to catch more cases (#45474)
This now covers everything that isn't `isObject` or `typeof x === 'number'`.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-26 10:48:40 +00:00
Pradeep Ashwathanarayan cee4515c2e fix(manager/gomod): handle bare ../ replace paths in gomodTidyAll (#45392)
fix(gomod): handle bare ../ replace paths in gomodTidyAll

When a go.mod file uses a replace directive pointing to the parent
directory with no sub-path (e.g. `replace example.com/root => ../`),
gomodTidyAll would silently skip running `go mod tidy` on that module
and any of its dependents.

The root cause was in the `localReplace` regex where the localPath
capture group used `\S+` (one or more non-whitespace), so `../` —
with nothing after the slash — was never matched. Only paths like
`../subdir` were picked up.

Changing `\S+` to `\S*` allows zero-or-more trailing characters,
so bare `../` and `./` now parse correctly and the dependency graph
is built properly.
2026-08-26 09:40:47 +00:00
Jamie Tanna 0cc9356915 test(versioning/conan): ignore unreachable coverage branches (#45458)
`fixParsedRange()`'s `ordValues` array is only populated for a bare
(operator-less) segment when it's adjacent to `||`.

Any other bare segment throws earlier at `ordValues[i].includes('||')`
before either of these branches can be reached, so a falsy, non-`||`
`operator` is unreachable in both `fixParsedRange()` and `bumpRange()`.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-25 20:07:10 +00:00
Jamie Tanna aa5d1e59a0 test(manager/bundler): add missing branch coverage in extract() (#45457)
The `else if (gitRefsMatch.repoName)` branch was unreachable, so we can
simplify this check.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-25 20:07:09 +00:00
Jamie Tanna ad63dddef7 fix(platform/bitbucket): remove support for Issues (#45445)
On 2026-02-20, Atlassian announced that they would be removing the
native issue tracker in Bitbucket Cloud[0].

As of 2026-08-24[1], this change is now complete.

When Renovate attempts to update an existing Dependency Dashboard Issue,
we see:

    DEBUG: GET https://api.bitbucket.org/2.0/repositories/some/repo/issues?q=... = (code=ERR_NON_2XX_3XX_RESPONSE, statusCode=410 retryCount=0, duration=87)
    WARN: Error finding issues

And when trying to create one, we see:

    DEBUG: findIssue(Dependency Dashboard)
    DEBUG: Issues are disabled - cannot findIssue

Because it's not possible - until #20568 - to use another source for
Issues on Bitbucket Cloud, we need to remove support for the Dependency
Dashboard.

When we do try and interact with them, we can DEBUG log as to why it's a
no-op (similar to `platform=bitbucket-server`), and reference the deprecation.

As we now don't touch Issues, we can remove the additional permissions
that were previously required.

As there are no longer Issues, we can remove `has_issues` from our
types.

As well as the Dependency Dashboard, this also means that i.e. Config
Warning Issues are no longer available.

[0]: https://developer.atlassian.com/cloud/bitbucket/changelog/#CHANGE-3071
[0]: https://developer.atlassian.com/cloud/bitbucket/changelog/#CHANGE-3401

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-08-25 15:40:06 +00:00
Alan Amoyel 448597f970 fix(manager/sveltos): concatenate repositoryURL with chartName for OCI (#45439)
fix(manager/sveltos): concatenate repositoryURL with chartName for OCI registries
2026-08-25 15:33:22 +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
Diogo Santos c3b016672c fix(manager/copier): report template conflicts as artifact errors (#45433)
* fix(copier): report template conflicts as artifact errors

* test(copier): cover conflict artifact errors

* chore(copier): restore test file newline
2026-08-25 11:30:17 +00:00
RahulGautamSingh 694410d4bb fix(platform/azure): detect hosted deployment when deploymentType is a string (#45440) 2026-08-25 10:35:24 +00:00
Jamie Tanna f50bee3afa refactor(manager/npm): remove redundant CI=true
As it's now the default.
2026-08-24 17:27:42 +01:00
Jamie Tanna 2779587e31 test(manager/npm): fix getChildProcessEnv mock in yarn tests
As part of follow-up changes, it was noticed that our mocking of
`getChildProcessEnv` means we're not seeing the actual environment
variables in our tests.

To make sure that future tests can check that `CI` is added as expected
by default, we can remove the mocking.

Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-24 17:25:48 +01:00
Jamie Tanna 5b1749983c feat: always set CI=true for subprocesses
As noted in #43761, we had recently set `CI=true` for the Renovate and
Containerbase orgs on Mend-hosted apps due to a pnpm v11 requirement:

    ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY  Aborted removal of
      modules directory due to no TTY

    If you are running pnpm in CI, set the CI environment variable to
      "true", or set "confirmModulesPurge" to "false".

Similarly in #43606, it was noted that we should do this for `mise lock`
to mark the workspace as "trusted".

Although we went with a different situation, there will be cases where
this is useful for tools being executed, for instance when we invoke `yarn`.

We also make sure to keep our documentation up-to-date as we add to the
specific overrides.

With help from Claude Sonnet and Opus to:

- perform some of the mechanical updates as part of this change
- ensure that the Docker sidecar always has `hardcodedProcessEnv` passed
  into it
- catch a needed change to `exposeAllEnv` handling

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-24 17:21:24 +01:00
goda6565 9cc1ab0df6 fix(http/github): support cursor pagination (#45241)
* fix(http/github): support cursor pagination

* fix(http/github): harden cursor pagination

* fix(http/github): log pagination mode
2026-08-24 14:24:25 +00:00
renovate[bot] 9ce288efba docs: update references to python to 4fad234 (main) (#45407)
docs: update references to python to 4fad234

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-24 00:29:58 +00:00
Sebastian Poxhofer a473e73b3e fix(linters): forbid inert counts in v8 coverage-ignore comments (#45287)
Adds a custom oxlint rule renovate/v8-ignore-no-count that flags the
count form '/* v8 ignore next <N> */'. The count is not honored by
vitest's ast-v8-to-istanbul hint parser, which captures only the
keyword (if/else/next/file); 'next' always exempts exactly the next
AST node. Trailing counts therefore suggest a line range that is never
applied and mislead readers.

The rule is autofixable (drops the count, preserving actual behavior)
and has been applied to all existing occurrences.
2026-08-22 11:25:31 +00:00
Jamie Tanna 1fc0a3e5bd docs(manager/gradle): add link to Dependency Verification docs (#45384)
Plus make it very clear that this needs to be `allowUnsafeExecutions`'d.
2026-08-21 10:51:35 +00:00
Christoph Mathys adce441ee5 feat(manager/devcontainer): add folder pattern to list of managerFilePatterns (#45377)
fix(devcontainer): add folder pattern to list of managerFilePatterns

This extension is according to the spec found here:
https://containers.dev/implementors/spec/#devcontainerjson
2026-08-21 08:49:52 +00:00
Jamie Tanna a61de24310 fix(datasource/npm): don't break on non-string homepage (#45358)
As reported in #45357, changes in
116c3d610c caused a regression for cases
where an npm package had `homepage: [...]`.

We should restore the `catch(undefined)` and add a test to make sure
this isn't broken in the future.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-19 20:41:56 +00:00
Simon Marquis 8ea65f77d2 fix(kotlin-script): support vararg arguments in @file:DependsOn and @file:Repository (#44762)
* fix(kotlin-script): support vararg arguments in @file:DependsOn and @file:Repository

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(kotlin-script): remove unreachable branch to restore code coverage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(kotlin-script): restore functional style after vararg fix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(kotlin-script): use non-null assertion to avoid uncovered branches

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Implement requested changes

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-19 14:09:53 +00:00
Simon Marquis c77ac1f29c fix(gradle): collision with well-known Android APIs (#45350)
Discussion: https://github.com/renovatebot/renovate/discussions/45349
2026-08-19 13:46:51 +00:00
Luigi Cerone dd72cf0cd2 feat(manager/poetry): pass POETRY_SOLVER_MIN_RELEASE_AGE when minimumReleaseAge is configured (#43429)
* feat(manager/poetry): pass POETRY_SOLVER_MIN_RELEASE_AGE when minimumReleaseAge is configured

* test(manager/poetry): add coverage for invalid minimumReleaseAge duration

* refactor(poetry): remove pyproject.toml solver logic

* style: apply prettier formatting

* fix(poetry): address review comments

* fix: review changes

* fix: review changes

* Update lib/modules/manager/poetry/artifacts.ts

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

* fix: linting

---------

Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
2026-08-19 09:39:52 +00:00
RahulGautamSingh 37444eff27 fix(datasource): keep merged releases when a registry is rate-limited (#45299)
* fix(datasource): keep merged releases when a registry is rate-limited

* apply suggestions
2026-08-18 09:21:54 +00:00
Felipe Santos 2606ae2bd3 feat(pypi): add support for JSON-based Simple API (PEP 691) (#44222)
* feat(pypi): add support for JSON-based Simple API (PEP 691)

* Fix some stuff

* Clean some things up

* Fix coverage

* Simplify JSON parse

* Remove useless tests

* Align terminology

* Incorporate some changes from PR #44182

Co-authored-by: Andreas Hippler <andreas.hippler@goto.com>

* Use isNonEmptyString to filter requires_python

* Address review feedback

* Warn once actually

* fixup! review comments

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

* fixup! fixup! review comments

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>

* fixup! review comments

As the list of status codes we retry on was based on an unverified
claim that Artifactory, Nexus and devpi answer a rejected `Accept`
header with `400`/`403`/`415`, we should only retry on `406`, which is
what RFC 9110 specifies for a request whose `Accept` cannot be
satisfied.

Our `Accept` header ends with `text/html; q=0.01`, so any conforming
registry can satisfy it, `415` refers to the request body's
`Content-Type` rather than `Accept`, and retrying on `403` doubles the
requests for a registry we're not authenticated against.

The unwrapping of `ExternalHostError` is unaffected, as that's needed
for the `abortOnError` case regardless of which status codes we retry.

Co-Authored-By: Claude Opus 5 <claude-code@jamietanna.co.uk>

* fixup! review comments

As the note about `upload-time` sat in the paragraph about the Simple
API, it read as if `minimumReleaseAge` needs a registry which supports
the JSON-based Simple API (PEP 691).

That's only true of the Simple API. The JSON API has always exposed
`upload_time`, and as the default registry of `https://pypi.org/pypi/`
doesn't end in `/simple/`, that's the lookup most users get, so
`minimumReleaseAge` already works for them.

We can split the two apart, so that the guarantee for each API is
stated separately.

Co-Authored-By: Claude Opus 5 <claude-code@jamietanna.co.uk>

* reword

* fixup! review comments

As the JSON-based Simple API's release timestamps were only covered by
hand-written responses, we didn't have the equivalent of the real world
coverage added for the JSON API in
e942788539.

We can add a `numpy` fixture from PyPI's JSON-based Simple API, trimmed
to 1.5.0 and 1.5.1, so we assert against a response a registry has
actually served. 1.5.1 is the interesting case, as it was released in
2010 but gained a wheel in 2014 which PyPI lists first.

This also covers the `upload-time` format the Simple API uses, of
`2010-11-18T14:16:58.801332Z`, rather than the JSON API's
`2010-11-18T14:16:58`, so that we know `asTimestamp` normalises both.

Unlike the JSON API, there's no previous behaviour to characterise
first, as before these changes the Simple API exposed no timestamps at
all.

Co-Authored-By: Claude Opus 5 <claude-code@jamietanna.co.uk>

* fixup! fixup! review comments

* fixups

* fixups

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>

* fixup! comments

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

---------

Co-authored-by: Andreas Hippler <andreas.hippler@goto.com>
Co-authored-by: Jamie Tanna <jamie.tanna@mend.io>
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Claude Opus 5 <claude-code@jamietanna.co.uk>
2026-08-18 09:03:12 +00:00
Gregor Zeitlinger a53aaf4141 refactor(java-version): extract adoptium HTTP logic from datasource class (#42604)
* refactor(java-version): extract adoptium HTTP logic from datasource class

Move getPageReleases and the Adoptium fetch logic out of the
JavaVersionDatasource class into a standalone adoptium.ts module.
This makes the code easier to test in isolation and decouples
Adoptium-specific logic from the datasource class.

No behavior change — customRegistrySupport remains false, and the
hardcoded adoptiumRegistryUrl replaces the previously injected
defaultRegistryUrl (which was always the same value).

* fix(java-version): remove unused adoptiumRegistryUrl import from test

* test(java-version): use partial helper in spec

* refactor(java-version): extract adoptium HTTP logic from datasource class

* fix(java-version): pass Adoptium schema to HTTP client

* test(java-version): move Adoptium test to module spec

* chore(ci): retrigger failed checks
2026-08-18 08:13:54 +00:00
Sebastian Poxhofer 41da033756 refactor: remove escapeRegExp and replace with RegExp.escape (#45322) 2026-08-18 06:24:47 +00:00
Jamie Tanna d8705054b0 fix(datasource/go): prefer later releaseTimestamp from GitHub Releases (#45315)
As noted in #45314, there are cases where we may see as similar case to
the GitHub Releases datasource in #43451, where a Go module's published
`Time` matches the time that the commit the Git tag points to was
committed, rather than the time that the release was created.

If we do have a GitHub repository, we can look up the GitHub Releases
(or we'll get the Git Tags, if no Releases are present) and use the date
if it's /newer/

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-08-17 19:01:23 +00:00
Aleksandr Mezin 5e8bf3c010 fix(github): recognize another "needs approving review" message (#45052)
* fix(github): recognize another "needs approving review" message

    "response": {
      "message": "Repository rule violations found\n\nNew changes require approval from someone other than the last pusher.\n\n",
      "documentation_url": "https://docs.github.com/rest/pulls/pulls#merge-a-pull-request",
      "status": "405"
    }

* Add tests

* Include message in test name
2026-08-17 13:47:53 +00:00
Jamie Tanna e942788539 fix(datasource/pypi): use the earliest upload_time of a version (#45313)
* test(datasource/pypi): cover which `upload_time` a version reports

As part of future changes to how we calculate the `releaseTimestamp`, it
was clear we don't have as much coverage of this logic.

To make this more explicit, we can add new test coverage.

Additionally, we can introduce a new example from a package to guide
this.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>

* fix(datasource/pypi): use the earliest `upload_time` of a version

When calculating the `releaseTimestamp` for the PyPI datasource, we've
been looking at the first entry in the response, which isn't always
the first time this package existed.

In the case that a Wheel is uploaded after the package first was
released - for instance, to support a new version of Python, at an
existing pinned version of the package - this would lead to a
potentially incorrect calculation for the `releaseTimestamp`.

This can lead to Renovate seeing a package as newer than it is, which
can mean that i.e. `minimumReleaseAge` can show as pending for a package
that shouldn't be.

As part of upstream changes[0], this should be less frequent in the
ecosystem, but existing packages still exist with this behaviour.

To fix this, we can make sure that we filter a given Release's
to find the earliest `upload_time`.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>

[0]: https://blog.pypi.org/posts/2026-07-22-releases-now-reject-new-files-after-14-days/

---------

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-08-17 11:01:26 +00:00
Jamie Tanna 5e93fc225d test(datasource/pypi): add regression test for constraintsFiltering=strict (#45312)
test(datasource/pypi): add regression

As per changes suggested by Claude Opus 5 in a commit in #44222, a
regression could be triggered with our handling of
`constraintsFiltering=strict`, breaking a key piece of functionality.

To prevent this, we can add a regression test for this functionality.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-08-17 10:05:26 +00:00
Jamie Tanna 116c3d610c fix(datasource/npm): handle absent homepages (#45219)
* fix(datasource/npm): handle absent `homepage`s

As a follow-up to 89f526e0b1, this handles
it at the response from the npm registry.

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

* fixup! fix(datasource/npm): handle absent `homepage`s

* fixup! fix(datasource/npm): handle absent `homepage`s

---------

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-17 09:34:29 +00:00
Sebastian Poxhofer a1971afa78 fix(linters): add linting rule to enforce usage of our regEx utility (#44690)
* ci(linter): add renovate/require-regex-util rule

Adds a custom oxlint rule that flags raw RegExp usage in lib/
production code: any `new RegExp(...)` call and any regex literal
that is not the direct first argument of `regEx(...)`. The regEx()
helper from lib/util/regex.ts uses the RE2 engine for ReDoS-safe
matching and caches compiled patterns. lib/util/regex.ts itself is
exempt.

The rule is disabled for **/*.spec.ts, test/**, and tools/** via
config overrides, because vitest APIs such as expect.stringMatching
need bare RegExp instances (a past commit reverted regEx() there).

Severity is set to "warn" instead of "error": the repo currently has
197 pre-existing violations (above the agreed mechanical-fix
threshold of 80), and a number of them are deliberately
RE2-incompatible patterns (lookahead/lookbehind/named backreferences,
see TODO #12872/#12875 markers in e.g. lib/modules/versioning/rez/
pattern.ts and lib/modules/manager/dockerfile/extract.ts) that need
per-site judgment before they can be wrapped in regEx() or suppressed
with a justified disable comment. No violation fixes are included in
this commit.

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

* ci(linter): enforce renovate/require-regex-util at error

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

* refactor: use regEx() for regex literals and RegExp construction in lib

Burn down all renovate/require-regex-util violations (197):

- wrap RE2-compatible regex literals and RegExp constructions in regEx()
- rewrite lookaround patterns where behavior is provably preserved:
  goproxy separator split, sbt-package link extraction, leiningen
  comment stripping and keyword search, npm GitHub owner validation
  (unit-count bound replaced by an explicit length check)
- keep native RegExp with disable comments where RE2 cannot be used:
  moo / good-enough-parser lexer patterns (moo rejects RE2 instances),
  MigrationsService propertyName (matched via isRegExp, which RE2
  instances fail), rez named backreferences and lookaheads, GitHub
  markdown link negative lookbehind, emoji astral-plane matching
- drop stale TODO #12875 comments for patterns current re2 handles

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

* refactor: reduce require-regex-util disable comments

Rewrite the github massage-markdown-links URL regex to capture an
optional `api.` prefix in a named group (skipped in code) instead of
relying on a negative lookbehind, so both the base and global variants
can use regEx()/RE2 and their two disable comments are removed. Add
spec cases for api-prefixed URLs that match the URL shape.

Consolidate the four related line disables in rez/pattern.ts (bound and
range patterns emulating Python conditional patterns via named
backreferences and lookaheads, which RE2 cannot express) into a single
block disable/enable pair, matching the treatment of the lexer files.

Disable comment count drops from 13 to 8.

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

* refactor(datasource/sbt-package): use named capture group in link regex

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

* refactor(manager/cake): restore original multiLineComment regex spelling

The [^] -> [\\s\\S] rewrite was only needed for an RE2 wrap that was
later reverted; keep the diff minimal.

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

* fix(datasource/go): skip empty GOPROXY segments

The switch from a lookahead split to a capture-group split (needed because
RE2 has no lookahead support) changed how empty GOPROXY segments parse:
`a|,b` yielded `{ url: ',', fallback: '|' }` before and
`{ url: '', fallback: ',' }` after. The comma fallback only continues on
404/410, so a failing proxy ahead of an empty segment silently stopped the
lookup instead of falling through to the remaining proxies.

Empty segments carry no url to query, so drop them.

* refactor(datasource/go): use isTruthy for empty segment filter

* fix(datasource/go): filter empty segments before mapping

Filtering after the map broke the contextual typing from the
GoproxyItem[] annotation, widening fallback to string.

* refactor(platform/github): use regEx() for merge queue query stripping

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 14:30:46 +00:00
Arnaud Dezandee 6a782d3a18 feat(terraform-provider): use OpenTofu packages API for lockfile hashes (#43573)
* feat(terraform-provider): use OpenTofu packages API for lockfile hashes

* refactor(terraform-provider): reuse OpenTofu registry constant

* refactor(terraform-provider): test file structure consistency

* refactor(terraform-provider): simplify hashes with flatMap

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

* fix(terraform-provider): handle OpenTofu API URL for lockfile hashes

* perf(terraform-provider): skip /versions request for OpenTofu lockfile hashes

* refactor(terraform-provider): improve function return flow

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

* docs(terraform-provider): clarify OpenTofu packages endpoint behavior

* test(terraform-provider): add message to toThrow assertion

* fix(terraform-provider): wrap OpenTofu packages errors in ExternalHostError

* test(terraform-provider): cover OpenTofu package errors

* refactor(terraform-provider): use async/await for provider packages

* refactor(terraform-provider): use LooseRecord for schema packages prop

Co-authored-by: Sergei Zharinov <zharinov@users.noreply.github.com>

* fix(terraform-provider): import LooseRecord in schema

---------

Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: RahulGautamSingh <rahultesnik@gmail.com>
Co-authored-by: Sergei Zharinov <zharinov@users.noreply.github.com>
2026-08-14 09:51:00 +00:00
Michael Kriese c953fafcdc fix(platform/github): abort branch update when PR is in merge queue (#45252)
* fix(platform/github): skip PR update when PR is in merge queue

Updating a PR that is queued for merging can remove it from the merge
queue. Check the PR's merge queue status via GraphQL before updating
and skip the update if it is queued. The check is skipped on GHES
<3.12.0 and fails open on errors.

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

* fix(platform/github): dequeue PR from merge queue instead of skipping update

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

* docs(platform/github): note re-queue behavior after dequeue

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

* refactor(platform/github): dequeue merge queue PR in commitAndPush

Dequeue on push instead of on PR metadata update, since pushing to the
branch is what invalidates the queued merge result.

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

* refactor(platform/github): extract dequeuePr to pr.ts

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

* fix(platform/github): abort branch update when PR is in merge queue

Instead of dequeueing the PR, throw PR_ALREADY_IN_MERGE_QUEUE from
commitAndPush and handle it gracefully in processBranch.

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

* feat(platform/github): check merge queue enablement per base branch

Cache merge queue enablement per base branch like branchForceRebase and
skip the per-PR merge queue check when the base branch has no merge
queue. Errors are treated as enabled.

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

* feat(platform/github): fetch default branch merge queue status in initRepo

Include mergeQueue in repoInfoQuery so no extra query is needed for the
default branch, stripping it on GHES <3.12.0 like other unsupported
fields.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 07:05:12 +00:00
Sebastian Poxhofer 16ef1715e9 refactor(linters): add rules for @sindresorhus/is helpers (#45229)
* 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>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 14:22:03 +00:00
Sebastian Poxhofer 874f3e3953 feat(presets): support relative paths inside a preset repo (#45211)
* feat(presets): support relative `extends` references inside presets

Presets which are fetched from a repository can now reference sibling
presets relatively, instead of repeating their own source, repository and
tag:

- `./x` resolves against the directory of the preset file with the
  reference
- `../x` resolves against the parent directory of that file
- `/x` resolves against the root of the preset repository

The source, repository and tag of the preset which holds the reference are
inherited, so `./system/registries` inside `github>org/repo#v2.0.0`
resolves to `github>org/repo//system/registries#v2.0.0`. A reference which
resolves to the `default` preset at the repository root is emitted in the
plain repository form, so `github>org/repo#v2.0.0`, which keeps it
deduplicated against the way consumers spell the very same preset.

A reference must stay inside its repository, its final path segment must
name a preset file rather than a directory, and it can carry parameters
but neither its own `#tag` nor a `:subPreset`. Parameters may contain a
Handlebars template, including a sub-expression such as
`./group({{ lower (env.TEAM) }})`, while a templated path cannot be
resolved and is left alone. A reference must also not carry a source
prefix, so strings such as `local>./x` or `github>../x` are rejected as
invalid.

References are canonicalized lazily, while the preset which holds them is
fetched in `getPreset()`, after migration and massaging. Only presets from
a repository hosted source, so `github`, `gitlab`, `gitea`, `forgejo` and
`local`, are walked. A relative reference which has no parent preset, for
example in a repository config, an inherited config or in `globalExtends`,
is reported as a validation error for that entry.

Relative entries of a preset's `ignorePresets` are resolved in the same
way, so a preset can neutralize a preset which it references relatively,
as long as the consuming repository does not set `ignorePresets` itself.
A reference which cannot be resolved is kept raw and logged, which lets
consumers neutralize it with `ignorePresets`, and it only fails per entry.

Because relative references cannot be resolved while a config is
validated, they are stripped from a `packageRules` entry before its
presets are resolved. A rule which is then left without any selector is
reported as a warning rather than as an error, since the stripped preset
may still provide the missing selectors. Rules without relative references
keep failing hard as before.

The `renovate-config` manager reports relative and unparsable `extends`
entries with a skipReason, instead of dropping them, and ignores templated
entries which can only be resolved at runtime.

Behavior change: an `extends` string which starts with `./`, `../` or `/`,
such as `./x`, `../x` or `/x`, is now read as a relative reference. Before
it was parsed as a local repository name, which in rare cases could
accidentally resolve through the dot segment normalization of the request
URL. For the same reason a source prefixed relative looking string, such
as `local>/org/repo`, `github>./x` or `npm>./x`, is now rejected as an
invalid preset.

* fix(presets): parse scoped npm presets with explicit `npm>` prefix

`npm>@scope/name` was parsed as a local preset, because the heuristic for
local presets matched before the `npm>` prefix was stripped.

Every other use of `npm>` keeps its current behavior, so `npm>foo` still
falls back to the npm package `renovate-config-foo`, `npm>owner/repo` is
still resolved as a local preset and nested prefixes such as
`local>npm>foo` keep working.

* refactor: remove duplicated preset source

* docs: streamline new docs

* add more docs for skipReason and add requested changes

* Apply suggestions from code review

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

* test(presets): drop object literal type casts in relative preset spec

---------

Co-authored-by: Jamie Tanna <github@jamietanna.co.uk>
2026-08-13 13:54:50 +00:00
Thinh Nguyen ab105e6e42 feat(gomod): add gomodTidyAll option for indirect dependency updates in Go monorepos (#37138)
* feat(gomod): add `gomodTidyAll` option for indirect dependency updates in Go monorepos

In Go monorepos it is common for one module to depend on another in the
same repo via a local `replace` directive (e.g. `replace example.com/shared
=> ../shared`). When Renovate updates the shared module, today `go mod
tidy` runs only in that module, leaving dependent `go.sum` files stale.

Add a new `gomodTidyAll` post-update option that:

- Discovers every `go.mod` in the repo and parses its local `replace`
  directives (both inline and block form).
- Builds a dependency graph with `graph-data-structure`, with edges from
  dependency → dependent, matching the existing NuGet convention.
- Runs `go mod tidy` on every transitive dependent in topological order,
  propagating any `gomodTidy1.17` / `gomodTidyE` flags to the dependent
  commands.
- Collects updated `go.mod` and `go.sum` files from each dependent
  directory into the artifact result.
- Implies `gomodTidy` so users only need to enable one option.

Supporting changes:

- Extract `getMatchingFiles` and `resolveRelativePathToRoot` into
  `lib/util/fs/util.ts` so NuGet and gomod can share them instead of
  each having its own glob/resolve helper.
- Refactor `lib/modules/manager/nuget/package-tree.ts` to use the
  shared `getMatchingFiles` helper and rename local variables for
  clarity (`deps` → `visited`, `dep` → `dependent`) per review feedback.

Docs and config:

- Register `gomodTidyAll` in `postUpdateOptions` `allowedValues`.
- Add a row for `gomodTidyAll` to the `postUpdateOptions` table in
  `docs/usage/configuration-options.md`.
- Add a "Monorepo tidying for local `replace` directives" subsection
  to `docs/usage/golang.md` describing when to use the option.

Tests and coverage:

- `lib/modules/manager/gomod/package-tree.spec.ts` — parse/graph/topo
  order, 100% line/branch/function coverage.
- `lib/modules/manager/gomod/artifacts-gomodtidyall.spec.ts` — six
  integration cases covering subshell commands, `tidyOpts` propagation,
  result collection, no-op with no dependents, error handling, and
  the disabled path.
- Full `lib/modules/manager/gomod` suite (151 tests) and NuGet
  package-tree suite (9 tests) pass; new code is fully covered.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(gomod): use named capture groups and direct fs util imports

* fix(gomod): use `go -C` for dependent module tidy commands

A subshell only works in Docker mode, where all commands are concatenated
into a single `bash -l -c`. With `binarySource=install` or `global` each
command is split with shlex and run without a shell, so `(cd dir && ...)`
is treated as the name of a binary.

* refactor(gomod): simplify parsing of local `replace` directives

A single regex now covers both the single line form and the lines inside
a `replace (...)` block. The previous block pattern stopped at the first
`)`, so a block containing a comment with a bracket was skipped, and the
single line pattern did not allow a trailing comment.

Also keeps the NuGet package tree unchanged apart from the two helpers it
now shares.

* docs(gomod): warn against combining `gomodTidyAll` with `gomodMassage`

Massaging comments out the relative `replace` directives that
`gomodTidyAll` follows, so the two options work against each other.

* refactor(fs): use `matchRegexOrGlob` in `getMatchingFiles`

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-13 08:35:38 +00:00
Lukas Backström 481f9b6d46 fix(github-actions): support ratchet comments for nested actions (#45210)
The `ratchet:` alternative in the pin-comment regex only allowed
`owner/repo`, so a ratchet marker for an action in a subdirectory
(`owner/repo/path@ref`) never matched. Such comments fell through to the
bare-token branch, which made `currentValue` the entire marker string,
e.g. `ratchet:actions/cache/restore@v4`. That is not version-like, so
the dep was switched to the `github-digest` datasource, which cannot
resolve the marker as a tag or branch and logs "Could not determine new
digest for update". The dep then gets no updates at all.

Allow further path segments after `owner/repo` so that nested actions
are extracted the same way as their top-level counterparts, with
`currentValue: v4` and the `github-tags` datasource.

Assisted-by: Claude:claude-opus-5
2026-08-12 22:15:52 +00:00
Sergei Zharinov 7c3a3eff21 fix(manager/terraform): stream-based H1 hashing (#45220)
* fix(manager/terraform): stream provider H1 hashing

* docs(manager/terraform): explain provider H1 semantics

* docs(manager/terraform): clarify provider H1 semantics
2026-08-12 22:09:45 +00:00
RahulGautamSingh d53ffc5633 test(bun): mock util/fs instead of fs-extra in artifacts spec (#45235) 2026-08-12 22:07:40 +00:00
RahulGautamSingh d678372061 fix(platform/azure): skip work item Markdown format on Azure DevOps Server (#45237) 2026-08-12 14:04:20 +00:00
Michael Kriese b2da209f26 fix(manager/npm): do not pass --recursive to pnpm dedupe (#45244)
`pnpm dedupe` does not support the `--recursive` flag, so strip it from
the shared args when building the dedupe command.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 12:58:51 +00:00
Sebastian Poxhofer e01b50c6ab refactor(linter): oxlint prefer partial typed casts for consts (#45239)
* refactor: flag all typed object literal casts in prefer-partial-in-specs

* refactor: type maven spec httpError helper against got response shape
2026-08-12 08:50:57 +00:00
Marcelo Estriga 3646307241 fix(manager/npm): pass correct arguments to pnpm dedupe (#42024)
* fix(manager/npm): pass correct arguments to pnpm dedupe

Run pnpm dedupe with the same options that pnpm install, to:
- suppress unecessary dependency download;
- respect Renovate allowScripts and ignoreScripts options.

* fix documentation table alignment

* Fix typo
2026-08-11 22:02:16 +00:00
Edward Klesel 2869cd3a8b fix(terraform): deduplicate provider lockfile hashes (#45226) 2026-08-11 16:01:22 +00:00
Jamie Tanna fba1a9de30 feat(manager/github-actions): add support for Actions Lockfiles (#45199)
* refactor(manager/github-actions): make `extractPackageFile` async

As part of follow-up changes we'll need to read `.github/workflows/actions.lock`
while extracting, which requires we are an async function.

To reduce the diff, we can prefactor this change first.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>

* feat(manager/github-actions): add support for Actions Lockfiles

In June, GitHub announced a public preview for the GitHub Actions
lockfile functionality[0].

To add support for this, we can extend our support for GitHub Actions to
handle the presence of an `actions.lock` file, and if so, update it
after updating other manager files.

Although our ideal case would be to have a pure Typescript-based parsing
and updating of the `actions.lock`, due to the early nature of the
Actions Lockfile syntax, and its lack of stability, we can invoke the
`gh actions-lock` extension when updating.

After the schema has reached a v1 release, we can then migrate to
Typescript.

To make sure that the version of the `actions-lock` extension is always
version pinned, we can expose a `constraints` to control the version,
but allow Renovate to keep the pinned default updated as needed.

This doesn't imply that we have support for `lockFileMaintenance`, as we
are only updating the lockfile when there is a dependency update, not
periodically recreating the lockfile from the current ranges.

`gh actions-lock` re-reads every workflow from disk and rewrites the
whole lockfile, so it does not fit `updateArtifacts`, which is called
once per updated package file.

We can instead follow the shape the `npm` manager uses for its
lock files, and have `processBranch` invoke this once per branch, after
every updated package file has been written to disk.

We skip workflows that aren't onboarded to the lockfile, but still run
for any other package file, as a local composite action can be a
transitive dependency of a workflow which is.

`gh actions-lock` rewrites the workflows it manages back to plain refs
when it regenerates them, which strips out any inline digest pin:

```diff
-        uses: actions/setup-java@1bcf9fb12c # v5.4.0
+        uses: actions/setup-java@v5.7.0
```

This would lead to a repository with `pinDigests` set "flip flopping",
and would cause a lot of erroneous noise for repository owners.

Instead, we can make sure that:

- we don't suggest a `pinDigest` for workflows that are managed by the
  lockfile
- digest pinning is still enabled for `docker://` references
- already-committed digests are updated when they're present - we only
  avoid suggesting /new/ digests to be pinned

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Claude Fable 5 <jamie.tanna+claude-code@mend.io>

[0]: https://github.com/github/actions-lockfile

* coverage

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

* fixup! feat(manager/github-actions): add support for Actions Lockfiles

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>

---------

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-08-11 11:55:06 +00:00
Birger Johan Nordølum 3823ef8742 docs: fix fenced blocks (#45206) 2026-08-11 10:29:08 +00:00
Jamie Tanna 15d541461b refactor(manager): add utility for creating Artifact Error messages (#45218)
* refactor(manager); add utility for creating Artifact Error messages

To prevent ignoring linting rules for nullish coalescing, as well as for
future changes that will use this helper, we can extract out a helper
function for this.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

* fixup! refactor(manager); add utility for creating Artifact Error messages

---------

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-08-11 10:18:20 +00:00