protoc: Generate Code From .proto Files in CI
protoc compiles .proto files into generated code; -I sets the import root and --<lang>_out picks the target language and output directory.
protoc is the reference Protocol Buffers compiler. In CI the two things that break first are the import path (-I) and whether the language plugin is on PATH.
What it does
protoc parses .proto files, resolves their import statements against the directories given by -I/--proto_path, and writes generated code through a per-language output flag like --cpp_out, --python_out, or a plugin flag such as --go_out. Each .proto filename you pass must be reachable under one of the -I roots.
Common usage
protoc -I proto --python_out=gen proto/api/v1/user.proto
# Go via the protoc-gen-go plugin (must be on PATH)
protoc -I proto --go_out=gen --go_opt=paths=source_relative \
proto/api/v1/user.proto
# multiple files at once
protoc -I proto --go_out=gen proto/api/v1/*.protoFlags and options
| Flag | What it does |
|---|---|
| -I <dir> / --proto_path=<dir> | Import root; repeatable. Imports resolve relative to these |
| --<lang>_out=<dir> | Output dir for a built-in language (cpp, java, python, etc.) |
| --go_out=<dir> | Invoke the protoc-gen-go plugin and write Go to <dir> |
| --go_opt=paths=source_relative | Lay out Go files mirroring the .proto tree |
| --plugin=protoc-gen-X=<path> | Point at a plugin binary not found on PATH |
| --descriptor_set_out=<file> | Emit a compiled FileDescriptorSet instead of code |
| --version | Print the protoc version (libprotoc 3.x / 4.x / 5.x) |
In CI
Pin the protoc version in the job; generated output differs between major releases and a floating apt-get install protobuf-compiler can silently change it. Commit generated code or regenerate and diff, but be consistent: a version bump that reformats output looks like a spurious failure otherwise.
Common errors in CI
"<file>: File not found." or "Import "x.proto" was not found or had errors." means the import root is wrong; the path after import must be reachable under a -I dir, not relative to the importing file. "Missing output directives." means you passed .proto files but no --*_out flag. "<file>: File does not reside within any path specified using --proto_path" means the file you named is outside every -I root; add the right -I.