Skip to content

Build, format, lint, and check for breaking changes in your Protobuf schemas, and automatically publish to the Buf Schema Registry.

License

Notifications You must be signed in to change notification settings

bufbuild/buf-action

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

The Buf logo

buf-action

ci slack

This GitHub action makes it easy to run buf within a workflow to check for build, lint, format, and breaking change errors, as well as to automatically publish schema changes to the Buf Schema Registry (BSR).

Annotations example for lint and breaking changes

Usage

To use this action with the recommended default behavior, create a new .github/workflows/buf-ci.yaml file in your repository with the following content:

name: Buf CI
on:
  push:
  pull_request:
    types: [opened, synchronize, reopened, labeled, unlabeled]
  delete:
permissions:
  contents: read
  pull-requests: write
jobs:
  buf:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: bufbuild/buf-action@v1
        with:
          token: ${{ secrets.BUF_TOKEN }}

Default behavior

When you push a Git commit, tag, or branch to GitHub, the action will push named modules to the BSR using buf push.

On a pull request, the action will run all checks (using buf build, buf lint, buf format, buf breaking) and then post a summary comment on the PR.

When you delete a Git branch or tag, the action will archive the corresponding label on the BSR.

Configuration

To customize the behavior of the action, you can set the following parameters in the workflow file. Add these parameters under the with section of the uses step in the workflow file.

- uses: bufbuild/buf-action@v1
  with:
    ...
Parameter Description Default
version Version of the buf CLI to use. Latest version
token API token for logging into the BSR.
domain Domain for logging into the BSR, enterprise only. buf.build
input Input for the buf command.
paths Limit to specific files or directories (separated by newlines).
exclude_imports Exclude files imported by the target modules. False
exclude_paths Exclude specific files or directories, e.g. "proto/a/a.proto", "proto/a" (separated by newlines).
pr_comment Comment the results on the pull request. The workflow and job name combination must be unique. Only on pull requests (non forks)
format Whether to run the formatting step. Runs on pushes to Git PR
lint Whether to run the linting step. Runs on pushes to Git PR
breaking Whether to run the breaking change detection step. Runs on pushes to Git PR
breaking_against Input to compare against. Base of the PR or the commit before the event
push Whether to run the push step. Runs on Git pushes (non forks)
push_disable_create Disables repository creation if it does not exist. False
archive Whether to run the archive step. Runs on Git deletes (non forks)
setup_only Setup only the buf environment, optionally logging into the BSR, but without executing other commands.
github_actor GitHub actor for API requests. Actor from GitHub context
github_token GitHub token for API requests. Ensures requests aren't rate limited Token from GitHub context

Skip the breaking change detection step

By default, the action runs the breaking change detection step on every pull request. To skip this step, add the label buf skip breaking to the PR.

Skip breaking changes example

Ensure the workflow file includes the pull_request event types labeled and unlabeled so checks re-run on label changes.

To disable the ability to skip breaking change checks via a label, set the breaking parameter to the value ${{ github.event_name == 'pull_request' }} so it runs on all PRs. See examples/disable-skip/buf-ci.yaml for an example.

Disable steps

To disable parts of the workflow, each step corresponds to a boolean flag in the parameters. For example to disable formatting set the parameter format to false:

- uses: bufbuild/buf-action@v1
  with:
    format: false

See action.yml for all available parameters.

Versioning

For reproducible builds, you can pin to an explicit version of buf by setting version.

- uses: bufbuild/buf-action@v1
  with:
    version: 1.35.0

If no version is specified in the workflow config, the action will resolve the version in order of precedence:

  • A version specified in the environment variable ${BUF_VERSION}.
  • The version of buf that is already installed on the runner (if it exists).
  • The latest version of the buf binary from the official releases on GitHub.

Authentication

Publishing schemas to the BSR provides a seamless way for consumers of your APIs to generate code. Authenticating with the BSR is required for both the push and archive label steps.

To authenticate with the BSR, set the API token as the parameter token. Generate a token from the BSR UI and add it to the repository secrets.

