Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
26 changes: 26 additions & 0 deletions .github/workflows/protos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Protos

on:
pull_request:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Add read-only permissions declaration

paths:
- 'pkg/protocol/protobuf/**'
- 'Dockerfile.protoc'
- 'Makefile'
- '.github/workflows/protos.yml'
push:
branches: [main]
paths:
- 'pkg/protocol/protobuf/**'
- 'Dockerfile.protoc'
- 'Makefile'
- '.github/workflows/protos.yml'

jobs:
check:
name: Verify generated protos are up to date
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run proto-check
run: make proto-check
44 changes: 44 additions & 0 deletions Dockerfile.protoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Dockerfile.protoc — reproducible protoc + protoc-gen-go toolchain.
#
# The versions below are pinned to match the headers of the committed
# *.pb.go files in pkg/protocol/protobuf/ (the runtime version printed
# by protoc is "3.21.9", which corresponds to the upstream release
# tag "v21.9"). Bumping either ARG will typically produce a diff in the
# regenerated code; run `make proto-gen-docker` and commit the result
# in the same change.

FROM golang:1.23.0-bookworm AS toolchain

ARG PROTOC_VERSION=21.9
ARG PROTOC_GEN_GO_VERSION=1.28.1
# SHA256 sums for the official protoc release archives. Update these when

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The Makfile overrides the version but not the hashes, so the Makefile override is useless. Probably cleanest just to scrap it.

# bumping PROTOC_VERSION; values can be recomputed with `sha256sum` against
# the assets at https://github.com/protocolbuffers/protobuf/releases.
ARG PROTOC_SHA256_X86_64=3cd951aff8ce713b94cde55e12378f505f2b89d47bf080508cf77e3934f680b6
ARG PROTOC_SHA256_AARCH_64=a584286dfa8ebb17032ece206ed74d5e9931e2edb9016e427be2a0dab3b21071
ARG TARGETARCH

RUN apt-get update \
&& apt-get install --no-install-recommends -y curl unzip ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# protoc release archives use x86_64 / aarch_64 in their file names.
RUN case "${TARGETARCH:-amd64}" in \
amd64) PROTOC_ARCH=x86_64; PROTOC_SHA256="${PROTOC_SHA256_X86_64}" ;; \
arm64) PROTOC_ARCH=aarch_64; PROTOC_SHA256="${PROTOC_SHA256_AARCH_64}" ;; \
*) echo "unsupported TARGETARCH=${TARGETARCH}" >&2; exit 1 ;; \
esac \
&& curl -fsSL -o /tmp/protoc.zip \
"https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip" \
&& echo "${PROTOC_SHA256} /tmp/protoc.zip" | sha256sum -c - \
&& unzip -q /tmp/protoc.zip -d /usr/local/protoc \
&& rm /tmp/protoc.zip \
&& chmod +x /usr/local/protoc/bin/protoc
Comment on lines +31 to +36

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

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

The Dockerfile downloads the protoc zip from GitHub but doesn't verify its checksum/signature. Since this image is intended to gate CI and provide reproducible output, it would be safer and more deterministic to validate the downloaded archive (e.g., check SHA256 from the release assets) before unzipping/using it.

Copilot uses AI. Check for mistakes.

RUN go install "google.golang.org/protobuf/cmd/protoc-gen-go@v${PROTOC_GEN_GO_VERSION}"

ENV PATH="/usr/local/protoc/bin:/go/bin:${PATH}"

WORKDIR /workspace

ENTRYPOINT ["protoc"]
49 changes: 48 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ endif
PROTO_DIR=./pkg/protocol/protobuf
PROTO_FILES=$(wildcard $(PROTO_DIR)/*.proto)

# Pinned protoc toolchain. Update both versions here AND in Dockerfile.protoc
# when bumping; expect a diff in the regenerated *.pb.go files.
# PROTOC_VERSION uses the upstream release tag (e.g. "21.9"); the matching
# runtime version reported by `protoc --version` is "3.21.9".
PROTOC_VERSION=21.9
PROTOC_GEN_GO_VERSION=1.28.1
PROTOC_IMAGE=vehicle-command-protoc:$(PROTOC_VERSION)-$(PROTOC_GEN_GO_VERSION)
PROTOC_DOCKERFILE=Dockerfile.protoc

all: build

linters:
Expand Down Expand Up @@ -38,4 +47,42 @@ doc-images:
proto-gen: $(PROTO_FILES)
protoc --proto_path $(PROTO_DIR) --go_out $(PROTO_DIR) --go_opt=module=github.com/teslamotors/vehicle-command/pkg/protocol/protobuf ${PROTO_FILES}

.PHONY: install build linters test format set-version doc-images protoc-gen
# Build the pinned protoc toolchain image. No-op if it already exists.
proto-builder:
docker build \
--build-arg PROTOC_VERSION=$(PROTOC_VERSION) \
--build-arg PROTOC_GEN_GO_VERSION=$(PROTOC_GEN_GO_VERSION) \
-f $(PROTOC_DOCKERFILE) \
-t $(PROTOC_IMAGE) \
.

# Regenerate *.pb.go using the pinned toolchain. Use this instead of
# `proto-gen` to get reproducible output independent of the host's
# installed protoc version.
proto-gen-docker: proto-builder
docker run --rm \
--user "$$(id -u):$$(id -g)" \
-v "$(CURDIR):/workspace" \
-w /workspace \
$(PROTOC_IMAGE) \
--proto_path $(PROTO_DIR) \
--go_out $(PROTO_DIR) \
--go_opt=module=github.com/teslamotors/vehicle-command/pkg/protocol/protobuf \
$(PROTO_FILES)

# Regenerate via Docker and fail if the result differs from what is
# committed, or if regeneration produced files that are not tracked (a new
# .proto whose .pb.go was never committed). Intended for CI to catch
# out-of-date or missing *.pb.go files.
proto-check: proto-gen-docker
@if ! git diff --quiet -- $(PROTO_DIR) || \
[ -n "$$(git ls-files --others --exclude-standard -- $(PROTO_DIR))" ]; then \
echo "ERROR: generated protobuf files are out of date or missing."; \
echo "Run 'make proto-gen-docker' and commit the result."; \
git --no-pager status --short -- $(PROTO_DIR); \
git --no-pager diff -- $(PROTO_DIR); \
exit 1; \
fi
@echo "Generated protobuf files are up to date."

.PHONY: install build linters test format set-version doc-images proto-gen proto-builder proto-gen-docker proto-check