diff --git a/api/bazel/BUILD b/api/bazel/BUILD index f68f07c91146..eb9f3971a1ef 100644 --- a/api/bazel/BUILD +++ b/api/bazel/BUILD @@ -12,6 +12,7 @@ load(":repository_locations_utils.bzl", "load_repository_locations_spec") licenses(["notice"]) # Apache 2 exports_files([ + "extensions.bzl", "repository_locations.bzl", "repository_locations_utils.bzl", "utils.bzl", diff --git a/api/bazel/api_build_system.bzl b/api/bazel/api_build_system.bzl index e3047cac49b5..a5d4ae70972b 100644 --- a/api/bazel/api_build_system.bzl +++ b/api/bazel/api_build_system.bzl @@ -1,6 +1,7 @@ load("@com_envoyproxy_protoc_gen_validate//bazel:pgv_proto_library.bzl", "pgv_cc_proto_library") load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library") load("@com_github_grpc_grpc//bazel:python_rules.bzl", _py_proto_library = "py_proto_library") +load("@com_google_protobuf//bazel:java_proto_library.bzl", "java_proto_library") load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") load("@io_bazel_rules_go//go:def.bzl", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") @@ -24,6 +25,7 @@ _CC_GRPC_SUFFIX = "_cc_grpc" _GO_PROTO_SUFFIX = "_go_proto" _GO_IMPORTPATH_PREFIX = "github.com/envoyproxy/go-control-plane/" _JAVA_PROTO_SUFFIX = "_java_proto" +_IS_BZLMOD = str(Label("//:invalid")).startswith("@@") _COMMON_PROTO_DEPS = [ "@com_google_protobuf//:any_proto", @@ -43,7 +45,8 @@ _COMMON_PROTO_DEPS = [ def _proto_mapping(dep, proto_dep_map, proto_suffix): mapped = proto_dep_map.get(dep) if mapped == None: - prefix = "@" + Label(dep).workspace_name if not dep.startswith("//") else "" + prefix = "@@" if _IS_BZLMOD else "@" + prefix = prefix + Label(dep).repo_name if not dep.startswith("//") else "" return prefix + "//" + Label(dep).package + ":" + Label(dep).name + proto_suffix return mapped @@ -113,7 +116,7 @@ def api_cc_py_proto_library( ) if java: - native.java_proto_library( + java_proto_library( name = name + _JAVA_PROTO_SUFFIX, visibility = ["//visibility:public"], deps = [relative_name], diff --git a/api/bazel/cc_proto_descriptor_library/BUILD b/api/bazel/cc_proto_descriptor_library/BUILD index 993d10801d30..6d013919c120 100644 --- a/api/bazel/cc_proto_descriptor_library/BUILD +++ b/api/bazel/cc_proto_descriptor_library/BUILD @@ -37,7 +37,6 @@ cc_library( "@com_google_absl//absl/strings:str_format", "@com_google_protobuf//:protobuf", "@com_google_protobuf//src/google/protobuf/compiler:code_generator", - "@com_google_protobuf//src/google/protobuf/compiler:retention", ], ) diff --git a/api/bazel/cc_proto_descriptor_library/builddefs.bzl b/api/bazel/cc_proto_descriptor_library/builddefs.bzl index 23d9f5581bce..e3ae549e7d5b 100644 --- a/api/bazel/cc_proto_descriptor_library/builddefs.bzl +++ b/api/bazel/cc_proto_descriptor_library/builddefs.bzl @@ -3,6 +3,9 @@ """ load("@bazel_skylib//lib:paths.bzl", "paths") +load("@com_google_protobuf//bazel/common:proto_info.bzl", "ProtoInfo") +load("@rules_cc//cc/common:cc_common.bzl", "cc_common") +load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") # begin:google_only # load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain") diff --git a/api/bazel/extensions.bzl b/api/bazel/extensions.bzl new file mode 100644 index 000000000000..7f47d4e726c1 --- /dev/null +++ b/api/bazel/extensions.bzl @@ -0,0 +1,33 @@ +"""Non-BCR dependencies for Envoy Data Plane API. + +This extension provides repositories that are not available in Bazel Central Registry (BCR). +""" + +load(":repositories.bzl", "api_dependencies") + +def _non_module_deps_impl(module_ctx): + """Implementation for non_module_deps extension. + + This extension calls api_dependencies(bzlmod=True) which creates repositories + not in BCR. It safely coexists with BCR deps because envoy_http_archive + checks native.existing_rules() before creating repositories. + + Args: + module_ctx: Module extension context + """ + api_dependencies(bzlmod = True) + +non_module_deps = module_extension( + implementation = _non_module_deps_impl, + doc = """ + Extension for Envoy API dependencies not available in BCR. + + This extension creates the following repositories: + - prometheus_metrics_model: Prometheus client model + - com_github_chrusty_protoc_gen_jsonschema: Proto to JSON schema compiler + - envoy_toolshed: Tooling and libraries for Envoy development + + For WORKSPACE mode, call api_dependencies() directly from WORKSPACE. + This extension should only be used in MODULE.bazel files. + """, +) diff --git a/api/bazel/repositories.bzl b/api/bazel/repositories.bzl index 217614f5e563..ba118cb5f049 100644 --- a/api/bazel/repositories.bzl +++ b/api/bazel/repositories.bzl @@ -12,7 +12,23 @@ def external_http_archive(name, **kwargs): **kwargs ) -def api_dependencies(): +def api_dependencies(bzlmod = False): + # Dependencies needed for both WORKSPACE and bzlmod + external_http_archive( + name = "prometheus_metrics_model", + build_file_content = PROMETHEUSMETRICS_BUILD_CONTENT, + ) + external_http_archive( + name = "com_github_chrusty_protoc_gen_jsonschema", + ) + external_http_archive( + name = "envoy_toolshed", + ) + + # WORKSPACE-only dependencies (available in BCR for bzlmod or not needed) + if bzlmod: + return + external_http_archive( name = "bazel_skylib", ) @@ -30,10 +46,6 @@ def api_dependencies(): external_http_archive( name = "com_github_cncf_xds", ) - external_http_archive( - name = "prometheus_metrics_model", - build_file_content = PROMETHEUSMETRICS_BUILD_CONTENT, - ) external_http_archive( name = "rules_buf", ) @@ -51,9 +63,6 @@ def api_dependencies(): external_http_archive( name = "dev_cel", ) - external_http_archive( - name = "com_github_chrusty_protoc_gen_jsonschema", - ) PROMETHEUSMETRICS_BUILD_CONTENT = """ load("@envoy_api//bazel:api_build_system.bzl", "api_cc_py_proto_library") diff --git a/api/bazel/repository_locations.bzl b/api/bazel/repository_locations.bzl index 95d61074f0fe..a3e36fbb5915 100644 --- a/api/bazel/repository_locations.bzl +++ b/api/bazel/repository_locations.bzl @@ -166,4 +166,22 @@ REPOSITORY_LOCATIONS_SPEC = dict( license = "Apache-2.0", license_url = "https://github.com/google/cel-spec/blob/v{version}/LICENSE", ), + envoy_toolshed = dict( + project_name = "envoy_toolshed", + project_desc = "Tooling, libraries, runners and checkers for Envoy proxy's CI", + project_url = "https://github.com/envoyproxy/toolshed", + version = "0.3.5", + sha256 = "ec59fe6cf1432d33c0207e9f85bda3cbf653b54b3a16f3f94479b6cc8f3d1701", + strip_prefix = "toolshed-bazel-v{version}/bazel", + urls = ["https://github.com/envoyproxy/toolshed/archive/bazel-v{version}.tar.gz"], + use_category = ["build", "controlplane", "dataplane_core"], + implied_untracked_deps = [ + "tsan_libs", + "msan_libs", + ], + release_date = "2025-10-27", + cpe = "N/A", + license = "Apache-2.0", + license_url = "https://github.com/envoyproxy/toolshed/blob/bazel-v{version}/LICENSE", + ), ) diff --git a/api/tools/generate_listeners_test.py b/api/tools/generate_listeners_test.py index 5e214c1172de..348fac07bdc7 100644 --- a/api/tools/generate_listeners_test.py +++ b/api/tools/generate_listeners_test.py @@ -9,7 +9,18 @@ import generate_listeners if __name__ == "__main__": - srcdir = os.path.join(os.getenv("TEST_SRCDIR"), 'envoy_api') + test_srcdir = os.getenv("TEST_SRCDIR") + # In bzlmod, the main repository is '_main', in WORKSPACE it's 'envoy_api' + # Try both to support both build systems + for workspace_name in ['_main', 'envoy_api']: + candidate_dir = os.path.join(test_srcdir, workspace_name) + if os.path.isdir(candidate_dir): + srcdir = candidate_dir + break + else: + # Fallback to _main if neither exists (shouldn't happen) + srcdir = os.path.join(test_srcdir, '_main') + generate_listeners.generate_listeners( os.path.join(srcdir, "examples/service_envoy/listeners.pb"), "/dev/stdout", "/dev/stdout", iter([os.path.join(srcdir, "examples/service_envoy/http_connection_manager.pb")])) diff --git a/api/tools/tap2pcap_test.py b/api/tools/tap2pcap_test.py index 504b49aa4335..93d96b7f214c 100644 --- a/api/tools/tap2pcap_test.py +++ b/api/tools/tap2pcap_test.py @@ -14,7 +14,18 @@ # a golden output file for the tshark dump. Since we run tap2pcap in a # subshell with a limited environment, the inferred time zone should be UTC. if __name__ == '__main__': - srcdir = os.path.join(os.getenv('TEST_SRCDIR'), 'envoy_api') + test_srcdir = os.getenv('TEST_SRCDIR') + # In bzlmod, the main repository is '_main', in WORKSPACE it's 'envoy_api' + # Try both to support both build systems + for workspace_name in ['_main', 'envoy_api']: + candidate_dir = os.path.join(test_srcdir, workspace_name) + if os.path.isdir(candidate_dir): + srcdir = candidate_dir + break + else: + # Fallback to _main if neither exists (shouldn't happen) + srcdir = os.path.join(test_srcdir, '_main') + tap_path = os.path.join(srcdir, 'tools/data/tap2pcap_h2_ipv4.pb_text') expected_path = os.path.join(srcdir, 'tools/data/tap2pcap_h2_ipv4.txt') pcap_path = os.path.join(os.getenv('TEST_TMPDIR'), 'generated.pcap')