* fix(util/exec): pick tool releases compatible with resolved node version
* refactor(util/exec): pass resolved runtimes as an object
* refactor(util/exec): match tools against their containerbase parent
* test(util/exec): run real constraints filtering for parent versions
* chore(util/exec): add a strong type for Containerbase's known tools
As noted in #41849, we currently don't have a way of enforcing the usage
of a `ContainerbaseToolName` being a tool that Containerbase actually
knows.
To handle this, we can use the new `@containerbase/base` and
`@renovatebot/base-image` packages to see what Tools we currently have
support for, and make sure that our types use the tools supported by
`@renovatebot/base-image` (and therefore `@containerbase/base`).
As well as the Typescript compilation error a user will receive, we can
add a test that provides a better note to the user about how to add a
new tool.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fixup! chore(util/exec): add a strong type for Containerbase's known tools
* fixup! chore(util/exec): add a strong type for Containerbase's known tools
So we can get better confidence that we're not clashing with type names
between Containerbase tools and non-tool constraints.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
---------
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
`install-tool` installs a version and also makes it the active one. The
memo skipped `install-tool` for any tool version already installed in the
run, so after A -> B -> A the last command ran on B. Track the active
version per tool instead and skip only when the requested version is
already active.
Co-authored-by: Claude Opus 5.5 <michael.kriese+claude-code@mend.io>
As it's not an official tool Renovate supports, and was added for
Mend-internal usage.
However, as we work towards #41849, we should make sure that we don't
document a tool that isn't used by Renovate.
When running Renovate with `binarySource=install` on a repository with
many branches, the amount of time running `install-tool` - on already
installed tools - can take a significant percentage of the overall run.
For instance, on one repository we have instrumented with OpenTelemetry,
we see:
- initial `install-tool golang`: 8.7s
- follow-up `install-tool golang`: median 635ms, max 2.4s
However, because we run `install-tool golang` 640 times, this adds up to
24.8/29.2m (85%) of the repo's run time, which is an overwhelming
percentage when we're not even re-installing the tool.
To handle this more effectively, we can add an in-memory cache of all
the tools (and resolved versions) that we've installed in a given run.
We can't do this with `binarySource=docker`, as it has a fresh container
each time.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* feat(manager): add apm manager for Agent Package Manager
Add a new `apm` manager that updates git-pinned dependencies in APM
(Agent Package Manager) `apm.yml` manifests, as requested in
renovatebot/renovate#42507.
The manager parses the string entries under `dependencies.apm` and
`devDependencies.apm` (`[host/]owner/repo[/subpath]#<ref>`) and selects
the datasource dynamically from the git host, reusing the existing
github-tags, gitlab-tags and git-tags datasources. MCP entries carry no
pinnable version and are ignored.
When an `apm.lock.yaml` lockfile is present, it is refreshed by running
`apm install` via a new `apm` tool constraint (pypi `apm-cli`).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vfjt3BpqDriiVsvwqVe9M9
* fix(manager/apm): resolve apm tool from github releases
APM ships self-contained binaries as GitHub release assets
(apm-linux-<arch>.tar.gz under vX.Y.Z tags), not as the PyPI apm-cli
wheel. Point the apm tool constraint at the github-releases datasource so
the version Renovate resolves matches the artifact that actually gets
installed, stripping the leading `v` from the tag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vfjt3BpqDriiVsvwqVe9M9
* docs(manager/apm): point to canonical microsoft/apm repository
The APM project's canonical home is github.com/microsoft/apm (originally
danielmeppiel/apm). Update the manager URL and readme accordingly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vfjt3BpqDriiVsvwqVe9M9
* refactor(manager/apm): validate manifest with zod schema
Address review feedback on the apm manager:
- parse `apm.yml` with a dedicated zod schema via
`parseSingleYaml(content, { customSchema })` instead of casting the
parsed YAML to `ApmManifest`
- `LooseArray(z.string())` keeps only the string dependency entries, so
MCP objects and other non-string values are dropped by the schema and
the manual `Array.isArray`/`is.string` guards are no longer needed
- drop the `as SkipReason` casts now that the literals are inferred
- remove the now-unused `types.ts`
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbMAQBiMRNkCNxc8EGQw1C
* Update schema.ts
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
* Update readme.md
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
* Update readme.md
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
* refactor(manager/apm): simplify manifest schema and host detection
Address review feedback:
- default the `apm` array to `[]` in the schema (`LooseArray(...).catch([])`)
since LooseArray already discards non-string entries, so downstream code
no longer needs to handle `undefined`
- use `coerceArray` when mapping the optional dependency sections
- drop the redundant `host === 'github.com'` / `host === 'gitlab.com'`
checks in datasource selection; `detectPlatform` already resolves those
hosts (the explicit host comparison is only kept to decide registryUrls
for self-hosted instances)
- document that APM only supports remote git references and that dots in
repo names / subpaths are handled, with a regression test
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbMAQBiMRNkCNxc8EGQw1C
* docs(manager/apm): fix readme trailing newline
Remove the trailing blank line left after the readme edits so it passes
`prettier` and `markdown-lint`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbMAQBiMRNkCNxc8EGQw1C
* refactor(manager/apm): parse dependency path with named capture groups
Replace the manual host/owner/repo splitting (and the standalone dot
regex) with a single named-capture regex, as suggested in review. `owner`
excludes dots so the optional hostname segment is unambiguous, while repo
names and subpaths may still contain dots.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbMAQBiMRNkCNxc8EGQw1C
* test(manager/apm): align admin config with InternalGlobalConfigOptions
`localDir` moved out of `RepoGlobalConfig` into `InternalGlobalConfigOptions`
on main, so annotate the test admin config as
`RepoGlobalConfig & InternalGlobalConfigOptions`, matching the other
manager artifacts specs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbMAQBiMRNkCNxc8EGQw1C
* fix(manager/apm): resolve GitLab nested groups and recognize SHA-pinned refs
- resolve nested GitLab project slugs (e.g. `group/subgroup/project`)
instead of capping at `owner/repo`, splitting the project from any
virtual-package subpath using APM's primitive-dir / virtual-file markers
- recognize the documented SHA-pinned form and skip it
(`unversioned-reference`) rather than treating the SHA as a version or
rewriting it
* feat(manager/apm): support digest pinning for SHA-pinned deps
Recover the release tag from the trailing YAML comment of a SHA-pinned
entry (`owner/repo#<sha> # v2.0.0`) - which the structured parse strips -
so it extracts as a digest (`currentDigest` + `currentValue`) and updates
both via `pinDigests`, mirroring the github-actions manager. A bare SHA
with no tag comment (or a quoted form we can't rewrite verbatim) is left
skipped.
* fix(manager/apm): map SHA-pin tag recovery per line to handle duplicates
The raw-manifest scan matched the first line for the entry regardless of
section, so the same `owner/repo#<sha>` pinned in both `dependencies` and
`devDependencies` resolved to the first line's tag/replaceString. Consume
each line at most once (in file order) so duplicate pins map to distinct
lines.
* fix(manager/apm): recognize `.chatmode.md` virtual files
APM's VIRTUAL_FILE_EXTENSIONS includes `.chatmode.md`; add it to the
subpath-boundary regex so a `*.chatmode.md` virtual dependency on a
nested-group host (GitLab, Azure DevOps) is not folded into the repo path.
* test(manager/apm): cover SHA-pin digest updates on git-tags hosts
Lock in that a SHA-pinned dep on a non-github/gitlab host resolves via the
git-tags datasource (which supports `getDigest` through `git ls-remote`),
so the commit is preserved on a bump rather than dropped.
* fix(manager/apm): commit regenerated harness files, not just the lockfile
`apm install` re-deploys the harness directories APM consumers commit
(`.github/`, `.claude/`, ...), but updateArtifacts only returned
`apm.lock.yaml`, leaving instruction files stale after a bump. Capture
every file the install changed via `getRepoStatus` (additions +
deletions); the gitignored `apm_modules/` cache is excluded, and the
manifest stays with `updatedPackageFiles`.
* fix(manager/apm): declare lockFileMaintenanceIsDelegatedToPackageManager
main now requires managers with `supportsLockFileMaintenance` to set this
field. apm regenerates the lockfile via `apm install`, so it delegates to
the package manager (`true`).
* refactor(manager/apm): reuse shared regex and git-sha helpers
Adopt the shared utilities per review:
- use the exported `newlineRegex` from `util/regex` instead of a local copy
- use `isLongCommitSha` from `util/schema-utils/git` instead of a bespoke
SHA regex
- filter path segments with `isTruthy` instead of `Boolean`
* test(manager/apm): align docker exec snapshot with current base-image wrapper
The shared `util/exec` docker wrapper now injects `-e CI` and single-quotes
the `bash -l -c` payload. Update the docker-mode expectation to match, so the
snapshot tracks the current wrapper output.
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
* refactor(linters): add prefer-coerce-array rule
Refs #45217
`x ?? []` and `coerceArray(x)` say the same thing, but only the second
one is searchable and consistent. The rule flags a `??` whose default is
a bare `[]` literal; a non-empty default or an asserted `([] as Foo[])`
still passes.
Applying it across `lib/` surfaced three spots the helper cannot cover,
which keep `?? []` with a disable comment or a narrower fix:
- `package-files.ts` destructures a tuple, which `coerceArray()` widens
- `generate.spec.ts` defaults `matchAll()`, an iterator rather than an array
- `mise/upgradeable-tooling.ts` declares a `Record` return, so its
`?? []` fallback was wrong to begin with and becomes `coerceObject()`
* refactor(platform/github): hoist the GHE version header lookup
`Object.entries(...).find()` returns a tuple, and defaulting it with
`?? []` only to destructure the second element reads as an array
default when it is not one. Name the found entry instead, which drops
the `?? []` rather than routing a tuple through `coerceArray()`.
* 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>
* feat(deps): update ghcr.io/renovatebot/base-image docker tag to v13.84.0
| datasource | package | from | to |
| ---------- | ------------------------------ | ------- | ------- |
| docker | ghcr.io/renovatebot/base-image | 13.83.0 | 13.84.0 |
* feat(util/exec): add support for `gh` tool
As a prerequisite for #44753 and #45190, we need to support the `gh`
CLI.
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Enable no-else-return (with allowElseIf: false) and unicorn/no-lonely-if
as errors in .oxlintrc.json and fix all 131 pre-existing violations
(91 no-else-return, 40 unicorn/no-lonely-if) across 98 files.
The no-else-return violations were fixed with the oxlint autofix
(iterated to a fixpoint, plus two else-if chains that required
--fix-dangerously) followed by Prettier formatting. One comment dropped
by the autofix in lib/modules/manager/pub/artifacts.ts was restored
manually. The unicorn/no-lonely-if violations were merged by hand,
preserving comments and coverage-ignore hints.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
As noted in #43489, it's not currently possible to install the nightly
variant of Rust.
Although Containerbase does have support for `install-tool rust nightly`
it never gets that far, as the version lookup occurs through the
`docker` datasource.
We can instead make sure we move to the `rust-version` datasource and
its associated `rust-release-channel` versioning.
The result from the `rust-release-channel` returns a version like
`nightly-2026-06-19`, which needs extra handling in Containerbase.
We can also update **??** what supported Rust versions we'd accept.
* feat(mise): add lock file support
- Add lockfile.ts with getLockFileName() for deriving lock file paths
- Add artifacts.ts with updateArtifacts() and updateLockedDependency()
- Add MiseLockFile Zod schema for parsing lock files
- Update extract.ts to be async and extract lockedVersion from lock files
- Export supportsLockFileMaintenance, lockFileNames, updateArtifacts, updateLockedDependency
* refactor(mise): remove redundant comments
Remove comments that simply restate what the code already clearly
communicates. Keep valuable comments that explain non-obvious behavior
(e.g., why temporary errors are rethrown) and move helpful examples
into JSDoc comments.
* fix(mise): improve lock file version lookup and add tests
- Fix lock file key lookup for non-registry tools (aqua:, ubi:, etc.)
Registry tools use short names (node), non-registry use full names
(aqua:cli/cli). New getLockedVersion() tries both patterns.
- Add injection prevention test for shell quoting
- Add update-failed test for error handling
- Add comprehensive tests for getLockedVersion()
- Add null check for depName in updateLockedDependency
- Add JSDoc to updateArtifacts and extractPackageFile
- Add lock file support documentation to README
- Remove code duplication by consolidating into lockfile.ts
* fix(mise): pass --local flag and MISE_ENV for env/local config files
When updating mise.local.toml, `mise lock` updates mise.lock, not
mise.local.lock. Add --local flag to target the correct lock file.
For env-specific configs (mise.test.toml), set MISE_ENV=test so mise
reads and locks the correct configuration.
Extracted getConfigType() from getLockFileName() to share the parsing
logic between lock file name derivation and command flag generation.
Builds on #42099 by altendky.
* test(mise): cover tool absent from lock file
* refactor(mise): remove dead branches in extractPackageFile
tools is required by MiseFile schema so if(tools) is always true.
depName is always set by createDependency so if(dep.depName) is always true.
Add test for tool absent from lock file to cover the lockedVersion
assignment branch.
* fix(mise): address review feedback on lock file support
* fix(mise): remove unsupported tool constraint
* fix(mise): add containerbase tool definition
* fix(mise): add typed exec constraint support
* fix(config): restore requireConfig typing
* test(mise): await registry extraction cases
* Update lib/modules/manager/mise/artifacts.ts
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* fix: revert unrelated types cleanup
* fix: drop missing VersioningName import
* fix(mise): use npm versioning string after import removal
* test(mise): set binarySource=global in artifacts spec
GlobalConfig.get now returns defaults; without explicit binarySource the
test fell into containerbase dynamic install and tried to resolve the
mise version via the github-releases datasource, causing missing HTTP
mock errors. Force binarySource=global so the spec only exercises the
mocked exec path.
---------
Co-authored-by: Kyle Altendorf <sda@fstab.net>
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Jamie Tanna <jamie.tanna@mend.io>
* feat(manager/renovate-config): extract `constraints`
As noted in #41571, it would be useful to detect and suggest updates
when specifying `constraints` in Renovate config, where it's a known
tool we provide versioning information for.
We can extend our existing `renovate-config` manager to add support for
`constraints` that are known Containerbase tools.
We can support top-level `constraints` as well as `constraints` inside
`packageRules`.
* refactor(renovate-config): remove nesting
* fix(validation): validate `constraints`
To provide better coverage for our users of what is a valid option for a
`constraints` value, we can validate the overall format of the
`constraints` block, as well as the given names of constraints.
Where we have a Tool defined, we can use the default versioning for that
Tool to validate the constraint's value.
For now, both the validation of the `constraints`' value, and the
validation of `constraints`' names will be a warning, but in the future
may be made an error.
* chore(validation): remove check for `compatibility`
As this was renamed in #7308. It's been long enough since then that we
can remove this check.
* chore(validation): add logger in `else` case
For coverage fix, and also to provide insight when this does happen
* fixup! chore(validation): add logger in `else` case
* fixup! chore(validation): add logger in `else` case
* key
* coverage
* Remove duplicate function
As it's been pulled in via another PR.
* fixup! docs(constraints): document the possible `constraints` and `installTools` (#42837)
As it can't be `undefined`.
* test: coverage
And more whitespace to make it clearer they're two separate `if` blocks.
* typo
* typo
---------
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
* docs(constraints): list the possible `constraints` and `installTools`
Now we have a stronger type for what a valid tool constraint is, and
what additional constraints are, we should be very explicit with what
each option is, and specify them in the `constraints` as well as our
`installTools` docs.
* test: add coverage
Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
---------
Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
* chore(types): add a strong type for `ToolName`s
Until #41849, we can use our local definitions of the tool names that
Containerbase supports by extracting out a `ToolName` type.
* fixup! chore(types): add a strong type for `ToolName`s
Co-authored-by: Claude Opus 4.6 <jamie.tanna+claude-code@mend.io>
Co-authored-by: gpt-4.1 <jamie.tanna+github-copilot@mend.io>
* fixup! fixup! chore(types): add a strong type for `ToolName`s
* no-never
* simplify
* coverage
* sq
* warn
* sq
* fixup! sq
* sq
* fixup! sq
---------
Co-authored-by: Claude Opus 4.6 <jamie.tanna+claude-code@mend.io>
Co-authored-by: gpt-4.1 <jamie.tanna+github-copilot@mend.io>
* feat(exec): register bazelisk as containerbase tool
* test(bazel-module): add failing tests for updateArtifacts
* feat(bazel-module): implement updateArtifacts for lockfile support
* feat(bazel-module): export updateArtifacts from manager index
* fix(bazel-module): address code review feedback
- Use logger.warn instead of debug for artifact errors
- Add utf8 encoding to readLocalFile calls
- Use getSiblingFileName for lockfile path derivation
- Add empty updatedDeps guard
- Strengthen test assertions
* docs(bazel-module): document lockfile support
* Update lib/modules/manager/bazel-module/index.ts
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* Apply suggestions from code review
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* fix(bazel-module): address review feedback
- Remove unnecessary afterEach in tests
- Use partial<StatusResult> for all StatusResult mocks
- Add lockfile maintenance support
- Export supportsLockFileMaintenance flag
* fix(bazel-module): handle untracked lock files and clarify docs
Check status.not_added alongside status.modified for lock file changes,
matching the pattern used by other managers (composer, gomod, etc.).
Clarify that Bazelisk (not Renovate) reads .bazelversion. Add test for
lockfile maintenance with no changes.
* feat(bazelisk): implement updateArtifacts for MODULE.bazel.lock
When the Bazel version in .bazelversion changes, run `bazel mod deps` to
regenerate MODULE.bazel.lock and return the updated lockfile as an artifact.
* feat(bazelisk): add lockfile maintenance support
* docs(bazelisk): add lockfile support section linking to bazel-module docs
* refactor(bazel-module): extract shared lockfile update helper
* refactor(bazel-module): delegate lockfile update to shared helper
Replace inline lockfile update logic in artifacts.ts with a call to the
shared updateBazelLockfile() helper, and update tests to mock the helper.
* refactor(bazelisk): delegate lockfile update to shared helper
Replace inline lockfile update logic in bazelisk/artifacts.ts with a
call to the shared updateBazelLockfile() helper from bazel-module/lockfile.ts.
* fix(bazelisk): use index.md for cross-manager docs link
The docs pipeline renames readme.md to index.md, so cross-manager
links must reference index.md to pass the docs link checker.
* feat(bazel-module,bazelisk): support bazelisk version constraint
Pass config.constraints.bazelisk through to toolConstraints so users
can pin the bazelisk version if the newest release is broken.
* fix(bazel-module): rename lockFile to fileName in ArtifactError
Upstream renamed lockFile to fileName in ArtifactError type (#41631).
---------
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
After recent changes to remove `shell: true`, it's clear from #40231
that this breaks Containerbase's installing of tools, as we use the
`hash` shell built-in.
As we no longer need the `hash` call, we can remove it.