3771 Commits

Author SHA1 Message Date
Jamie Tanna d1f6e41650 test(manager/renovate-config): document which constraints scopes are extracted (#47349)
As part of changes towards #46438, it was noticed that there wasn't
coverage for the ability to specify `constraints` inside `packageRules`.

Co-authored-by: Claude Opus 5.5 <jamie.tanna+claude-code@mend.io>
2026-10-23 17:01:46 +00:00
RahulGautamSingh 1c61ebe76a fix(workers/branch): dedupe updatedArtifacts by path (#46626) 2026-10-23 13:26:37 +00:00
Michael Kriese 0db8910569 test(workers/repository): use a temp cache dir in init specs (#47339)
Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-23 11:13:07 +00:00
Michael Kriese ef96e4da50 feat: validate the containerbase image version on startup (#47248)
* feat: validate the containerbase image version on startup

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

* fix: read the containerbase version check bypass from the process environment only

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

* refactor: use isContainerbase from the base image package in the version check

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

* fix: explain the containerbase image version check errors

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

* test: read the containerbase version file from memfs

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

* fix: address review feedback for the containerbase version check

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

---------

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-22 14:02:27 +00:00
RahulGautamSingh 8b2ff8b388 fix(dependency-dashboard): ignore dashboard checkboxes when mode=silent (#47271) 2026-10-22 07:58:22 +00:00
Jamie Tanna b91f928aa0 fix(workers/repository/lookup): warn when a tag is missing its v prefix (#47155)
When a GitHub Actions Workflow digest pins against a repository that
tags releases with the `v` prefix, but the Workflow itself doesn't use
the `v` like:

    uses: renovatebot/github-action@abd08c7549 # 46.1.5

we correctly match `46.1.5` to the release `v46.1.5` and propose an
update, but when we do a `digest` update (which confirms whether the
current digest SHA is still what the tag is pointing to) it uses
`46.1.5` as its `newValue`.

We look for a release with that version verbatim, and because it's
missing the `v` prefix, we'll perform a failed tag lookup:

    DEBUG: github/tags.findCommitOfTag: Tag 46.1.5 not found for renovatebot/github-action
    DEBUG: Could not determine new digest for update.

As we have a `currentDigest`, this also adds a warning for the
dependency, and we'll never be able to update if the underlying tag has
moved, because we can't look up the tag's SHA.

Although we could retry the lookup with the `v` prefix, we should
instead treat this as the misconfiguration it is, and surface it more
visibly to users with a WARN log.

If we did provide a retry, this could lead to a supply chain attack
where a repository maintainer could push both a `1.2.3` and `v1.2.3` and
convince Renovate to update to a malicious version.

Co-authored-by: Claude Sonnet 5.5 <jamie.tanna+claude-code@mend.io>
2026-10-21 14:11:16 +00:00
Michael Kriese 571a2695a8 fix(workers): keep absent registry URLs absent when detaching credentials (#47256)
Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-21 12:35:23 +00:00
Jamie Tanna fea23465cc fix(workers/repository/init): massage static repo config before validating (#47202)
As `validateConfig` expects massaged config, we should massage the
static repo config before we validate it, as we do for the resolved
repository config.

Otherwise, a string for an option which allows a string (i.e.
`description: "static"`) is reported as invalid, which then logs a
validation issue that the user can't do anything about.

We only massage the config for validation, so the config that is
returned is unchanged.

Via review of the validation code by Claude Fable 5.1.

Co-authored-by: Claude Sonnet 5.5 <jamie.tanna+claude-code@mend.io>
2026-10-21 10:53:00 +00:00
Jamie Tanna 2a3a481e4d fix(workers/repository/init): massage inherited config before validating (#47201)
As `validateConfig` expects massaged config, we should massage the
inherited config - both as it's read, and once its presets have been
resolved - before we validate it, as we do for the repository config.

Otherwise, a string for an option which allows a string (i.e.
`description: "shared"`) is reported as invalid, which fails the run.

We only massage the config for validation, so the config that is merged
is unchanged.

Via review of the validation code by Claude Fable 5.1.

Co-authored-by: Claude Sonnet 5.5 <jamie.tanna+claude-code@mend.io>
2026-10-21 10:52:59 +00:00
Jamie Tanna de17a09413 test(workers/repository/init): document validation of unmassaged config (#47200)
As part of follow-up changes, we'll fix this, but should have existing
test coverage first.

`validateConfig` expects massaged config (i.e. where an option that
`allowString`s has had its string converted to a list), but neither the
inherited config nor the static repo config are massaged before being
validated.

This means that a string for an option which allows a string, such as
`description: "shared"`, is reported as `should be a list (Array)`.

For an inherited config that leads to a failed Renovate run, and for a
static repo config it logs a validation issue that the user can't do
anything about.

In practice, this doesn't seem to impact too many users, but we should
make sure that this is stricter.

Co-authored-by: Claude Sonnet 5.5 <jamie.tanna+claude-code@mend.io>
2026-10-21 10:52:58 +00:00
Michael Kriese dc71c78337 fix(vulnerabilities): apply vulnerabilityAlerts limits to packageRule alerts (#47211)
packageRules can mark updates with isVulnerabilityAlert without forcing the vulnerabilityAlerts config, so those updates used the repository-wide prConcurrentLimit and branchConcurrentLimit instead of the vulnerabilityAlerts ones.

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-20 12:30:51 +00:00
Michael Kriese 71d4f95ecc fix(workers): keep URL credentials of dependencies out of the repository cache and generated texts
Co-Authored-By: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
Co-Authored-By: Claude Sonnet 5 <michael.kriese+claude-code@mend.io>
2026-10-20 09:05:00 +01:00
Michael Kriese 061e9bad5c fix(extract): resolve npmrc again instead of caching it with package files
Co-Authored-By: Claude Fable 5.1 <michael.kriese+claude-code@mend.io>
Co-Authored-By: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-20 09:05:00 +01:00
Michael Kriese 320f770c36 fix(cache): hash URL credentials in cache keys
Co-Authored-By: Claude Fable 5.1 <michael.kriese+claude-code@mend.io>
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
Co-Authored-By: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-20 09:05:00 +01:00
Michael Kriese aaf9d8e1d4 fix(platform/azure): apply the repo's azureWorkItemType (#47158)
Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-19 12:32:56 +00:00
Michael Kriese 293a29bef6 test(config): don't read a local config.js in the config file tests (#46995)
The tests for the default config file resolved `config.js` in the
working directory, so a developer's own config.js was imported and
printed in the assertion diff. Resolve the default config file in a
temporary directory without such a file instead.

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-19 08:18:22 +00:00
Jamie Tanna 08cb221f4a fix(workers/repository): pass constraints correctly when applying postUpgradeTasks (#47069)
As noted in #47068 and #43633, our implementation in
e83acfb2ef missed the case when in
`executionMode=branch`, resulting in no `constraints` being passed, and
therefore using incorrect versions of tools.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-10-15 14:25:59 +00:00
Adam Setch 5b9a6b62c5 fix(prune): refresh PR state before autoclosing (#46518)
* fix(prune): refresh PR state before autoclosing

Signed-off-by: Adam Setch <adam.setch@outlook.com>

* refactor(platform): align getPr refresh param with bitbucket-server

Signed-off-by: Adam Setch <adam.setch@outlook.com>

---------

Signed-off-by: Adam Setch <adam.setch@outlook.com>
2026-10-14 14:11:17 +00:00
RahulGautamSingh 5a3bfc0237 fix(workers/reconfigure): pass default branch to extraction config (#46997)
* fix(workers/reconfigure): pass default branch to extraction config

* docs: note reconfigure branch only previews config changes
2026-10-13 13:14:13 +00:00
Michael Kriese ad515fb962 fix(workers/repository): keep lookup results out of the extract cache (#46982)
* fix(workers): keep lookup results out of the extract cache

The extract cache stored the package files by reference, so lookup
results such as a `skipReason` were saved with them and reused on the
next run, which then skipped those dependencies. Store and load a copy
of the package files instead, and bump the extract cache revision so
existing caches are discarded.

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

* test(workers): drop the coverage ignore of the cached extract branch

The cached extract branch is now covered by tests.

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

* fix(workers/repository): keep the extract cache revision

Keep the existing extract caches; they are refreshed by the next base
branch or config change.

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

---------

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-13 08:07:47 +00:00
Alexander Lindeskär cf46a67d9a fix(workers/global): apply hostRules and internalHostAccess when resolving globalExtends (#46666)
* fix(workers/global): apply `hostRules` and `internalHostAccess` when resolving `globalExtends`

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

* fix(workers/global): resolve admin hostRules per rule for globalExtends and share the HTTP GlobalConfig keys

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:54:47 +00:00
Adam Setch 179f69ce59 fix(platform/github): replace rendered alerts after smart truncation (#45613)
* fix(github): rendered md alerts

Signed-off-by: Adam Setch <adam.setch@outlook.com>

* fix(github): rendered md alerts

Signed-off-by: Adam Setch <adam.setch@outlook.com>

* fix(github): rendered md alerts

Signed-off-by: Adam Setch <adam.setch@outlook.com>

* refactor(pr): use `codeBlock` and address review feedback

- Use `codeBlock` template helper for Caution/Important PR body notes
- Drop the all-platform truncation notice text change (moved to separate PR)
- Remove GitHub truncation-notice test depending on the extracted change

Signed-off-by: Adam Setch <adam.setch@outlook.com>

* remove extra space

Signed-off-by: Adam Setch <adam.setch@outlook.com>

* fix(github): tolerate blockquote blank line whitespace in alert conversion

The emoji callout to GitHub alert syntax conversion relied on the blank
blockquote line being exactly '> ' (trailing space). Linters/CI strip
trailing whitespace from the emitted notes, so also accept '>' without
a trailing space.

* fix(dashboard): render abandoned-dependencies note as a GitHub alert

The '[!NOTE]' callout inside the abandoned-dependencies <details> block
never rendered: GitHub alerts only render at the top level of a body, not
inside collapsible sections, and the description text sat outside the
blockquote (no '> ' prefix), leaving the alert empty.

Move the note outside (above) the <details> block and keep the
description inside the blockquote with '> ' prefixes.

* Revert "fix(dashboard): render abandoned-dependencies note as a GitHub alert"

This reverts commit 55a5d9490e.

* incorporate feedback

Signed-off-by: Adam Setch <adam.setch@outlook.com>

* update test case per feedback

Signed-off-by: Adam Setch <adam.setch@outlook.com>

---------

Signed-off-by: Adam Setch <adam.setch@outlook.com>
2026-10-12 15:13:20 +00:00
Birger Johan Nordølum 8cbd7f5eab fix(changelog): preserve dependency-specific embedded notes (#46733)
* fix(changelog): preserve dependency-specific embedded notes

* fix: use const value for if check
2026-10-12 12:43:29 +00:00
Michael Kriese f64ec3975a fix(cache): build all cache keys with a shared helper (#46811)
* refactor(datasource): separate registry URLs in cache keys with a colon

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

* fix(datasource/go): separate the remaining cache key parts with a colon

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

* refactor(datasource): build cache keys with a shared colon-joining helper

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

* refactor: build all cache keys with buildCacheKey

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

* refactor(http): keep GET package cache keys as the bare URL

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

* refactor(cache): extend cache key helper to memory cache keys

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

* refactor(datasource/go): prefix the goproxy cache keys with their purpose

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

---------

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-10 10:46:09 +00:00
Michael Kriese d071998a8d feat(config): merge mergeable env options with RENOVATE_CONFIG (#46844)
Single env variables for mergeable options now combine with the value in
`RENOVATE_CONFIG` instead of replacing it: lists are appended and objects
are shallow-merged, with the env variable winning for shared keys.
Non-mergeable options are still replaced. This extends the `hostRules`
and `customManagers` handling to every mergeable option, e.g.
`packageRules`, `addLabels` and `registryAliases`.

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-08 14:19:31 +00:00
Michael Kriese 888bf06ddf fix(config): append env host rules to RENOVATE_CONFIG ones (#46843)
* fix(config): append env host rules to RENOVATE_CONFIG ones

List options set through their own env variable, like
`RENOVATE_HOST_RULES`, replaced the list from `RENOVATE_CONFIG`. Append
them instead when the option is mergeable (`hostRules`, `customManagers`),
the same way file and env config are combined.

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

* test(config): cover customManagers from env without RENOVATE_CONFIG

Drop the `mergeable` check from the list-of-objects branch: only
`hostRules` and `customManagers` reach it, and both are mergeable, so the
check could never be false. Add a test for `RENOVATE_CUSTOM_MANAGERS`
without a list in `RENOVATE_CONFIG`.

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

---------

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-08 12:46:29 +00:00
Sebastian Poxhofer 101cb08b4e feat(datasource): report the datasource which served a lookup (#46808)
* feat(datasource): report the datasource which served a lookup

A datasource which delegates a lookup to another one, such as the go datasource to github-tags, returns the delegate's id as effectiveDatasource. The lookup copies it onto the update result, so that templates, matchJsonata and logs can tell which path answered.

* Update lib/util/template/index.ts

* style(template): format the effectiveDatasource description
2026-10-07 14:57:25 +00:00
Jamie Tanna 9284b7ed47 fix(changelog): don't duplicate depName when it matches repo name (#46789)
As noticed in #46787, when a GitHub Action performs an update where the
`repoName` and `depName` are the same, we get i.e.

    jlumbroso/free-disk-space (jlumbroso/free-disk-space)

of which the unnecessary duplication isn't ideal.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-10-07 07:48:56 +00:00
Michael Kriese 31bcd2fcbd refactor(manager): default manager data generics to unknown (#46640)
* refactor(manager): default manager data generics to unknown

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

* refactor(manager): guard bazel artifacts without manager data and type npm post-update config in npm

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

---------

Co-authored-by: Claude Fable 5.1 <michael.kriese+claude-code@mend.io>
2026-10-07 06:31:48 +00:00
Michael Kriese f0d8c92ede refactor(manager/npm): type npm, yarn, bun and deno manager data (#46637)
Co-authored-by: Claude Fable 5.1 <michael.kriese+claude-code@mend.io>
2026-10-07 06:31:45 +00:00
RahulGautamSingh 215433f311 fix(vulnerabilities): raise fixes for deps their manager disables by default (#46761) 2026-10-05 12:46:38 +00:00
Sebastian Poxhofer ebdf90aff3 fix(workers/lookup): only flag downgrades when the versioning orders the values (#46725)
The downgrade guard generalised in #46146 dropped every aws-machine-image
update, because that versioning reports each AMI as greater than any other
and relies on the datasource order instead. Require a strict ordering before
treating an update as a downgrade.

Reported in discussion #46724.
2026-10-03 15:25:58 +00:00
RahulGautamSingh 86bc5d0e18 fix(changelog): only cache release notes on a cache miss (#46612) 2026-10-01 13:12:08 +00:00
y.takahashi ff0e5eed24 feat(npm): support devEngines.runtime and devEngines.packageManager (#43369)
* feat(npm): extract devEngines.runtime and devEngines.packageManager

Adds extraction for the npm devEngines field
(https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines)
covering both single-object and array forms. Uses dot-notated depTypes
("devEngines.runtime", "devEngines.packageManager") consistent with
"pnpm.overrides", and reuses the existing engines/packageManager
datasource resolution. Items without a version are skipped.

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(npm): update devEngines.runtime and devEngines.packageManager versions

Adds an update path for the new devEngines depTypes. Handles both the
single-object form and the array form (the array element is identified
via managerData.devEnginesIndex set at extraction time). Uses the same
anchored search-and-verify approach as the existing replaceAsString
(indexOf("devEngines") + dequal check), so unrelated occurrences of the
same version string elsewhere in the file are not touched.

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(npm): skip lockedVersion and apply @yarnpkg/cli for devEngines deps

Extends the locked-versions post-extract step to cover the new
devEngines depTypes:

- devEngines.runtime and devEngines.packageManager are added to the
  npm-lock skip list (mirrors the engines/packageManager/volta handling
  added in #38598)
- devEngines.packageManager with depName "yarn" gets the @yarnpkg/cli
  packageName fallback when the project is on Yarn 2+, matching the
  existing behavior for engines / packageManager

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(npm): harden devEngines handling against malformed input

- Register devEngines.runtime and devEngines.packageManager in
  knownDepTypes (matches the existing pnpm.overrides pattern)
- Guard against null/non-object array elements in devEngines.* during
  extraction so malformed JSON does not throw
- Use JSON.stringify when interpolating versions into the source search
  string, so any future versions containing JSON-escaped characters are
  matched correctly
- Add an extraction test for a mixed array containing a null item, a
  valid entry, and a version-less entry

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(npm): set hasPackageManager when devEngines.packageManager is an array

The previous hasPackageManager check used isNonEmptyObject which returns
false for arrays. Now that the array form of devEngines.packageManager
is actually extractable and updatable, the corepack post-update step
needs to be triggered for those users as well. Introduces a shared
hasDevEnginesPackageManager helper and uses it from both
extractPackageJson and extractPackageFile.

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(npm): require at least one non-empty array item for hasPackageManager

Align the array branch of hasDevEnginesPackageManager with the
single-object branch by requiring at least one non-empty object item.
Previously, an array containing only null/empty entries would set
hasPackageManager to true and trigger corepack post-update even though
no usable item exists. Add coverage for the empty-array and
only-invalid-items cases.

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(npm): document hasPackageManager semantics for stray-key array items

Make the chosen semantic explicit: an array element with arbitrary keys
but no `name` (e.g. `[{ foo: 'bar' }]`) still sets hasPackageManager to
true, mirroring the pre-existing single-object behavior. The extract
step independently filters out items lacking `name`/`version`.

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(npm): cover dequal rejection in devEngines array update

Adds a test where two devEngines.packageManager array items share the
same version string. The first source-level match belongs to the wrong
index, so the dequal verification rejects it and the loop continues to
the correct occurrence. This exercises the false branch of the dequal
check in updateDevEnginesDependency.

Refs #38067.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(node): list devEngines.runtime as a supported field for Node.js

The npm manager now updates the version inside devEngines.runtime in
package.json, so include it in the file-support list alongside engines
and volta.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Apply the comment changes suggested in the code review

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

* test(npm): cover devEngines update error path instead of ignoring it

Remove the v8 ignore on the updateDevEnginesDependency catch and add a
test that reaches it with invalid JSON, matching how the main
updateDependency catch is covered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(npm): drop unnecessary spread fallback in devEngines managerData

Object spread ignores null/undefined, so the `?? {}` fallback is
redundant. Removing it satisfies the oxlint no-unnecessary-spread-fallback
rule that now runs in CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(npm): type devEnginesIndex on NpmManagerData

Declare devEnginesIndex on NpmManagerData so the value no longer needs a
`as number | undefined` cast when reading it back during update.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(node): document package manager version fields

List packageManager and devEngines.packageManager separately from the Node.js runtime file support entries.

Co-authored-by: Codex <noreply@openai.com>

* feat(npm): support Bun and Deno devEngines runtimes

* fix(npm): preserve Corepack hashes in devEngines

* test(npm): use partial helper for devEngines fixture

Co-authored-by: Codex <noreply@openai.com>

* fix(npm): warn on invalid devEngines update state

Co-authored-by: Codex <noreply@openai.com>

* fix(npm): include devEngines in extracted tool constraints

Co-authored-by: Codex <noreply@openai.com>

* fix(npm): prefer devEngines over volta for package manager versions

Co-authored-by: Codex <noreply@openai.com>

* fix(npm): update Yarn binaries for devEngines package manager upgrades

Co-authored-by: Codex <noreply@openai.com>

* fix(npm): recognize devEngines package managers for Yarn catalogs

Co-authored-by: Codex <noreply@openai.com>

* fix(npm): exclude devEngines from Yarn locked versions

Co-authored-by: Codex <noreply@openai.com>

* refactor(npm): reuse Bun extraction for devEngines runtime

Co-authored-by: Codex <noreply@openai.com>

* test(npm): cover Yarn devEngines manifest preservation and grouped updates

Co-authored-by: Codex <noreply@openai.com>

* refactor(npm): pass packageJsonResult directly to hasDevEnginesPackageManager

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

* test(npm): simplify malformed devEngines fixture

Co-authored-by: Codex <noreply@openai.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Codex <noreply@openai.com>
2026-10-01 11:25:52 +00:00
Jamie Tanna 57bd81f3ac fix(datasource/go): check GitHub Tags for a later release timestamp (#46631)
Similar to changes in d8705054b0, we
should make sure that when there is an annotated Git tag (on GitHub) we
use the tag's `tagger.date` by using the `queryTags()`, and then using
the latest date, instead of relying on the GO module proxy's `Time`
field.

We can use an example from `github.com/kr/pretty@v0.3.1`, whose tag was
created some weeks after the commit it points to.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-10-01 10:49:38 +00:00
Sebastian Poxhofer 8f2ffc0e90 feat(manager/mise): support remote include and git task files (#46611)
* feat(manager/mise): support remote `include` entries

* feat(manager/mise): support digest pinning of `include` refs via comment hints

* feat(manager/mise): support git references of remote task files

* fix(manager/mise): use gitlab-tags for gitlab.com references

* refactor(manager/mise): only support `# <version>` and `# <branch>` hints

* refactor(manager/mise): parse git references with parseGitUrl

* feat(manager/mise): support http and Azure DevOps ssh git references

* refactor(manager/mise): separate remote reference datasources from backends

* docs(manager/mise): add tag ref example for remote includes
2026-10-01 07:43:28 +00:00
Jamie Tanna f52629af41 refactor(instrumentation): instrument getMatchingFiles (#46604)
As part of investigating a `filter packageFiles for managers` span
taking ~2.5m on a very large repository, this gives us the cost of
matching a manager's file patterns against the repository's file list,
as distinct from the `getFilteredFileList` span nested inside it.
2026-09-30 15:06:18 +00:00
Jamie Tanna a35adeacdc refactor(instrumentation): instrument getFilteredFileList (#46603)
As part of investigating a `filter packageFiles for managers` span
taking ~2.5m on a very large repository, we can't tell how much of it is
spent applying `includePaths`/`ignorePaths` to the repository's file
list, versus matching that list against the manager's file patterns.

We can instrument the filtering to find out. This also covers the call
from `bump-versions`.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-30 15:06:17 +00:00
Jamie Tanna 12c6f96612 refactor(instrumentation): instrument each manager's file filtering (#46602)
As part of investigating a `filter packageFiles for managers` span
taking ~2.5m on a very large repository, the span covers the ~120
managers that may be enabled at a given time, which means we don't know
which manager(s) are taking the longest.

To improve this, we can make sure we add a per-manager span.
2026-09-30 15:06:16 +00:00
Jamie Tanna 8b3a066756 test: remove redundant hostRules.clear() calls (#46584)
As we're now managing them via a `afterEach` in `test/setup.ts`, we can
remove any entries in tests themselves.

We don't update overrides of an outer hook or cases where there are more
explicit `clear()`s.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-30 11:22:18 +00:00
Jamie Tanna 2088cac066 feat(workers/repository): log date of last merged PR in repo stats (#46557)
* feat(workers/repository): log date of last merged PR in repo stats

When reviewing the repo's PR merge stats, it can be useful to see how
recently a PR was merged, in case it's a repo that historically used
Renovate, but hasn't recently accepted any PRs.

We can use the `closedAt` field from a merged PR, and make this
available as a top-level stat.

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

* fixup! feat(workers/repository): log date of last merged PR in repo stats

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-30 10:07:32 +00:00
RahulGautamSingh 1732addd25 fix(lookup): warn on unknown datasource (#46511)
* fix(lookup): warn on unknown datasource

* test(lookup): fix type error in missing packageName test
2026-09-29 11:38:34 +00:00
Jamie Tanna af055eba22 feat(config): allow self-hosted admins to bypass allowedHeaders (#45654)
In a similar way to how `allowedEnv` works, we should allow a
self-hosted admin to specify whichever headers they wish in their
`hostRules` - whether in their global config, a `repositories[]` entry,
or a preset a `repositories[]` entry extends.

Previously, this would require a self-hosted admin to add any header
they wished to set to `allowedHeaders`, which would also allow any of
their users' repositories to set that same header.

We can align this behaviour with `allowedEnv`, which makes sure that
the admin's own `headers` are always applied regardless of
`allowedHeaders`, while a repository's own `hostRules` - and those of
any preset it extends - remain constrained by it as before.

We make sure to use an explicit `[]` to make it clear when there are no
headers to allow, opposed to using something less clear like
`undefined`.

We do not currently allow an `extends` (without a `repositories[]`
entry) to bypass, and they'll be followed-up with in #45670.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-29 10:37:15 +00:00
Jamie Tanna c11053adc3 fix(workers/global): apply internalHostAccess during platform init (#46542)
As noted in #45848, the platform initializes itself over HTTP inside
`globalInitialize()`, which happens before we set `endpoint` in
`GlobalConfig`.

This means that `isPlatformEndpoint()` would never be true during
Platform initialisation, so a self-hosted platform on an internal
address was judged as a host the administrator had not vouched for, and
logged:

    WARN: HTTP request to an internal host, which `internalHostAccess=block`
               would refuse ...
          "hostType": "gitea"

This also would apply to `internalHostAccess`'s setting, so even when
using `internalHostAccess=allow`, a warning would appear.

To handle this, we can make sure that we re-set the global values once
we've performed `globalInitialize`, in case global initialisation has
determined the `endpoint`, etc.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-29 08:19:35 +00:00
Sebastian Poxhofer fd4eb7bfbd refactor(workers): normalise depName and packageName once after extraction (#46156)
* refactor(workers): assemble the per-dependency lookup config in one place

The extracted constraints were merged with the same spread twice in
`fetch.ts`, once per package file and once per dependency, and
`constraintsVersioning` only at the package file level. Both levels now go
through `mergeExtractedConstraints()`, and `PackageDependency` gained the
`constraintsVersioning` which only `PackageFileContent` had.

The datasource `defaultConfig` was applied in `fetch.ts` before the lookup and
again in `flatten.ts` afterwards, because `Object.assign(dep, upd)` only copies
the `UpdateResult` fields back onto the dependency. Both call
`applyDatasourceDefaultConfig()` now. Persisting the merged defaults on the
dependency instead would have moved them into another precedence layer of
`flatten.ts`, which merges them over the update config, so the defaults keep
being applied twice.

Behaviour change: a `constraintsVersioning` set on a dependency by a manager is
now honoured, below the package file and the repository config. No manager sets
it yet.

* refactor(workers): normalise depName and packageName once after extraction

`massageDepNames()` only copied `packageName` into a missing `depName`, so the
opposite fallback was applied again in `fetch()` and re-derived at seven worker
call sites.

Extraction now normalises both directions once, via an exported
`normalizeDepNames()`, which also takes over the `depName` trimming that
`fetch()` used to do. Every consumer downstream of extraction reads the field it
wants directly: `fetch()`, the dependency dashboard, the auto-replace deps
signature, the attestation PR note, the commit body table, the OSV lookup and
the rollback PR note.

Both places which re-extract a package file outside the extract phase -
`checkBranchDepsMatchBaseDeps()` and `checkForPendingVersions()` - call
`normalizeDepNames()` on the freshly parsed deps first, so their names stay
comparable with the deps that went through extraction.

In-manager fallbacks are left alone: they run before extraction normalises the
names.

No behaviour change.

* Apply suggestion from @secustor

* refactor(workers): assemble the per-dependency lookup config in one place

The extracted constraints were merged with the same spread twice in
`fetch.ts`, once per package file and once per dependency, and
`constraintsVersioning` only at the package file level. Both levels now go
through `mergeExtractedConstraints()`, and `PackageDependency` gained the
`constraintsVersioning` which only `PackageFileContent` had.

The datasource `defaultConfig` was applied in `fetch.ts` before the lookup and
again in `flatten.ts` afterwards, because `Object.assign(dep, upd)` only copies
the `UpdateResult` fields back onto the dependency. Both call
`applyDatasourceDefaultConfig()` now. Persisting the merged defaults on the
dependency instead would have moved them into another precedence layer of
`flatten.ts`, which merges them over the update config, so the defaults keep
being applied twice.

Behaviour change: a `constraintsVersioning` set on a dependency by a manager is
now honoured, below the package file and the repository config. No manager sets
it yet.

* refactor(config): move applyDatasourceDefaultConfig next to getManagerConfig

Importing config/utils from the datasource module made tools/generate-imports.mjs load config options before manager-default-configs.generated.ts exists, breaking install in CI.

* test(manager/gomod): normalise dep names before running the lookup

* test(manager/gomod): explain why dep names are normalised

* test(workers): give the jsonata base dep a packageName like extraction does
2026-09-29 07:38:08 +00:00
Sebastian Poxhofer a31f03dd7f refactor(workers): assemble the per-dependency lookup config in one place (#46155)
* refactor(workers): assemble the per-dependency lookup config in one place

The extracted constraints were merged with the same spread twice in
`fetch.ts`, once per package file and once per dependency, and
`constraintsVersioning` only at the package file level. Both levels now go
through `mergeExtractedConstraints()`, and `PackageDependency` gained the
`constraintsVersioning` which only `PackageFileContent` had.

The datasource `defaultConfig` was applied in `fetch.ts` before the lookup and
again in `flatten.ts` afterwards, because `Object.assign(dep, upd)` only copies
the `UpdateResult` fields back onto the dependency. Both call
`applyDatasourceDefaultConfig()` now. Persisting the merged defaults on the
dependency instead would have moved them into another precedence layer of
`flatten.ts`, which merges them over the update config, so the defaults keep
being applied twice.

Behaviour change: a `constraintsVersioning` set on a dependency by a manager is
now honoured, below the package file and the repository config. No manager sets
it yet.

* refactor(config): move applyDatasourceDefaultConfig next to getManagerConfig

Importing config/utils from the datasource module made tools/generate-imports.mjs load config options before manager-default-configs.generated.ts exists, breaking install in CI.

* Apply suggestion from @secustor

* refactor(config): drop any from applyDatasourceDefaultConfig
2026-09-29 07:38:07 +00:00
Sebastian Poxhofer c94897829c fix(versioning/poetry): accept PEP 440 specifiers instead of a lookup special case (#46147)
* refactor(versioning/poetry): accept PEP 440 specifiers instead of a lookup special case

`filterVersions()` carried a poetry-shaped branch: when `allowedVersions` was no
valid poetry range but a valid PEP 440 specifier, it matched releases with the
pep440 versioning instead. Poetry accepts PEP 440 specifiers, so the poetry
versioning is where that belongs: `isValid()` falls back to `pep440.isValid()`
and `matches()` to `pep440.matches()` for a range poetry's own syntax cannot
express, and the three versioning imports leave `filter.ts`.

The `config.versioning !== npmVersioning.id` guard on the semver fallback is
dropped as well: npm's `isValid()` is `validRange()` over a normalisation which
only rewrites x-ranges, so it accepts everything `semver.validRange()` accepts
(checked over 163k generated ranges) and the fallback was already unreachable
for npm versioning.

Behaviour changes:

- Poetry `isValid()` now accepts PEP 440 specifiers such as `!=1.2.3` or
  `>=2.6, !=3.0.*, <4`, which it used to reject. The poetry manager is
  unaffected, because it tests pep440 before poetry when picking a versioning.
- Poetry `matches()` now answers those ranges through pep440 everywhere, not
  only for `allowedVersions`.
- For poetry versioning, an `allowedVersions` which is an invalid poetry range
  but valid as both a semver range and a PEP 440 specifier is now matched by
  pep440 rather than semver, because the pep440 fallback moved ahead of the
  semver one.

* fix(versioning/poetry): route every PEP 440-only range to pep440

CI caught `python` versioning's `isLessThanRange('1.9.0', '== 2.7.*')` throwing
`Invalid comparator: ==`: since poetry `isValid()` accepts PEP 440 specifiers,
the python wrapper dispatched that range to poetry, whose npm-based
`isLessThanRange()` cannot parse it. Only `matches()` had the pep440 fallback.

`isLessThanRange()`, `getSatisfyingVersion()`, `minSatisfyingVersion()` and
`getNewValue()` now delegate to pep440 for ranges poetry's own syntax cannot
express, and `subset()` answers `undefined` for them instead of throwing.

The `python` versioning's `poetry.isValid(range) ? poetry : pep440` ternaries
became dead code (poetry now answers every valid range itself, and both modules
receive the same invalid ranges), so the module is `{ ...poetry, isBreaking }`.

The poetry spec also gains rows for three branches nothing covered before: an
unparsable candidate in `getSatisfyingVersion()` / `minSatisfyingVersion()`,
and `getNewValue()` with the `*` range, for which npm's implementation returns
`null`.

* test(versioning/poetry): keep the new spec rows clear of main's coverage rows

main's #46252 appended rows to the same minSatisfyingVersion, getSatisfyingVersion and getNewValue tables, which made the stacked PR conflict with main. Those rows are adopted verbatim at the table ends and the pep440 rows move into the middle of each table, so both sides merge cleanly.
2026-09-28 10:37:31 +00:00
Sebastian Poxhofer aee9d8e0ab fix(workers/lookup): apply the downgrade guard to every versioning (#46146)
* test(workers/repository/lookup): enforce http mocks in the lookup spec

The spec's `afterEach` called `httpMock.clear(false)`, which skipped both
the missing-request and the unused-mock checks for every test in the file.
That kept nine tests green while they performed unmocked requests or left
mocks unused, including two tests whose mocks were crossed: `handles github
404` mocked PyPI and `handles pypi 404` mocked the GitHub API, so neither
ever exercised a 404.

Drop the opt-out and fix the tests it was hiding: swap the two crossed 404
mocks, mock the GitHub GraphQL calls made by the digest lookups, add the
missing packagist `~dev` metadata, gomod `?go-get=1` and PyPI requests, let
the Maven `postprocessRelease` spy handle every call, and delete the dead
`@types/helmet` mock in a test that returns before any release is fetched.

`httpMock.clear(false)` remains in other specs, so the `check` parameter of
`clear()` is kept.

* refactor(workers/repository/lookup): share the update-type config resolution

`applyMinimumReleaseAgeToDigestUpdate()` and `filterInternalChecks()` both
resolved the config their `minimumReleaseAge` check runs against by merging
the `updateType`-scoped sub-config and then applying `packageRules` matching
on `update-type`, and both carried a comment asking the other to be kept in
sync by hand.

Extract that sequence as `resolveUpdateTypeConfig()` in `filter-checks.ts`
and use it from both, and share the `timestamp-optional` warning text as
`missingReleaseTimestampWarning`. The warning stays a constant rather than a
helper function so that each caller keeps its own `logger.once` call site.
Both sync comments are gone.

No behaviour change.

* refactor(workers/repository/lookup): split lookupUpdates into testable stages

`lookupUpdates()` was a single ~840-line function whose stages could only be
reached end-to-end through the datasource layer, which is why its spec had
grown to 6700 lines. Move seven of those stages into separately testable
functions, leaving `lookupUpdates()` as a linear orchestrator:

- `matchVersionCompatibility()` / `restoreVersionCompatibility()` in the new
  `version-compatibility.ts`
- `resolveRangeStrategy()` in the new `range-strategy.ts`
- `resolveCurrentVersion()` and `getNewestMatchingVersion()` in `current.ts`
- `applyVulnerabilityFixFilter()` in the new `vulnerability.ts`
- `groupReleasesIntoBuckets()` in `bucket.ts`
- `resolveUpdateDigests()` in the new `digest.ts`, which also takes over
  `couldApplyMinimumReleaseAgeToDigest()`, `applyMinimumReleaseAgeToDigestUpdate()`
  and `DigestLikeUpdate` from `index.ts`
- `stripNoopUpdates()` in `utils.ts`

`lookupUpdates()` keeps its signature and `index.ts` drops from 1020 to 665
lines. Each new stage gets a focused spec; the end-to-end specs are unchanged.

No behaviour change.

* refactor(workers/lookup): resolve the current version from one release list

`resolveCurrentVersion()` took an `allVersions: string[]` and a separate
`nonDeprecatedVersions: string[]`. The caller built the first from the
releases filtered by `isVersion()` and `followTag`, but the second from the
unfiltered `dependency.releases`, so the "prefer non-deprecated, fall back to
all" passes searched different sets of releases.

It now takes the filtered `Release[]` and derives both lists from it, the same
way `getNewestMatchingVersion()` already did. The shared pair of passes moved
into a private `getCurrentVersionFromReleases()` helper used by both.

No behaviour change in practice: the non-deprecated pass no longer sees
releases that are not versions or that `followTag` excluded, but a non-version
release could only have been picked if `versioningApi.matches()` accepted it,
and the whole lookup spec (including every `followTag` case) is unchanged.

* refactor(workers/lookup): share the release classification between getBucket and getUpdateType

`getUpdateType()` never read its `config` argument and `UpdateTypeConfig` was a
field-for-field copy of `BucketConfig`, while `getBucket()` and
`getUpdateType()` each ran their own major/minor comparison. Both now call a
single `classifyRelease(versioningApi, currentVersion, newVersion)`, which asks
`isSame()` for the minor as well as the major and falls back to comparing
`getMajor()`/`getMinor()` when the versioning does not implement it.
`getUpdateType()` and `UpdateTypeConfig` are gone; the two callers use
`classifyRelease()` directly.

Behaviour changes:

- `getBucket()` now honours `isSame('major')`, so `pvp` no longer buckets
  1.1.x -> 1.10.x as non-major just because `getMajor()` squashes both into the
  float 1.1.
- The update type now reports a difference rather than an increase, matching
  what `getBucket()` has always done. Epoch-aware versionings (deb, debian,
  pep440, rpm) can produce a greater version with a lower major or minor
  number; those updates were bucketed as major/minor but labelled `patch`, and
  are now labelled to match their bucket.

* refactor(workers/lookup): move the gomod pseudo-version check into the go datasource

The only manager-name check in `lookupUpdates()` relabelled an update between
two Go pseudo-versions as a `digest` update (#29034). Knowing that
`v0.0.0-<timestamp>-<commit>` identifies a commit rather than a release belongs
to the Go ecosystem, so `DatasourceApi` gains an optional `isPseudoVersion()`,
`GoDatasource` implements it, and the lookup asks the datasource instead of the
manager. The gomod manager's own `v0.0.0-` check calls the same helper.

Behaviour change: the relabelling is keyed on the `go` datasource instead of the
`gomod` manager, so it now also applies to the other managers using that
datasource (bazel, mise, ocb), and no longer applies to a `gomod` dependency
whose datasource was overridden to something else. The recognised
pseudo-version form is unchanged: only the `v0.0.0-` prefix, not every form
matched by `GoDatasource.pversionRegexp`.

* refactor(workers/lookup): apply the downgrade guard to every versioning

`lookupUpdates()` drops an update whose new value is lower than the current
one, because only a rollback is ever meant to go backwards. Nothing in that
condition is docker-specific, yet it only ran for `versioning=docker`, so the
same broken lookup produced a downgrade PR under any other versioning. The
versioning-id clause is gone, and the `istanbul ignore if` it needed is
replaced by a test which drives a downgrade through npm versioning.

Behaviour change: a non-rollback update to a lower version is now skipped with
the `Unexpected downgrade detected: skipping` warning for every versioning, not
just docker. Rollback updates stay exempt.

* refactor(workers/lookup): ask the go-mod-directive versioning about pseudo-versions

Review feedback: version predicates are the domain of `lib/modules/versioning`,
not of the datasource API. `isPseudoVersion()` now lives in the
`go-mod-directive` versioning (the Go versioning module) and the optional
`DatasourceApi.isPseudoVersion?()` hook is gone. The lookup worker and the gomod
manager import the versioning helper directly.

Because the lookup no longer asks the datasource, the predicate has to be exact:
it matches the anchored `v0.0.0-<timestamp>-<commit>` shape (with the optional
pre-release segment `GoDatasource.pversionRegexp` also allows) instead of the
`v0.0.0-` prefix, so that no manager or datasource gating is needed. The forms
derived from tags (`v1.2.3-0.…`) stay unrecognised, as before.

* refactor(workers/lookup): keep the pseudo-version relabelling limited to gomod

Review feedback: the move of the predicate into the versioning module should
not widen which dependencies get relabelled. The `config.manager === 'gomod'`
condition is back in front of the `isPseudoVersion()` checks, so the lookup
behaves as on main.
2026-09-28 10:37:31 +00:00
Sebastian Poxhofer 868395fb5d refactor(workers/lookup): ask the gomod versioning about pseudo-versions (#46145)
* refactor(workers/lookup): move the gomod pseudo-version check into the go datasource

The only manager-name check in `lookupUpdates()` relabelled an update between
two Go pseudo-versions as a `digest` update (#29034). Knowing that
`v0.0.0-<timestamp>-<commit>` identifies a commit rather than a release belongs
to the Go ecosystem, so `DatasourceApi` gains an optional `isPseudoVersion()`,
`GoDatasource` implements it, and the lookup asks the datasource instead of the
manager. The gomod manager's own `v0.0.0-` check calls the same helper.

Behaviour change: the relabelling is keyed on the `go` datasource instead of the
`gomod` manager, so it now also applies to the other managers using that
datasource (bazel, mise, ocb), and no longer applies to a `gomod` dependency
whose datasource was overridden to something else. The recognised
pseudo-version form is unchanged: only the `v0.0.0-` prefix, not every form
matched by `GoDatasource.pversionRegexp`.

* refactor(workers/lookup): ask the go-mod-directive versioning about pseudo-versions

Review feedback: version predicates are the domain of `lib/modules/versioning`,
not of the datasource API. `isPseudoVersion()` now lives in the
`go-mod-directive` versioning (the Go versioning module) and the optional
`DatasourceApi.isPseudoVersion?()` hook is gone. The lookup worker and the gomod
manager import the versioning helper directly.

Because the lookup no longer asks the datasource, the predicate has to be exact:
it matches the anchored `v0.0.0-<timestamp>-<commit>` shape (with the optional
pre-release segment `GoDatasource.pversionRegexp` also allows) instead of the
`v0.0.0-` prefix, so that no manager or datasource gating is needed. The forms
derived from tags (`v1.2.3-0.…`) stay unrecognised, as before.

* refactor(workers/lookup): keep the pseudo-version relabelling limited to gomod

Review feedback: the move of the predicate into the versioning module should
not widen which dependencies get relabelled. The `config.manager === 'gomod'`
condition is back in front of the `isPseudoVersion()` checks, so the lookup
behaves as on main.

* refactor(workers/lookup): ask the gomod versioning about pseudo-versions

Review feedback: the pseudo-version predicate has nothing to do with the `go`
directive, so it moves from `go-mod-directive` to the new `gomod` versioning,
which is the home for Go module version helpers (#44184).

The lookup worker and `gomod/update.ts` use its `isUntaggedPseudoVersion()`,
which is `isPseudoVersion()` limited to `v0.0.0-` pseudo-versions, so which
dependencies are relabelled or written directly stays as on main.
`go-mod-directive` is unchanged against main again.

* fix(workers/lookup): treat pseudo-versions of major version modules like v0 ones

Review feedback: Go writes a pseudo-version without a base release as
`vX.0.0-<time>-<commit>`, with the major version of the module path, so a
`/v2` module without releases gets `v2.0.0-…`. Only `v0.0.0-` was
recognised, so an update between two such pseudo-versions was not relabelled
as a digest update (#29034), and gomod/update.ts wrote the bare commit
instead of the new pseudo-version.

The lookup and the update now use `isPseudoVersion()` from the `gomod`
versioning, and `isUntaggedPseudoVersion()` is gone. The go datasource only
returns pseudo-versions for modules without releases, which always have that
form, so nothing else changes. The lookup keeps its `config.manager ===
'gomod'` condition.

* refactor(workers/lookup): drop the guards around isPseudoVersion()

Review feedback: `isPseudoVersion()` now accepts an undefined version, so
the lookup and gomod/update.ts pass their optional values to it directly.
2026-09-28 10:37:30 +00:00
Michael Kriese 0efc05f025 fix(reconfigure): cache a flag instead of the unused extract result (#46441)
* fix(reconfigure): cache a flag instead of the unused extract result

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

* fix(reconfigure): migrate a cached extract result to the new flag

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

---------

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-09-24 12:47:57 +00:00