Today we're excited to release Bazel rules for buf
, rules_buf.
Bazel is a scalable multi-language build tool for large projects that focuses on reproducibility and speed. This resonates strongly at Buf where we help teams develop robust, language agnostic, scalable APIs.
The rules work alongside the proto_library
rule of rules_proto.
Managing dependencies
The buf_dependencies
repository rule helps manage Protobuf
dependencies
using the Buf Schema Registry (BSR).
Here's a small example that demonstrates using the rule to gather dependencies into a
target called buf_deps
.
load("@rules_buf//buf:defs.bzl", "buf_dependencies")
buf_dependencies(
name = "buf_deps",
modules = [
"buf.build/envoyproxy/protoc-gen-validate:dc09a417d27241f7b069feae2cd74a0e",
"buf.build/acme/petapis:84a33a06f0954823a6f2a089fb1bb82e",
],
)
This can now be used as part of the deps
attribute in the proto_library
rule like this,
load("@rules_proto//proto:defs.bzl", "proto_library")
proto_library(
name = "foo_proto",
srcs = [
"pet.proto" # imports "validate/validate.proto"
],
deps = [
"@buf_deps//validate:validate_proto"
],
)
You can read more about this in the docs.
Lint and Breaking Checks
buf lint
and buf breaking
are widely used to ensure quality standards of Protobuf
APIs are met.
Now, you can use them within Bazel. Here's an example,
Breaking rule
load("@rules_buf//buf:defs.bzl", "buf_breaking_test")
exports_files(["buf.yaml"])
buf_breaking_test(
name = "foo_proto_breaking",
against = "//:image.bin", # The Image file to check against.
targets = ["//foo/v1:foo_proto"], # The Protobuf library targets to check
config = ":buf.yaml",
)
Running bazel test --test_output=errors //:foo_proto_breaking
will print the errors,
...
Executing tests from //:foo_proto_breaking
-----------------------------------------------------------------------------
--buf-plugin_out: foo/v1/foo.proto:1:1:Field "3" with name "Bar" on message "Foo" changed option "json_name" from "bar" to "Bar".
foo/v1/foo.proto:1:1:Field "3" on message "Foo" changed name from "bar" to "Bar".
Lint rule
load("@rules_buf//buf:defs.bzl", "buf_lint_test")
load("@rules_proto//proto:defs.bzl", "proto_library")
proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
)
buf_lint_test(
name = "foo_proto_lint",
targets = [":foo_proto"],
config = "//:buf.yaml",
)
Running bazel test --test_output=errors //foo/v1:foo_proto_lint
will print the errors,
...
Executing tests from //foo/v1:foo_proto_lint
-----------------------------------------------------------------------------
--buf-plugin_out: foo/v1/foo.proto:1:1:Field name "Bar" should be lower_snake_case, such as "bar".
For more on these rules check out the docs for buf_lint_test and buf_breaking_test
Generate rules
At Buf we are strong believers of automation and hence we couldn't resist developing a Gazelle extension.
The extension can be used to generate all of above rules! It understands both buf.work.yaml
and buf.yaml
configuration files.
Check out the Gazelle section of the docs for setup and usage instructions.
Next steps
Get started by setting up rules_buf
or check out the examples illustrating various scenarios.