- uses: bufbuild/buf-action@v1
  with:
    token: ${{ secrets.BUF_TOKEN }}

For more information on authentication, see the BSR Authentication Reference.

Summary comment

The action reports the status of the most recent checks in a comment on each pull request.

Comment example showing the GitHub summary

To disable the comment, set the parameter comment to false and remove the permission pull_request: write as this is no longer required.

name: Buf CI
on:
  push:
  pull_request:
    types: [opened, synchronize, reopened, labeled, unlabeled]
  delete:
permissions:
  contents: read
- pull-requests: write
jobs:
  buf:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: bufbuild/buf-action@v1
        with:
          token: ${{ secrets.BUF_TOKEN }}
+         pr_comment: false

Specify the input directory

To run the action for parameters not declared at the root of the repository, set the parameter input to the directory of your buf.yaml file.

- uses: bufbuild/buf-action@v1
  with:
    input: <path/to/module>

Breaking change detection by default will use the input value as a subdirectory for the breaking against value. To customize this behavior, set the parameter breaking_against to the desired input.

- uses: bufbuild/buf-action@v1
  with:
    input: <path/to/module>
    breaking_against: ${{ github.event.repository.clone_url }}#format=git,commit=${{ github.event.pull_request.base.sha }},subdir=<path/to/module>

Alternatively, you can checkout the base for the breaking comparison to a local folder and then set the value of breaking_against to the path of the base.

- uses: actions/checkout@v4
  with:
    path: head
- uses: actions/checkout@v4
  with:
    path: base
    ref: ${{ github.event.pull_request.base.sha }}
- uses: bufbuild/buf-action@v1
  with:
    input: head/<path/to/module>
    breaking_against: base/<path/to/module>

For more information on inputs, see the Buf Inputs Reference.

Setup only

To only setup the action without running any commands, set the parameter setup_only to true. This will install buf and optionally login to the schema registry but no additional commands will be run. Subsequent steps will have buf available in their $PATH and can invoke buf directly.

- uses: bufbuild/buf-action@v1
  with:
    setup_only: true
- run: buf build --error-format github-actions

See the only-setup.yaml example.

Customize when steps run

To trigger steps on different events use the GitHub action context to deduce the event type. For example to enable formatting checks on both pull requests and push create an expression for the parameter format:

- uses: bufbuild/buf-action@v1
  with:
    format: ${{ contains(fromJSON('["push", "pull_request"]'), github.event_name) }}

See GitHub Actions expressions documentation.

Skip checks if commit message matches a specific pattern

To conditionally run checks based on user input, use the GitHub action context to check for the contents of the commit. For example to disable breaking change detection on commits, create an expression on the parameter breaking to check the contents of the commit message:

- uses: bufbuild/buf-action@v1
  with:
    breaking: |
      contains(fromJSON('["push", "pull_request"]'), github.event_name) &&
      !contains(github.event.head_commit.message, 'buf skip breaking')

See GitHub Actions job context documentation.

Only push on changes to APIs

To push only on changes to when your module changes, restrict the push step for any changes to buf related files. This can be achieved by using the paths filter on the push event.

push:
  paths:
    - '**.proto'
    - '**/buf.yaml'
    - '**/buf.lock'
    - '**/buf.md'
    - '**/README.md'
    - '**/LICENSE'

See the push-on-changes.yaml example.

Example workflows

Check out the examples directory for more detailed workflows.

Migrating from individual Buf actions

If you're currently using any of our individual actions (buf-setup-action, buf-breaking-action, buf-lint-action, buf-push-action), we recommend migrating to this consolidated action that has additional capabilities. Benefits to migrating include:

  • Less configuration and setup, with built-in best practices.
  • Enhanced integration with Git data when pushing to the BSR.
  • Status comments on pull requests.
  • Easy configuration for custom behavior.

Feedback and support

If you have any feedback or need support, please reach out to us on the Buf Slack, or GitHub Issues.

Status: stable

This action is stable and ready for production use.

Legal

Offered under the Apache 2 license.