Fail loudly if we try to use a prebuilt protoc with unreleased code (#28167)

Currently if you build with `--incompatible_enable_proto_toolchain_resolution`
(on by default in Bazel 9) on main or any recent Git commit, you end up using
an old v33.0 prebuilt protoc binary. The `authenticity_validation` rule does
not catch this, because it just checks that the `RELEASE_VERSION` prebuilt we
downloaded has version `RELEASE_VERSION`. This constant is never updated in
Git, only in releases published to BCR. As a result, we get mysterious compiler
errors rather than a clear error about what is going wrong.

This commit fixes the problem by keeping `RELEASE_VERSION` up to date with the
existing `PROTOC_VERSION`. This will cause the build to fail loudly if you try
to use a prebuilt protoc binary with a protobuf Git checkout. To make sure that
developers do not hit this issue, I updated .bazelrc to explicitly turn off use
of the prebuilt protoc.

I also removed `examples/example_without_cc_toolchain/`, because I don't think
this test is doing anything useful anymore. It attempts to exercise the
prebuilt protoc, but that is something we do not expect to work correctly with
unreleased protobuf code, and with my change it would result in a build error.

Closes #28167

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/28167 from protocolbuffers:prebuilt d7c67c9ce7
PiperOrigin-RevId: 943511369
This commit is contained in:
Adam Cozzette 2026-07-06 14:58:26 -07:00 committed by Copybara-Service
parent f25fb36bfe
commit 06e205948b
9 changed files with 7 additions and 92 deletions

View file

@ -6,7 +6,7 @@ build --javacopt=-Xep:SelfAssertion:WARN
# Disable prebuilt protoc on CI. On both main and release branches,
# PROTOBUF_VERSION ordinarily points to the next release, which doesn't
# exist and therefore doesn't have a prebuilt yet.
#build --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc=false
build --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc=false
# This flag works around some issues with Rust linking.
build --@rules_rust//rust/settings:experimental_use_cc_common_link=True

View file

@ -81,36 +81,6 @@ jobs:
cd examples;
bazel build //... @com_google_protobuf-examples-with-hyphen//... $BAZEL_FLAGS --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }} ${{ matrix.toolchain_resolution }};
prebuilt-protoc:
strategy:
fail-fast: false
matrix:
runner: [ ubuntu, windows, macos ]
bazelversion: [ '8.6.0', '9.0.0' ]
bzlmod: [ true ]
toolchain_resolution:
# Default flags, uses from prebuilt protoc
- ""
runs-on: ${{ matrix.runner }}-latest
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Prebuilt test ${{ matrix.runner }} ${{ matrix.bazelversion }} ${{ matrix.toolchain_resolution && ' (toolchain resolution)' || '' }}
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v5
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v5
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: examples-prebuilt-${{ matrix.bazelversion }}-${{ matrix.toolchain_resolution }}
version: ${{ matrix.bazelversion }}
bash: >
cd examples/example_without_cc_toolchain;
bazel build //... $BAZEL_FLAGS ${{ matrix.toolchain_resolution }};
bazel-tests-ubuntu:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.

View file

@ -6,6 +6,7 @@ In particular, see comment below on the toolchain#toolchain attribute.
load("//toolchain:platforms.bzl", "PROTOBUF_PLATFORMS")
load(":protoc_authenticity.bzl", "protoc_authenticity")
load(":tool_integrity.bzl", "RELEASE_VERSION")
[
toolchain(
@ -19,6 +20,7 @@ load(":protoc_authenticity.bzl", "protoc_authenticity")
toolchain_type = "@com_google_protobuf//bazel/private:proto_toolchain_type",
)
for platform, meta in PROTOBUF_PLATFORMS.items()
if not RELEASE_VERSION.endswith("-dev")
]
# Support verification of user-registered toolchains

View file

@ -3,19 +3,10 @@
This file contents are entirely replaced during release publishing, by .github/workflows/release_prep.sh
so that the integrity of the prebuilt tools is included in the release artifact.
The checked in content is only here to allow load() statements in the sources to resolve, and permit local testing.
The checked in content is only here to allow load() statements in the sources to resolve.
"""
# An arbitrary version of protobuf that includes pre-built binaries.
# See /examples/example_without_cc_toolchain which uses this for testing.
# TODO: add some automation to update this version occasionally.
_TEST_VERSION = "v33.0"
_TEST_SHAS = dict()
load("//:protobuf_version.bzl", "PROTOC_VERSION")
# Add a couple platforms which are commonly used for testing.
_TEST_SHAS["protoc-33.0-linux-x86_64.zip"] = "d99c011b799e9e412064244f0be417e5d76c9b6ace13a2ac735330fa7d57ad8f"
_TEST_SHAS["protoc-33.0-osx-aarch_64.zip"] = "3cf55dd47118bd2efda9cd26b74f8bbbfcf5beb1bf606bc56ad4c001b543f6d3"
_TEST_SHAS["protoc-33.0-win64.zip"] = "3742cd49c8b6bd78b6760540367eb0ff62fa70a1032e15dafe131bfaf296986a"
RELEASE_VERSION = _TEST_VERSION
RELEASED_BINARY_INTEGRITY = _TEST_SHAS
RELEASE_VERSION = "v{}-dev".format(PROTOC_VERSION)
RELEASED_BINARY_INTEGRITY = dict()

View file

@ -1,10 +0,0 @@
# Simulate a non-functional CC toolchain
common --per_file_copt=external/.*protobuf.*/src/google/protobuf/compiler/main.cc@--THIS_CC_TOOLCHAIN_IS_BROKEN
common --host_per_file_copt=external/.*protobuf.*/src/google/protobuf/compiler/main.cc@--THIS_CC_TOOLCHAIN_IS_BROKEN
# But, users should be able to use pre-built protoc toolchains instead.
common --incompatible_enable_proto_toolchain_resolution
common --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc
# Import Bazel 9 specific flags (such as --repo_contents_cache)
# TODO: Remove it when --repo_contents_cache issue has been resolved in bazel
try-import-if-bazel-version >=9.0.0 %workspace%/../../ci/bazel9.bazelrc

View file

@ -1,17 +0,0 @@
load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
proto_library(
name = "empty_proto",
srcs = ["empty.proto"],
)
cc_proto_library(
name = "cc_empty_proto",
# We already have a anaylsis test that asserts that the cc_proto_library
# uses the correct prebuilt toolchain, this cc_proto_library will never
# compile since the prebuilt toolchain is always behind the HEAD therefore
# will end up in version skew compilation errors.
tags = ["manual"],
deps = [":empty_proto"],
)

View file

@ -1,13 +0,0 @@
"""Bazel module dependencies"""
module(
name = "com_google_protobuf-example-without-cc-toolchain",
version = "0.0.0",
compatibility_level = 1,
)
bazel_dep(name = "protobuf", repo_name = "com_google_protobuf")
local_path_override(
module_name = "protobuf",
path = "../..",
)

View file

@ -1,3 +0,0 @@
This example demonstrates what happens when a Bazel user doesn't have a proper
CC toolchain installed. This case commonly happens in projects with no C++ code,
so they don't have a hermetic method of building C++ code.

View file

@ -1,5 +0,0 @@
edition = "2023";
package examples.without.cc.toolchain;
message EmptyMessage {}