2248 Commits

Author SHA1 Message Date
Michael Kriese 9e354ff18b ci: fail tests that read the repository config.js (#46999)
Write a canary config.js before the unit tests, and fail any test that
imports it, so tests can't depend on a config.js in the working
directory again.

Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-19 08:18:23 +00:00
Jamie Tanna 2a300e8d08 refactor(config): specify scopes for enabled and managerFilePatterns (#46683)
* refactor(config): specify scopes for `enabled` and `managerFilePatterns`

As part of #43020, the two options which name every manager - and in
`enabled`'s case, every update type - can describe where they're valid
through `scopes` instead, so they no longer need updating when a
manager is added.

This allows us to simplify the way that the parents are defined, and
will now result in an improved error message i.e.

```
"managerFilePatterns" can't be used at the top level of a config, as it
can only be used in a manager's config or in `customManagers`.
```

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

* fixup! refactor(config): specify scopes for `enabled` and `managerFilePatterns`

getConfig() decides whether an option gets a top-level default by
checking the raw option.parents for '.', which doesn't know about
scopes. Giving `enabled` its top-level eligibility through `scopes`
instead of a literal `parents: ['.']` entry meant getConfig() stopped
giving it a default value at all, so `config.enabled` became undefined
at the top level - breaking anything that reads it before a manager's
own config is merged in, such as extract-fingerprint-config.ts.

We can use getAllowedParents(), which already knows how to combine
scopes and parents, instead of reading option.parents directly.

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

---------

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-10-12 12:09:14 +00:00
Michael Kriese 20883909b8 build(deps): add @renovatebot/base-image package (#46784)
Add `@renovatebot/base-image` as a dependency at the same version as the
`ghcr.io/renovatebot/base-image` Docker image, so packages that consume
Renovate's types get it installed too. Renovate updates both in one
`renovate-base-image` group with the same commit types, and a
`lint-other` check fails when the two versions differ.

Co-authored-by: Jamie Tanna <jamie.tanna@mend.io>
Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-10-06 08:10:10 +00:00
Michael Kriese 13aad8030a ci: use github.token for the workflow token everywhere (#46591)
Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
2026-09-30 11:41:39 +00:00
Jamie Tanna a2704ed3f1 test: always clear hostRules after each test (#46582)
Instead of needing to always make sure that we've cleared host rules in
tests that use them - or knowing when they're touched indirectly - we
can make sure that we have an `afterEach` that will clear our Host
Rules.

We can do this by making sure that we have a top-level `afterEach` that
handles this, which needs a dynamic import to avoid eagerly importing
and caching it, which would leave stale unmocked bindings for a given
file's test run.

We also need to make sure that `private-key.spec.ts`'s `sanitize.ts`
mock is updated to also stub `clearRepoSanitizedSecretsList`, since
`hostRules.clear()` now calls.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-30 11:22:18 +00:00
renovate[bot] 3311b34ad6 chore(deps): update dependency tsdown to v0.23.0 (main) (#45855)
* chore(deps): update dependency tsdown to v0.23.0

| datasource | package | from    | to     |
| ---------- | ------- | ------- | ------ |
| npm        | tsdown  | 0.22.14 | 0.23.0 |

* fix: satisfy tsgo declaration emit for tsdown v0.23

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: secustor <sebastian@poxhofer.at>
2026-09-25 09:01:55 +00:00
Sergei Zharinov ac2fc77641 refactor(http-mock): Remove request tracing (#44482)
* refactor(http-mock): remove request tracing

* test: replace remaining HTTP trace assertions
2026-09-23 09:01:01 +00:00
Jamie Tanna e58e46d24f test(docs): support self-hosted-only sub-options in documentation checks
As part of future changes, we'll introduce a self-hosted configuration
option that has a parent.

Similar to e0ce9dabd6 we can make sure
that the self-hosted configuration documentation has sub-option
handling.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-09-10 14:52:01 +01:00
Michael Kriese 634d3b6084 refactor: use modern neotraverse API (#45809)
* build(deps): update dependency neotraverse to v1

| datasource | package     | from   | to    |
| ---------- | ----------- | ------ | ----- |
| npm        | neotraverse | 0.6.18 | 1.0.1 |

* refactor: use modern neotraverse API

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-09 13:15:15 +00:00
Sebastian Poxhofer 05e1271376 test: use expect().resolves instead of awaiting inside expect (#45672)
Enables the vitest/prefer-expect-resolves oxlint rule and applies its
autofix across the spec suite.
2026-09-04 10:40:46 +00:00
Sebastian Poxhofer 3412de84ce refactor(linters): enable oxlint rule prefer-named-capture-group (#44714)
* refactor(lint): enable oxlint prefer-named-capture-group at error

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* fix prettier failure

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

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-03 09:54:40 +00:00
Sebastian Poxhofer fbedd41e82 test: replace env operation with vi.stubEnv() (#45490)
* test: replace manual process.env mutation with vi.stubEnv

Enable Vitest's `unstubEnvs` so env stubs are reverted automatically
before every test, and convert the manual `process.env.X = ...` /
`delete process.env.X` pairs in specs to `vi.stubEnv()`.

This removes the hand-written `afterEach` cleanup blocks and the
`const OLD_ENV = process.env` / `process.env = { ...OLD_ENV }`
save-restore dance, which silently leaked state between tests when a
test set a variable without a matching delete.

Left as-is (incompatible with `unstubEnvs`, which unstubs before each
test, not after):
- module top-level env writes (cocoapods, gomod, post-update, pip-compile
  and bundler artifacts specs)
- `beforeAll` env writes -- the two in `util/http` moved to `beforeEach`

* test: stop asserting on ambient environment variables

Three specs asserted on values that the surrounding environment can
override, so they only passed on a machine that happened not to set them:

- `util/exec/env`: `getChildProcessEnv()` forwards every entry of
  `basicEnvVars`, but the spec only seeded a subset. Any other forwarded
  variable that was set ambiently (e.g. a lowercase `http_proxy`) leaked
  into the `toEqual` assertion. Clear all of them first.
- `util/git/index`: `process.env.GIT_SSH_COMMAND` deliberately overrides
  the default that the two env-inheritance tests assert on. Clear it.
- `logger/pretty-stdout`: the colorized level strings are built at import
  time, so the `beforeEach` setting `FORCE_COLOR` could never affect them
  -- it was dead code, and the test silently assumed a terminal without
  colour support. Derive the expectation the same way the module does.

* test(datasource/nuget): use a throwaway cache dir for nupkg downloads

The `determine source URL from nupkg` tests do not mock the filesystem,
so they really wrote downloaded packages into a fixed `/tmp/cache` path.
That fails wherever the system tmpdir is not writable, and two checkouts
running the suite at once would share the same directory.

Use `tmp.dir({ unsafeCleanup: true })` and clean it up afterwards, which
is the pattern the other specs that touch disk already use.

* feat(lint): add renovate/prefer-stub-env rule

Enforces in specs what the migration to `vi.stubEnv` established:

- assigning to or deleting `process.env.X` inside `beforeEach`, `afterEach`,
  `it` or `test` is reported, with a fixer that rewrites it to `vi.stubEnv()`
- module scope, `describe` bodies and `beforeAll` / `afterAll` are left alone:
  `unstubEnvs` reverts stubs *before* each test, so a stub created there is
  gone by the time the first test runs, and those must keep assigning directly
- replacing the `process.env` object is reported everywhere and never fixed.
  `vi.stubEnv()` captures the original object when the worker starts, so after
  a reassignment its deletes silently target the old object

The rule found 28 further violations in specs the earlier sweep missed, since
that one was anchored on `delete process.env`. Twelve were auto-fixed; the
rest replaced `process.env` wholesale and are now `clearEnv()` from test/util.

`util/exec/index.spec.ts` opts out with a comment: it asserts on the whole
child env, and `vi.stubEnv()` cannot express that because it maps `PROD`,
`DEV` and `SSR` onto '' instead of deleting them.
2026-08-28 09:26:20 +00: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
renovate[bot] ea8d11b096 chore(deps): update dependency @oxlint/plugins to v1.78.0 (main) (#45346)
* chore(deps): update dependency @oxlint/plugins to v1.78.0

| datasource | package         | from   | to     |
| ---------- | --------------- | ------ | ------ |
| npm        | @oxlint/plugins | 1.72.0 | 1.78.0 |

* chore(deps): update dependency oxlint to v1.78.0

Align oxlint with @oxlint/plugins so the plugin types match again, and
replace the computed namespace access in validate-schemas.spec.ts that
oxlint 1.78 flags via import/namespace.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: secustor <sebastian@poxhofer.at>
2026-08-24 09:13:19 +00:00
Jamie Tanna df7a014c91 refactor: generate the list of templatable fields
As part of follow-up changes, we need a list of fields that could be
used in templates as part of a linting rule.

To avoid the `tools` directory importing from `lib`, we can make sure
that we generate the list of fields.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-08-07 14:28:32 +01:00
Jamie Tanna f1cd516513 refactor(workers/repository): add isMinimumReleaseAgeApplicable/isMinimumConfidenceApplicable (#44824)
As part of follow-up changes, we'll use these functions to centrally
determine as to whether to execute `minimumReleaseAge` or
`minimumConfidence` checks against a given updateType.

For now, we can wire this into our documentation tests, to make sure
that this stays in sync with `isMinimumReleaseAgeApplicable`.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-07-24 16:22:00 +00:00
Jonathan Hill 0f06e635df feat(platform-azure): initial bearer token auth support for Azure DevOps (#43888)
* feat(platform/azure): support bearer token auth (auto-detect token type)

* refactor(platform/azure): use isPlainObject for JWT header check

Replace manual typeof/null check with isPlainObject() from
@sindresorhus/is in isProbablyJwt(). Remove unused _GlobalConfig
import from test file.

* refactor(platform/azure): use parseJsonc to parse JWT header

* test(platform/azure): use a real JWT in the set bearer token/endpoint test

* feat(platform/azure): log detected token type

* refactor(platform/azure): guard token before JWT check; remove outdated todo comment

* docs(platform/azure): restore TODO note about possibly-undefined token (#22198)

* refactor(platform/azure): move isProbablyJwt() and tests to new files lib/util/http/jwt.ts and lib/util/http/jwt.spec.ts

* refactor(platform/azure): use Json.safeParse() instead of parseJsonc() in isProbablyJwt()

* refactor(platform/azure): accept undefined token in isProbablyJwt and add guard to drop non-null assertions

* test(platform/azure): extract shared buildTestJwt helper and dedupe

* docs(platform/azure): reword the Entra ID token instructions

* chore(platform/azure): remove irrelevant lines from docstring

* refactor(platform/azure): export buildTestJwt() from new test/jwt-util.ts

* docs(platform/azure): use 1 for numbered lists

* refactor(test): extract arrow function from buildTestJwt

---------

Co-authored-by: Bastian Wenske <bastianwenske@outlook.de>
2026-07-19 23:01:52 +00:00
Sebastian Poxhofer 64e6a4c71f refactor(oxlint): enable unicorn/prefer-at (#44556)
Enable the unicorn/prefer-at rule as error in .oxlintrc.json and fix all
43 pre-existing violations (arr[arr.length - 1] -> arr.at(-1)) via oxlint
autofix. Where .at() widened the type to T | undefined, non-null
assertions were added at sites where surrounding logic guarantees the
element exists (length guards, split results), preserving the original
runtime behavior and typing.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 12:57:23 +00:00
Sebastian Poxhofer 7436b80cda test(linter): add renovate/no-redundant-mock-reset rule (#44557)
ci(linter): add renovate/no-redundant-mock-reset rule

Vitest sets mockReset: true globally in vitest.config.mts, which resets
all mocks before each test. This makes vi.resetAllMocks() /
vi.clearAllMocks() and per-mock .mockReset() / .mockClear() calls inside
beforeEach/afterEach hooks redundant. Add a custom oxlint rule (enabled
for **/*.spec.ts and test/**) flagging such calls, and remove the 40
redundant calls it found. restoreAllMocks/mockRestore are not flagged
because restoreMocks is not enabled globally.

Two sites keep an inline disable with a reason: nested beforeEach hooks
in filter-checks.spec.ts and onboarding/pr/index.spec.ts intentionally
call mockReset() to discard once-values queued by an outer beforeEach.

Requested by maintainer review feedback (review comment 3052324877).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 11:26:20 +00:00
Nahrin 67c9e08e97 docs: restructure postUpdateOptions table into headers (#44089)
* docs: restructure `postUpdateOptions` table into headers

Replace the wide markdown table under `postUpdateOptions` with
individual `###` headers per option, sorted alphabetically. This
improves readability and makes each option directly linkable.

Update `getConfigOptionSubHeaders` to handle backtick-wrapped
section and sub-header names. Add a test ensuring every
`allowedValues` entry has a corresponding sorted header.

* Update docs/usage/configuration-options.md

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

---------

Co-authored-by: Jamie Tanna <github@jamietanna.co.uk>
2026-06-19 15:12:33 +00:00
Sebastian Poxhofer 171a591d84 feat(git): validate commit shas (#43988)
* feat(git): validate length commit shas

* test: adapt test mocks

* chore: update import paths

* feat(git): make the validation more strict and support repositories using sha256

* test: add fakeSha function for deterministic git commit shas in tests
2026-06-15 06:36:57 +00:00
renovate[bot] 9245b57c58 chore(deps): update linters to v1.67.0 (main) (#42416)
* chore(deps): update linters to v1.67.0

| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| npm        | oxlint  | 1.57.0 | 1.67.0 |

* test(oxlint): deactivate new tests for now

* fixup linting errors

* revert googleAuth mock implementation

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: secustor <sebastian@poxhofer.at>
2026-06-06 14:09:05 +00:00
Jamie Tanna 7a2af5318c docs(config): reword repo configuration options header (#43678)
* docs(config): don't trim newline after generated config filenames

Otherwise there's no newline before the next sentence.

* docs(config): correct usage of JSON5 presets

* docs(config): rewrite overview section

- introduce a linkable section for "what filenames are supported"
- correct the usage of "config help" discussions
- keep precedence/ordering in a single paragraph

* fixup! docs(config): rewrite overview section
2026-05-29 13:37:45 +00:00
Jamie Tanna 44d122b762 docs: autogenerate cache namespaces (#43370)
As noted in #41214, it would be convenient to not have to manually
update this list.

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
2026-05-15 16:42:36 +00:00
Jamie Tanna 5c4f65c86b docs: mark child options as code blocks (#42854)
A follow-up missed from 982a0219bf.
2026-04-24 06:17:03 +00:00
Mike Ryan a9ae8ee17f test(docs): improve option filtering in specs (#42846)
chore: improve option filtering in specs

Prior to this change, any time any option that had a defined `parents` property that
also had root-level markdown documentation would require an update to the
`getRequiredConfigSubOptions` and `getRequiredConfigSubOptions` functions in the
`documentation.spec.ts`.

After this change, that is no longer required as the functions
now consider an option root-level when it does not have a `parents` property,
`parents` is an empty array, or `parents` contains the root-level specifier (`.`).

Originally surfaced from #42671, but extracted to its own PR.
2026-04-23 15:41:23 +00:00
Jamie Tanna 982a0219bf docs: wrap config options in <code> tags (#42836)
As they are configuration options and can be quite code-y we should
render them like this.

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
2026-04-23 11:32:05 +00:00
Sergei Zharinov a67a96eab5 refactor(lint): Switch to Oxlint (#42384)
* refactor(lint): Switch to Oxlint

* Update .oxlintrc.json

* Fix CI

---------

Co-authored-by: Jamie Tanna <jamie.tanna@mend.io>
2026-04-07 14:42:23 +00:00
Michael Kriese 440e353145 chore: use ts extension (#42300) 2026-04-01 07:46:34 +00:00
Jamie Tanna e31dfd74e8 refactor(tools/sync-module-labels): move shared code into a shared helper (#42249)
As otherwise this leads to us importing the tool itself, which has a
top-level function that runs the tool.

As noted on a comment on #42012, this means that the tests are now
executing `gh` which isn't intended.

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
2026-03-30 17:31:35 +00:00
Sergei Zharinov e0c9bc1961 refactor(lint): move option-dependent rules from ESLint to oxlint (#42215)
Migrate rules that previously stayed in ESLint due to option parity
concerns. oxlint now supports all needed options:

- `no-restricted-imports` (paths: nock, parse-link-header, path)
- `consistent-type-assertions` (objectLiteralTypeAssertions: allow)
- `explicit-function-return-type` (allowExpressions, allowTypedFunctionExpressions)
- `no-unused-vars` (args: none, ignoreRestSiblings)
- `no-empty-object-type` (allowInterfaces: with-single-extends)

Convert eslint-disable comments to oxlint-disable for the allowed
import sites (url.ts wrapper, http-mock.ts test helper).

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2026-03-30 16:45:02 +00:00
saudademjj f2546b84a3 ci: add module label sync tooling (#42012)
* ci: add module label sync tooling

* ci: align module label sync cli

* ci: fix module label sync checks

* refactor: simplify module label sync cli

* fix: relax module label sync cli options type

* Address a couple of nitpicks

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

* fixup! Address a couple of nitpicks

---------

Co-authored-by: Jamie Tanna <github@jamietanna.co.uk>
Co-authored-by: Jamie Tanna <jamie.tanna@mend.io>
2026-03-25 10:14:40 +00:00
Felipe Santos e8a5c70862 feat(config-migration): preserve comments when migrating renovate.json (#38646)
* feat(config-migration): preserve comments when migrating `renovate.json`

* Replace jsonc-parser with jsonc-weaver

* Switch to npm package

Refs https://github.com/felipecrs/jsonc-weaver/commit/7a168e2fdd6959fab9d1ebd6bb5dafc02dbf62ff

* Fix tests

* Add test coverage for fallback

* Fix coverage again

* Fix coverage for real

* Restore line break
2026-03-13 21:53:52 +00:00
Jamie Tanna e0ce9dabd6 docs: prefix child options with their parent (#41828)
This also makes sure that our URL fragments should be more consistent
over the years, as duplicate names (across parent and child options)
cannot clash.

This also corrects links from the code to include the new fragment.

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
2026-03-12 10:56:52 +00:00
Sergei Zharinov ee2c737d41 refactor: Drop more eslint plugins (#41740)
* refactor: replace @containerbase/eslint-plugin and eslint-plugin-import-x with local rules and biome

The two containerbase ESLint rules (test-root-describe, no-tools-import) are now
implemented locally in tools/lint/rules.js, removing the external dependency.

All eslint-plugin-import-x rules are dropped: default, named, namespace, and
no-cycle are already covered by oxlint; no-unresolved is covered by TypeScript;
no-extraneous-dependencies is replaced by biome's noUndeclaredDependencies.

* fix: exclude eslint.config.mjs from type-checking

eslint-plugin-promise has no type declarations. Previously this was
masked by @types/eslint pulled in transitively via eslint-plugin-import-x.
The config file is not application code and gains nothing from type-checking.

* refactor: drop eslint-plugin-promise, move covered rules to oxlint

The promise rules target .then()/.catch() patterns which are rare in an
async/await codebase. The 4 rules oxlint supports (catch-or-return,
no-callback-in-promise, no-new-statics, valid-params) are moved there.

* fix: prettier formatting after removing eslint-disable comment
2026-03-09 16:05:50 +00:00
renovate[bot] 756ede7873 chore(deps): update dependency memfs to v4.56.10 (main) (#40701)
* chore(deps): update dependency memfs to v4.56.10

| datasource | package | from   | to      |
| ---------- | ------- | ------ | ------- |
| npm        | memfs   | 4.55.0 | 4.56.10 |

* inner source memfs types

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: secustor <sebastian@poxhofer.at>
2026-02-28 11:21:29 +00:00
Michael Kriese 8cf4171637 chore(tsdown): validate and sort entrypoints (#41407)
chore(tsdown9: validate and sort entrypoints
2026-02-23 10:44:57 +00:00
renovate[bot] 645a28c77c build(deps): update dependency prettier to v3.8.1 (main) (#39779)
* build(deps): update dependency prettier to v3.8.1

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

* fixup prettier

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: secustor <sebastian@poxhofer.at>
2026-02-18 08:41:34 +00:00
Sergei Zharinov 9d857c1f68 refactor(lint): Organize imports with biome (#40966) 2026-02-06 13:40:01 +00:00
Sergei Zharinov 2b0e80b884 feat!: Switch to ESM modules (#40756) 2026-01-29 14:21:41 +00:00
Sergei Zharinov 930cf6633c refactor: Rewrite imports with .ts extensions (#40700)
fix: Additional vi.mock path corrections and prettier formatting
2026-01-26 22:48:17 +00:00
Jamie Tanna 9f3db00d1a fix(util/exec): allow ignoring failures per-command (#40290)
As part of future changes which will fix issues with Composer + Yarn 1
introduced by f430552de4, we need to find
a way to ignore command failure, on a per-command basis.

To do this, we can provide a refactor to introduce a new type,
`CommandWithOptions` which has the ability to specify whether to
`ignoreFailure`.

To make this less of a refactor than would otherwise require, we can
pass around a `(string | CommandWithOptions)[]`
(or a `string[]` or a `CommandWithOptions[]`) to be used, and use
helpers `asRawCommand` and `asRawCommands` to extract the underlying
command where necessary.

In the case a command's failure is being ignored, return the error code
in the `ExecResult`.

We also need to make sure that when executing in Docker, we still
provide the `|| true`s, otherwise we'll start to see commands failing
unexpectedly.

As part of future-proofing the `CommandWithOptions`, we can make sure
that it uses `string[]`s for the command it's representing, to avoid
re-parsing it.
2026-01-08 09:36:06 +00:00
Michael Kriese c641239c19 fix: use stricter types for renovate config (#39594)
* fix: use stricter types for renovate config

* fix: revert changes

* Apply suggestions from code review
2025-11-28 13:16:27 +00:00
Sergei Zharinov 558bdc159d feat: Cleanup mutexes before each run (#38987)
* feat: Cleanup mutexes before each run

* Update setup.ts

* Update mutex.spec.ts

* Update setup.ts

* Unmock mutex in deb datasource spec to prevent race condition

* Update index.spec.ts
2025-11-15 21:24:43 +00:00
Anne Stellingwerf cf7997ad62 chore: validate all handlebars helpers are documented (#38932)
* ci: validate all Handlebars helpers are documented

* ci: validate all Handlebars helpers are documented

* chore: validate all handlebars helpers are documented

* chore: validate all handlebars helpers are documented
2025-11-02 12:15:10 +00:00
Jamie Tanna 066c7026e7 test: correctly call toMigrate with vitest (#38242)
fix(tests): correctly call `async toMigrate` with vitest

While working on #38240, I noticed that the failing tests I was
writing didn't trigger.

It turns out that in 997c23502e, when we
migrated to Vitest, and made some functions `async`, we missed out on
making the tests themselves `async`.

This correctly applies the `async` modifier to test functions, allowing
them to correctly pass/fail when running async code.

We can also make sure that `toMigrate` is returning a Promise to
indicate it's asynchronous.
2025-09-27 08:29:30 +00:00
Rhys Arkins 93fa41b26f chore: remove rarkins from maintainers (#37585)
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
2025-08-29 08:36:42 +00:00
Michael Kriese 3211d56e21 refactor(zod): rename schema to match our best practices guide (#37499) 2025-08-14 10:35:03 +00:00
RahulGautamSingh 8bedd04ab7 test: use async (#36953) 2025-07-12 12:35:51 +00:00
Sergei Zharinov 2e382c5ebc ci: Check documented package cache namespaces (#36909) 2025-07-08 21:38:30 +00:00