This project provides support for integrating Buf with Gradle. It also enables integration with the Protobuf Gradle plugin (Note: the buf-gradle-plugin is compatible with protobuf-gradle-plugin versions >= 0.9.2).
This plugin supports straightforward usage of buf lint, buf format, and buf generate, and a self-contained integration between buf build and buf breaking.
This plugin assumes that Buf is configured for the project root with a configured buf.yaml, and instructions for setting up a Buf workspace can be found in the Buf docs.
The plugin can also be used without specifying a buf.yaml, in which case the plugin will scan all top-level directories for Protobuf sources.
If the project includes the protobuf-gradle-plugin, this plugin will use an implicit Buf workspace that includes the following:
- All specified Protobuf source directories
- The
includedependencies that theprotobuf-gradle-pluginextracts into$buildDir/extracted-include-protos - The dependencies that the
protobuf-gradle-pluginhas been told to generate which are extracted into$buildDir/extracted-protos
This plugin does not support usage of both a Buf workspace and the protobuf-gradle-plugin because dependency resolution would be complicated and error-prone.
Apply the plugin:
plugins {
id("build.buf") version "<version>"
}or
buildscript {
dependencies {
classpath("build.buf:buf-gradle-plugin:<version>")
}
}
apply(plugin = "build.buf")When applied, the plugin creates the following tasks:
bufFormatApplyappliesbuf formatbufFormatCheckvalidatesbuf formatbufLintvalidatesbuf lintbufBuildbuilds an image withbuf buildbufBreakingchecks Protobuf schemas against a previous version for backwards-incompatible changes throughbuf breakingbufGenerategenerates Protobuf code withbuf generate
Each integration test in this project is an example usage.
For a basic Buf project or one that uses the protobuf-gradle-plugin, you can create a Buf configuration file in the project directory:
# buf.yaml
version: v2
lint:
ignore:
- path/to/dir/to/ignore
use:
- DEFAULTAs an alternative to a buf.yaml file in the project directory, you can specify the location of a buf.yaml by configuring the extension:
buf {
configFileLocation = rootProject.file("buf.yaml")
}Or you can share a Buf configuration across projects and specify it via the dedicated buf configuration:
dependencies {
buf("build.buf:shared-buf-configuration:0.1.0")
}As an example, here's the setup for a shared-buf-configuration project:
shared-buf-configuration % tree
.
├── build.gradle.kts
└── buf.yaml
// build.gradle.kts
plugins {
`maven-publish`
}
publishing {
publications {
create<MavenPublication>("bufconfig") {
groupId = "build.buf"
artifactId = "shared-buf-configuration"
version = "0.1.0"
artifact(file("buf.yaml"))
}
}
}Projects with Buf workspaces must configure their workspaces as described in the Buf documentation; no configuration for linting will be overrideable. A buf.yaml in the project root or specified in the extension will be used for breakage checks only.
If your buf.yaml declares any dependencies using the deps key, you must run buf mod update to create a buf.lock file manually. The buf-gradle-plugin does not (yet) support creating the dependency lock file.
bufGenerate is configured as described in the Buf docs. Create a buf.gen.yaml in the project root and bufGenerate will generate code in the project's build directory at "$buildDir/bufbuild/generated/<out path from buf.gen.yaml>".
An example, for Java code generation using the remote plugin:
version: v2
plugins:
- plugin: buf.build/protocolbuffers/java:<version>
out: javaIf you want to use generated code in your build, you must add the generated code as a source directory and configure a task dependency to ensure code is generated before compilation:
// build.gradle.kts
import build.buf.gradle.GENERATED_DIR
plugins {
`java`
id("build.buf") version "<version>"
}
// Add a task dependency for compilation
tasks.named("compileJava").configure { dependsOn("bufGenerate") }
// Add the generated code to the main source set
sourceSets["main"].java { srcDir("$buildDir/bufbuild/$GENERATED_DIR/java") }
// Configure dependencies for protobuf-java:
repositories { mavenCentral() }
dependencies {
implementation("com.google.protobuf:protobuf-java:<protobuf version>")
}If you'd like to generate code for your dependencies, configure the bufGenerate task:
// build.gradle.kts
buf {
generate {
includeImports = true
}
}Ensure you have an up-to-date buf.lock file generated by buf mod update or this generation will fail.
By default, bufGenerate will read the buf.gen.yaml template file from the project root directory. You can override the location of the template file:
// build.gradle.kts
buf {
generate {
templateFileLocation = rootProject.file("subdir/buf.gen.yaml")
}
}bufFormatApply is run manually and has no configuration.
bufFormatCheck is run automatically during the check task if enforceFormat is enabled. It has no other configuration.
buf {
enforceFormat = true // True by default
}bufLint is configured by creating buf.yaml in basic projects or projects using the protobuf-gradle-plugin. It is run automatically during the check task. Specification of buf.yaml is not supported for projects using a workspace.
bufBuild is configured with the build closure:
buf {
build {
imageFormat = ImageFormat.JSON // JSON by default
compressionFormat = CompressionFormat.GZ // null by default (no compression)
}
}Available image formats are:
binpbbinjsontxtpb
Available compression formats are:
gzzst
The file is built in the bufbuild directory in the project's build directory and has the name image followed by
the image format and optionally the compression format, e.g. build/bufbuild/image.bin.zst.
bufBreaking is more complicated since it requires a previous version of the Protobuf schema to validate the current version. Buf's built-in git integration isn't quite enough since it requires a buildable Protobuf source set, and the protobuf-gradle-plugin's extraction step typically targets the project build directory which is ephemeral and is not committed.
This plugin uses buf build to create an image from the current Protobuf schema and publishes it as a Maven publication. In subsequent builds of the project, the plugin will resolve the previously published schema image and run buf breaking against the current schema with the image as its reference.
Enable checkSchemaAgainstLatestRelease and the plugin will resolve the previously published Maven artifact as its input for validation.
For example, first publish the project with publishSchema enabled:
buf {
publishSchema = true
}Then configure the plugin to check the schema:
buf {
// Continue to publish the schema
publishSchema = true
checkSchemaAgainstLatestRelease = true
}The plugin will run Buf to validate the project's current schema:
> Task :bufBreaking FAILED
src/main/proto/buf/service/test/test.proto:9:1:Previously present field "1" with name "test_content" on message "TestMessage" was deleted.
If for some reason you do not want to dynamically check against the latest published version of your schema, you can specify a constant version with previousVersion:
buf {
// Continue to publish the schema
publishSchema = true
// Will always check against version 0.1.0
previousVersion = "0.1.0"
}By default, the published image artifact will infer its details from an existing Maven publication if one exists. If one doesn't exist, you have more than one, or you'd like to specify the details yourself, you can configure them:
buf {
publishSchema = true
imageArtifact {
groupId = rootProject.group.toString()
artifactId = "custom-artifact-id"
version = rootProject.version.toString()
}
}The version of Buf used can be configured using the toolVersion property on the extension:
buf {
toolVersion = <version>
}We'd love your help making this plugin better!
Extensive instructions for building the plugin locally,
running tests, and contributing to the repository are available in our
CONTRIBUTING.md guide.
- connect-kotlin: Kotlin clients for idiomatic gRPC & Connect RPC
- connect-es: Type-safe APIs with Protobuf and TypeScript.
- connect-go: Service handlers and clients for GoLang
- Buf Studio: Web UI for ad-hoc RPCs
This project is in beta, and we may make a few changes as we gather feedback from early adopters. Join us on Slack!
Offered under the Apache 2 license.