Files
renovate/docs/usage/bazel.md
Tim Tran 2f71422620 feat(bazel-module,bazelisk): add lock files updating (#41507)
* 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>
2026-03-12 16:40:24 +00:00

276 lines
9.0 KiB
Markdown

---
title: Bazel
description: Bazel dependencies support in Renovate
---
# Bazel
Renovate upgrades dependencies in Bazel `WORKSPACE` files and `MODULE.bazel` files.
## How it works
1. Bazel support is enabled automatically
1. Renovate searches the repository for any `WORKSPACE` and `MODULE.bazel` files
1. Renovate extracts the dependencies it finds from the files (see below for the supported dependency declarations)
1. Renovate updates old dependencies to the latest version
## Bazel module (`MODULE.bazel`) support
### Bazel registry discovery
Renovate searches [Bazel registries](https://bazel.build/external/registry) to find new Bazel module versions.
You customize the registries your Bazel workspace uses by including [`--registry`](https://bazel.build/reference/command-line-reference#flag--registry) entries in your [`.bazelrc` files](https://bazel.build/run/bazelrc).
Renovate checks the workspace's `.bazelrc` files for custom registry entries.
If no registries are found, Renovate defaults to the [Bazel Central Registry](https://bcr.bazel.build/).
Here are some important points about Renovate's Bazel registry searches.
Renovate:
- uses _all_ `--registry` values found in a workspace's `.bazelrc` file
- uses any files that are transitively imported by a `.bazelrc` file
- only uses `--registry` values that are not associated with [a configuration](https://bazel.build/run/bazelrc#config)
- queries the registries in the order that they are found in the `.bazelrc` file
#### Example: multiple `.bazelrc` files
In this example, there is a `.bazelrc` file which imports another file called `.registry.bazelrc`.
Both files have `--registry` values:
```title=".bazelrc"
import .registry.bazelrc
build --registry=https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main
```
```title=".registry.bazelrc"
build --registry=https://example.com/custom_registry
```
The final registry list is:
1. `<https://example.com/custom_registry>`
1. `<https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main>`
#### Example: registry entries using Bazel configuration
In this example, a `.bazelrc` file has registry values with and without a configuration:
```title=".bazelrc"
build:ci --registry=https://internal.server/custom_registry
build --registry=https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main
```
In this case the `https://internal.server/custom_registry` is ignored.
The final registry list is:
1. `<https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main>`
### Supported Bazel module declarations
#### `bazel_dep`
Renovate updates the `version` value for a [`bazel_dep`](https://bazel.build/rules/lib/globals/module#bazel_dep) declaration.
```python
bazel_dep(name = "cgrindel_bazel_starlib", version = "0.15.0")
```
In the example above, Renovate evaluates the `0.15.0` version against the repository's registries.
If Renovate finds a newer version, it updates `0.15.0` to match that version.
#### `git_override`
If Renovate finds a [`git_override`](https://bazel.build/rules/lib/globals/module#git_override), it ignores the related `bazel_dep` entry and instead evaluates the `commit` value at the specified `remote`.
When using `git_override`, the `version` parameter on the `bazel_dep` is optional.
```python
bazel_dep(name = "cgrindel_bazel_starlib", version = "0.15.0")
git_override(
module_name = "cgrindel_bazel_starlib",
commit = "fb47f0e9f7c376a7700fc9fe3319231ae57880df",
remote = "https://github.com/cgrindel/bazel-starlib.git",
)
bazel_dep(name = "rules_foo")
git_override(
module_name = "rules_foo",
remote = "https://github.com/foo/rules_foo.git",
commit = "8a1e9abe415eda7cd7f2a744fdac7499ce42cdca",
)
```
If the primary branch has a newer commit than in the list, Renovate updates the `commit` value.
#### `single_version_override`
The [`single_version_override`](https://bazel.build/rules/lib/globals/module#single_version_override) is a declaration with many purposes.
Renovate only evaluates _two_ attributes from this declaration: `version` and `registry`.
If a `version` is specified, it overrides the version in the `bazel_dep`.
In the following example, Renovate notices that the version is pinned to `1.2.3`.
This results in `rules_foo` being ignored for update evaluation.
When using `single_version_override`, the `version` parameter on the `bazel_dep` is optional.
```python
bazel_dep(name = "rules_foo", version = "1.2.4")
single_version_override(
module_name = "rules_foo",
version = "1.2.3",
)
bazel_dep(name = "rules_bar")
single_version_override(
module_name = "rules_bar",
version = "1.2.3",
)
```
If a `registry` is specified, Renovate uses the specified registry URL to check for a new version.
In the following example, Renovate only uses the `https://example.com/custom_registry` registry to discover `rules_foo` versions.
Any registry values specified in the repository's `.bazelrc` files are ignored for the `rules_foo` module.
```python
bazel_dep(name = "rules_foo", version = "1.2.3")
single_version_override(
module_name = "rules_foo",
registry = "https://example.com/custom_registry",
)
```
#### `archive_override` and `local_path_override`
If Renovate finds an [`archive_override`](https://bazel.build/rules/lib/globals/module#archive_override) or a [`local_path_override`](https://bazel.build/rules/lib/globals/module#local_path_override), it ignores the related `bazel_dep`.
Because these declarations lack versionable attributes, Renovate does not update them.
When using `archive_override` and `local_path_override`, the `version` parameter on the `bazel_dep` is optional.
```python
bazel_dep(name = "rules_foo", version = "1.2.3")
archive_override(
module_name = "rules_foo",
urls = [
"https://example.com/archive.tar.gz",
],
)
bazel_dep(name = "rules_bar")
archive_override(
module_name = "rules_bar",
urls = [
"https://example.com/archive.tar.gz",
],
)
```
#### `multiple_version_override`
Renovate ignores [`multiple_version_override`](https://bazel.build/rules/lib/globals/module#multiple_version_override).
`multiple_version_override` does not affect the processing of version updates for a module.
### Lockfile support
Renovate updates the `MODULE.bazel.lock` file after modifying dependencies in `MODULE.bazel`.
When Renovate changes a `bazel_dep` version, it runs `bazel mod deps` to regenerate the lockfile.
For this to work:
1. Your repository must already have a `MODULE.bazel.lock` file
1. [Bazelisk](https://github.com/bazelbuild/bazelisk) must be available in the environment, or Renovate must be configured to install tools via containerbase (`binarySource=install`)
Renovate uses Bazelisk, which determines the correct Bazel version from the `.bazelversion` file in your repository.
If no `MODULE.bazel.lock` file exists, Renovate skips the lockfile update step.
### `git_repository`
If Renovate finds a [`git_repository`](https://bazel.build/rules/lib/repo/git#git_repository), it evaluates the `commit` value at the specified `remote`.
`remote` is limited to github repos: `https://github.com/<owner>/<repo>.git`
```python
git_repository(
name = "rules_foo",
remote = "https://github.com/fooexample/rules_foo.git",
commit = "8c94e11c2b05b6f25ced5f23cd07d0cfd36edc1a",
)
```
## Legacy `WORKSPACE` files
Renovate extracts dependencies from the following repository rules:
- `container_pull`
- `oci_pull`
- `git_repository`
- `go_repository`
- `maven_install`
- `http_archive`
- `http_file`
It also recognizes when these repository rule names are prefixed with an underscore.
For example, `_http_archive` is treated the same as `http_archive`.
### `git_repository` (legacy)
Renovate updates any `git_repository` declaration that has the following:
1. `name`
1. `remote` matching `https://github.com/<owner>/<repo>.git`
1. `tag` using a valid SemVer
e.g.:
```
git_repository(
name = "build_bazel_rules_typescript",
remote = "https://github.com/bazelbuild/rules_typescript.git",
tag = "0.6.1",
)
```
Renovate uses the list of **tags** on the remote repository (GitHub) to detect a new version.
### `http_archive` and `http_file`
Renovate updates any `http_archive` or `http_file` declaration that has the following:
1. `name`
1. `url` matching `https://github.com/<owner>/<repo>/releases/download/<semver>/<repo>.tar.gz`
1. `sha256`
e.g.:
```
http_archive(
name = "io_bazel_rules_go",
url = "https://github.com/bazelbuild/rules_go/releases/download/0.7.1/rules_go-0.7.1.tar.gz",
sha256 = "341d5eacef704415386974bc82a1783a8b7ffbff2ab6ba02375e1ca20d9b031c",
)
```
Renovate uses the list of **releases** that it finds at the `url` to detect a new version.
### `maven_install`
By default, Maven dependencies are extracted in the context of Gradle versioning scheme.
To change it, configure `packageRules` like this:
```json
{
"packageRules": [
{
"matchManagers": ["bazel"],
"matchDatasources": ["maven"],
"versioning": "maven"
}
]
}
```
## Future work
We welcome contributions or feature requests to support more patterns or use cases.