Skip to content

Buf Gradle Plugin#

The Buf Gradle Plugin runs the Buf CLI as part of a Gradle build, contributing six tasks (bufLint, bufFormatCheck, bufFormatApply, bufBuild, bufBreaking, bufGenerate) and wiring them into the build’s check, source sets, and Maven publishing.

You could call the Buf CLI from a raw Exec task; the plugin’s value is that it integrates with Gradle’s existing surfaces, including running on check, publishing schema images as Maven artifacts, and adding generated source roots to the right source set.

Install#

Apply the plugin from the Gradle Plugin Portal:

build.gradle.kts
plugins {
    id("build.buf") version "<version>"
}

The examples on this page use the Kotlin DSL (build.gradle.kts); the plugin also works with the Groovy DSL (build.gradle).

Configure#

By default, the plugin reads buf.yaml from the project root. To put it elsewhere, set configFileLocation:

buf {
    configFileLocation = rootProject.file("buf.yaml")
}

Pin the Buf CLI version with toolVersion:

buf {
    toolVersion = "<version>"
}

Tasks#

Task Purpose Wired into
bufLint Lint Protobuf sources. check
bufFormatCheck Verify Protobuf sources are formatted. check (when enforceFormat = true)
bufFormatApply Format Protobuf sources in place. (manual)
bufBreaking Detect breaking changes against a previous schema. (manual; see below)
bufGenerate Generate code from Protobuf sources. (manual; usually a dependsOn on compileJava)

Run any task with ./gradlew <task> or gradle <task>.

bufFormatApply / bufFormatCheck#

bufFormatApply formats Protobuf files in place; it has no configuration.

bufFormatCheck runs as part of check when enforceFormat is set:

buf {
    enforceFormat = true // true by default
}

bufLint#

bufLint lints every .proto file under the project’s buf.yaml and runs as part of check. Configure rules in buf.yaml.

bufBreaking#

bufBreaking needs a previous version of the schema to compare against. The plugin resolves that previous version through Maven: it builds the current schema as a Buf image, publishes the image as a Maven artifact, and on later builds resolves a published version of the same artifact for comparison. This is what enables the breaking-change check to work without a buildable Protobuf checkout sitting on disk.

Check against the latest published schema#

Enable publishSchema to publish the image, then checkSchemaAgainstLatestRelease to resolve the most recent published version on each build. Schema artifacts publish through Gradle’s normal publishing { repositories { ... } } configuration, with whatever auth the target repository requires.

buf {
    publishSchema = true
    checkSchemaAgainstLatestRelease = true
}

When bufBreaking detects an incompatibility, the build fails:

> 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.

Check against a static version#

To pin the comparison to a specific previous version, set previousVersion instead:

buf {
    publishSchema = true

    // Always compare against version 0.1.0
    previousVersion = "0.1.0"
}

Artifact details#

By default the published image artifact inherits its coordinates from an existing Maven publication. If no publication exists, more than one exists, or you want to set the coordinates explicitly:

buf {
    publishSchema = true

    imageArtifact {
        groupId = rootProject.group.toString()
        artifactId = "custom-artifact-id"
        version = rootProject.version.toString()
    }
}

bufGenerate#

bufGenerate reads buf.gen.yaml from the project root and writes the generated code under "$buildDir/bufbuild/generated/<out path from buf.gen.yaml>". For full configuration, see the code generation overview.

A minimal Java example using a remote plugin:

buf.gen.yaml
version: v2
plugins:
  - remote: buf.build/protocolbuffers/java
    out: java

To use the generated code in your build, register the output as a source directory and run bufGenerate before compileJava:

build.gradle.kts
import build.buf.gradle.GENERATED_DIR

plugins {
    `java`
    id("build.buf") version "<version>"
}

tasks.named("compileJava").configure { dependsOn("bufGenerate") }

sourceSets["main"].java { srcDir("$buildDir/bufbuild/$GENERATED_DIR/java") }

repositories { mavenCentral() }

dependencies {
    implementation("com.google.protobuf:protobuf-java:<protobuf version>")
}

$buildDir is a deprecated Gradle property; current Gradle style is layout.buildDirectory. The plugin’s existing constants and examples still use $buildDir, so the snippet above stays consistent with upstream.

Generating for dependencies#

To generate code for the schema dependencies as well as its own files, set includeImports:

build.gradle.kts
buf {
    generate {
        includeImports = true
    }
}

This reads dependencies from buf.lock, so buf.yaml must declare BSR dependencies and buf.lock must be up to date (buf dep update).

Override the buf.gen.yaml location#

build.gradle.kts
buf {
    generate {
        templateFileLocation = rootProject.file("subdir/buf.gen.yaml")
    }
}

Further reading#