Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/proto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
on:
push:
paths:
- 'proto/**'
- '.github/workflows/proto.yml'
pull_request:
paths:
- 'proto/**'
- '.github/workflows/proto.yml'

name: Proto
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
proto:
runs-on: ubuntu-latest
env:
BUF_VERSION: 1.55.1
PROTOC_GEN_GO_VERSION: v1.36.11
PROTOC_GEN_GO_GRPC_VERSION: v1.6.1
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch main for breaking baseline
if: github.ref != 'refs/heads/main'
run: git fetch --no-tags --prune origin +refs/heads/main:refs/remotes/origin/main
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
- name: Install buf
run: go install github.com/bufbuild/buf/cmd/buf@v${{ env.BUF_VERSION }}
- name: Install protoc-gen-go
run: go install google.golang.org/protobuf/cmd/protoc-gen-go@${{ env.PROTOC_GEN_GO_VERSION }}
- name: Install protoc-gen-go-grpc
run: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@${{ env.PROTOC_GEN_GO_GRPC_VERSION }}
- name: buf breaking (against main)
if: github.ref != 'refs/heads/main'
working-directory: proto
run: buf breaking --against '../.git#subdir=proto,ref=refs/remotes/origin/main'
- name: buf generate
working-directory: proto
run: buf generate
- name: Fail on regenerated diff
run: |
if ! git diff --exit-code -- proto/; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect untracked generated files in proto drift check

The Fail on regenerated diff step can miss missing generated artifacts because git diff --exit-code -- proto/ only compares tracked changes (index/worktree) and returns success when buf generate creates new untracked *.pb.go files. In that case CI can pass even though generation output is not fully committed (e.g., adding a new .proto file and forgetting to git add the new generated file), so this gate does not reliably enforce the intended “committed output matches generated output” invariant.

Useful? React with 👍 / 👎.

echo "::error::Generated proto files differ from committed output. Run 'make -C proto gen' and commit the result."
exit 1
fi
- name: go build
run: go build ./...
70 changes: 43 additions & 27 deletions proto/Makefile
Original file line number Diff line number Diff line change
@@ -1,39 +1,55 @@
PROTOC_VERSION := libprotoc 29.3
PROTOC_GEN_GO_VERSION := protoc-gen-go v1.36.11
PROTOC_GEN_GO_GRPC_VERSION := protoc-gen-go-grpc 1.6.1
BUF_VERSION := 1.55.1
PROTOC_GEN_GO_VERSION := 1.36.11
PROTOC_GEN_GO_GRPC_VERSION := 1.6.1

.PHONY: all gen check-tools
BUF ?= buf
BREAKING_AGAINST ?= ../.git#subdir=proto,branch=main

.PHONY: all gen check-tools breaking

all: gen

check-tools:
@if [ "$$(protoc --version)" != "$(PROTOC_VERSION)" ]; then \
echo "expected $(PROTOC_VERSION), got $$(protoc --version)"; \
@command -v $(BUF) >/dev/null 2>&1 || { \
echo "buf not found; install with:"; \
echo " go install github.com/bufbuild/buf/cmd/buf@v$(BUF_VERSION)"; \
exit 1; \
}
@installed=$$($(BUF) --version 2>/dev/null); \
if [ "$$installed" != "$(BUF_VERSION)" ]; then \
echo "buf version mismatch: expected $(BUF_VERSION), got $$installed"; \
echo "install with: go install github.com/bufbuild/buf/cmd/buf@v$(BUF_VERSION)"; \
exit 1; \
fi
@if [ "$$(protoc-gen-go --version)" != "$(PROTOC_GEN_GO_VERSION)" ]; then \
echo "expected $(PROTOC_GEN_GO_VERSION), got $$(protoc-gen-go --version)"; \
@command -v protoc-gen-go >/dev/null 2>&1 || { \
echo "protoc-gen-go not found; install with:"; \
echo " go install google.golang.org/protobuf/cmd/protoc-gen-go@v$(PROTOC_GEN_GO_VERSION)"; \
exit 1; \
}
@installed=$$(protoc-gen-go --version 2>/dev/null); \
if [ "$$installed" != "protoc-gen-go v$(PROTOC_GEN_GO_VERSION)" ]; then \
echo "protoc-gen-go version mismatch: expected v$(PROTOC_GEN_GO_VERSION), got $$installed"; \
echo "install with: go install google.golang.org/protobuf/cmd/protoc-gen-go@v$(PROTOC_GEN_GO_VERSION)"; \
exit 1; \
fi
@if [ "$$(protoc-gen-go-grpc --version)" != "$(PROTOC_GEN_GO_GRPC_VERSION)" ]; then \
echo "expected $(PROTOC_GEN_GO_GRPC_VERSION), got $$(protoc-gen-go-grpc --version)"; \
@command -v protoc-gen-go-grpc >/dev/null 2>&1 || { \
echo "protoc-gen-go-grpc not found; install with:"; \
echo " go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v$(PROTOC_GEN_GO_GRPC_VERSION)"; \
exit 1; \
}
@installed=$$(protoc-gen-go-grpc --version 2>/dev/null); \
if [ "$$installed" != "protoc-gen-go-grpc $(PROTOC_GEN_GO_GRPC_VERSION)" ]; then \
echo "protoc-gen-go-grpc version mismatch: expected $(PROTOC_GEN_GO_GRPC_VERSION), got $$installed"; \
echo "install with: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v$(PROTOC_GEN_GO_GRPC_VERSION)"; \
exit 1; \
fi

breaking: check-tools
@if git -C .. rev-parse --verify main >/dev/null 2>&1; then \
$(BUF) breaking --against '$(BREAKING_AGAINST)'; \
else \
echo "skip breaking check: main branch not found"; \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fail closed when the breaking baseline branch is unavailable

gen currently depends on breaking, but breaking silently succeeds when git -C .. rev-parse --verify main fails; in single-branch clones or detached checkouts where only origin/main exists, this prints “skip breaking check” and still runs buf generate, so wire-incompatible proto changes are regenerated without any gate. Since this commit’s goal is to enforce buf breaking before generation, the target should resolve a reachable baseline (for example origin/main) or fail instead of skipping.

Useful? React with 👍 / 👎.

fi

gen: check-tools
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
service.proto
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
internal.proto
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
distribution.proto
protoc --go_out=. --go_opt=paths=source_relative \
dynamodb_internal.proto
protoc --go_out=. --go_opt=paths=source_relative \
redis_internal.proto
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
etcd_raft.proto
gen: check-tools breaking
$(BUF) generate
8 changes: 8 additions & 0 deletions proto/buf.gen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: v2
plugins:
- local: protoc-gen-go
out: .
opt: paths=source_relative
- local: protoc-gen-go-grpc
out: .
opt: paths=source_relative
6 changes: 6 additions & 0 deletions proto/buf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: v2
modules:
- path: .
breaking:
use:
- WIRE
2 changes: 1 addition & 1 deletion proto/distribution.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion proto/distribution_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion proto/dynamodb_internal.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion proto/etcd_raft.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion proto/etcd_raft_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading