
5 Tips for Managing Bazel Dependencies (Without Losing Friends) | Endor Labs
Endor Labs gives five practices for updating third-party dependencies in Bazel monorepos: update one dependency at a time, stage cross-cutting upgrades, and test incrementally. It includes bazel query rdeps examples (e.g. for the Go zap library) to select only affected go_test targets. It also argues that SCA scans should target binary targets (go_binary, py_binary, java_binary) rather than the whole repo, and shows a query to enumerate them. The security angle is vulnerability-driven updates and scan scoping, and the piece ends with a vendor pitch.
What it is
Endor Labs' guidance on updating third-party dependencies in a Bazel monorepo. Its useful content is a set of bazel query recipes for narrowing test and scan scope. The rest is process advice and a vendor pitch.
How it works
Bazel pins one version of each dependency for every target, so a bump is visible repo-wide at once. The page treats that as a benefit: the person making the update owns every breakage it causes, and nothing ships broken into another team's repo. The recipes below rely on the same graph visibility to limit what gets tested or scanned.
What to do
Test only the consumers of a bumped library. The page's example is zap in src/golang/:
bazel query 'kind("go_test", rdeps(//src/golang/..., @org_uber_go_zap//:zap))'
bazel test $(bazel query 'kind("go_test", rdeps(//src/golang/..., @org_uber_go_zap//:zap))')This covers direct and transitive consumers. To cut CI time further, cap the reverse-dependency depth:
bazel test $(bazel query 'kind("go_test", rdeps(//src/golang/..., @org_uber_go_zap//:zap, 2))')The page says depth limiting suits minor patch or non-breaking changes, where deeper transitive paths are unlikely to be affected.
Enumerate the binary target types to scan.
bazel query 'kind(".*_binary", //...)' --output=label_kind \
| awk '{print $1}' \
| sort -uThis lists the rule kinds present, such as go_binary, py_binary and java_binary. The page recommends pointing SCA at binary targets rather than the whole repo. A binary scan covers first-party libraries and all transitive third-party dependencies of the shippable artifact. The stated payoff is that it ignores dependencies not used by what you deploy, and it makes per-target scans fast enough to run on each change instead of nightly.
Process rules:
- Update one dependency at a time, so a failure can be traced to a single change and reverted cleanly.
- For cross-cutting libraries such as protobuf, stage the work as a series of scoped PRs to a branch, one set of consumers at a time.
- Consider making central dependency updates a platform or DevOps team responsibility at large scale.
- In CI, scan only targets affected by the change, not every target on every run.
Caveats
- In a small repo the page says to skip the query tricks and run all tests.
- Unit tests are the first line of defense and run locally. Integration tests often need CI-only environments.
- Depth-limited
rdepstrades coverage for speed. The page gives no guidance on choosing depth beyond "minor patch". - The page asserts that binary-target scanning cuts noise, but offers no benchmarks or numbers.
- The "affected targets only" scan strategy is described in general terms, with no command or tooling shown. The closing pitch is for Endor Labs' Bazel-native component discovery.
Technologies named here
- Endor Labs
- Bazel monorepos
- Bazel
- bazel query
- protobuf
- bazel test
- go_binary, py_binary, java_binary
- Go
Techniques named here
- Incremental testing using reverse dependencies
Related in Supply Chain


