Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .github/workflows/gapic-generator-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ permissions:

name: Gapic Generator Specialized Tests

# trigger ci
on:
pull_request:
push:
Expand Down
2 changes: 1 addition & 1 deletion packages/gapic-generator/.bazeliskrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# See https://github.com/bazelbuild/bazelisk
USE_BAZEL_VERSION=6.5.0
USE_BAZEL_VERSION=7.7.1
11 changes: 11 additions & 0 deletions packages/gapic-generator/.bazelrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
# New protobuf requires C++17
build --repo_env=BAZEL_CXXOPTS="-std=c++17"

# Workaround for rules_python precompilation bug with directory outputs:
# Newer rules_python (v0.40.0+) attempts to precompile (.py -> .pyc) sources.
# GAPIC code generator rules (e.g., //tests/integration:asset_py_gapic) output a
# directory structure of generated code instead of discrete individual files.
# This triggers: "Error in add: Cannot add directories to Args#add since they may expand to multiple values".
# Disabling precompilation bypasses the bug without affecting runtime behavior.
build --@rules_python//python/config_settings:precompile=force_disabled

# Disable Bzlmod to use legacy WORKSPACE file repository resolution
common --noenable_bzlmod
169 changes: 105 additions & 64 deletions packages/gapic-generator/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -2,122 +2,163 @@ workspace(name = "gapic_generator_python")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

_bazel_skylib_version = "1.4.0"
# Load Protobuf 35.1 first to ensure Bazel uses Protobuf 35.1 over older
# transitive versions pulled in by downstream rules (e.g. gRPC or rules_gapic).
_protobuf_version = "35.1"
_protobuf_sha256 = "bf89df2fa0088de9c9890fbfba0076263a36c2f84847a7b54e7e32effd6201c7"
http_archive(
name = "com_google_protobuf",
sha256 = _protobuf_sha256,
strip_prefix = "protobuf-{}".format(_protobuf_version),
urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v{0}/protobuf-{0}.zip".format(_protobuf_version)],
)

_bazel_skylib_sha256 = "f24ab666394232f834f74d19e2ff142b0af17466ea0c69a3f4c276ee75f6efce"
# Load com_google_googleapis first so we can choose which version will be used
_googleapis_sha256 = "2638026851b9110c280d75338581a752a4271340"
http_archive(
name = "com_google_googleapis",
strip_prefix = "googleapis-{}".format(_googleapis_sha256),
urls = ["https://github.com/googleapis/googleapis/archive/{0}.zip".format(_googleapis_sha256)],
)

# Load rules_gapic v1.0.0. We patch rules_gapic's .bzl files to inject the
# explicit load for Starlark ProtoInfo from @rules_proto to maintain symbol
# resolution under rules_proto / Protobuf 35.1.
_rules_gapic_version = "1.0.0"
_rules_gapic_sha256 = "c21e78a42f69898e7c3142fa837e3a637b1993d27c08a64723262611971d2b96"
http_archive(
name = "rules_gapic",
sha256 = _rules_gapic_sha256,
strip_prefix = "rules_gapic-{}".format(_rules_gapic_version),
urls = [
"https://github.com/googleapis/rules_gapic/archive/v{}.tar.gz".format(_rules_gapic_version)
]
)

# Load C++ rules matching modern Protobuf C++ requirements
_rules_cc_version = "0.1.5"
_rules_cc_sha256 = "b8b918a85f9144c01f6cfe0f45e4f2838c7413961a8ff23bc0c6cdf8bb07a3b6"
http_archive(
name = "rules_cc",
sha256 = _rules_cc_sha256,
strip_prefix = "rules_cc-{}".format(_rules_cc_version),
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/{0}/rules_cc-{0}.tar.gz".format(_rules_cc_version)],
)

# Load bazel_skylib required by Starlark rules
_bazel_skylib_version = "1.9.0"
_bazel_skylib_sha256 = "3b5b49006181f5f8ff626ef8ddceaa95e9bb8ad294f7b5d7b11ea9f7ddaf8c59"
http_archive(
name = "bazel_skylib",
sha256 = _bazel_skylib_sha256,
url = "https://github.com/bazelbuild/bazel-skylib/releases/download/{0}/bazel-skylib-{0}.tar.gz".format(_bazel_skylib_version),
)

# Load Abseil C++ matching Protobuf 35 C++ dependencies
_com_google_absl_version = "20240722.1"
_com_google_absl_sha256 = "40cee67604060a7c8794d931538cb55f4d444073e556980c88b6c49bb9b19bb7"
http_archive(
name = "com_google_absl",
sha256 = _com_google_absl_sha256,
strip_prefix = "abseil-cpp-{}".format(_com_google_absl_version),
urls = [
"https://github.com/abseil/abseil-cpp/releases/download/{0}/abseil-cpp-{0}.tar.gz".format(_com_google_absl_version),
],
)

# Load Go rules required for GAPIC plugin building
_io_bazel_rules_go_version = "0.33.0"
_io_bazel_rules_go_sha256 = "685052b498b6ddfe562ca7a97736741d87916fe536623afb7da2824c0211c369"
http_archive(
name = "io_bazel_rules_go",
sha256 = "685052b498b6ddfe562ca7a97736741d87916fe536623afb7da2824c0211c369",
sha256 = _io_bazel_rules_go_sha256,
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v{0}/rules_go-v{0}.zip".format(_io_bazel_rules_go_version),
"https://github.com/bazelbuild/rules_go/releases/download/v{0}/rules_go-v{0}.zip".format(_io_bazel_rules_go_version),
],
)

_rules_python_version = "0.26.0"

_rules_python_sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b"

# Upgraded to rules_python 1.1.0 for modern C-extension toolchain support.
_rules_python_version = "1.1.0"
_rules_python_sha256 = "9c6e26911a79fbf510a8f06d8eedb40f412023cf7fa6d1461def27116bff022c"
http_archive(
name = "rules_python",
sha256 = _rules_python_sha256,
strip_prefix = "rules_python-{}".format(_rules_python_version),
url = "https://github.com/bazelbuild/rules_python/archive/{}.tar.gz".format(_rules_python_version),
url = "https://github.com/bazelbuild/rules_python/releases/download/{0}/rules_python-{0}.tar.gz".format(_rules_python_version),
)

load("@rules_python//python:repositories.bzl", "py_repositories")

load("@rules_python//python:repositories.bzl", "py_repositories", "python_register_multi_toolchains")
py_repositories()

load("@rules_python//python:pip.bzl", "pip_parse")

# Register multi-version hermetic Python toolchains (3.10 - 3.13) to ensure
# Bazel can resolve both execution and C-header toolchains for any Python target.
# Set ignore_root_user_error = True so toolchains unpack safely in Docker CI containers (EUID=0).
python_register_multi_toolchains(
name = "python",
ignore_root_user_error = True,
python_versions = [
"3.11",
"3.12",
"3.13",
],
)

load("@rules_python//python:pip.bzl", "pip_parse")
pip_parse(
name = "gapic_generator_python_pip_deps",
requirements_lock = "//:requirements.txt",
requirements_lock = "//:requirements.txt",
)
load("@gapic_generator_python_pip_deps//:requirements.bzl", "install_deps")

load("@gapic_generator_python_pip_deps//:requirements.bzl", "install_deps")
install_deps()
#
# Import gapic-generator-python specific dependencies
#
load(
"//:repositories.bzl",
"gapic_generator_python",
"gapic_generator_register_toolchains",
)

gapic_generator_python()

gapic_generator_register_toolchains()

_grpc_version = "1.71.0"

_grpc_sha256 = "9313c3f8f4dd3341597f152d506a50caf571fe40f886e24ea9078891990df285"

# Load gRPC v1.83.0 with temporary patch for legacy_channel.cc.
# The fix is merged upstream (https://github.com/grpc/grpc/commit/816506e5c0434a42414af6955cc9eef0c562ff3a)
# and this patch is temporary until released in a future gRPC release.
_grpc_version = "1.83.0"
_grpc_sha256 = "876ff5c9c26f364cd603531761268a5b58ccc1479afc78d6dab1d8e839da00c0"
http_archive(
name = "com_github_grpc_grpc",
sha256 = _grpc_sha256,
strip_prefix = "grpc-%s" % _grpc_version,
urls = ["https://github.com/grpc/grpc/archive/v%s.zip" % _grpc_version],
)
# instantiated in grpc_deps().

_protobuf_version = "30.2"

_protobuf_sha256 = "07a43d88fe5a38e434c7f94129cad56a4c43a51f99336074d0799c2f7d4e44c5"

http_archive(
name = "com_google_protobuf",
sha256 = _protobuf_sha256,
strip_prefix = "protobuf-%s" % _protobuf_version,
urls = ["https://github.com/protocolbuffers/protobuf/archive/v%s.tar.gz" % _protobuf_version],
strip_prefix = "grpc-{}".format(_grpc_version),
urls = ["https://github.com/grpc/grpc/archive/v{}.zip".format(_grpc_version)],
patches = ["//third_party:grpc_legacy_channel.patch"],
patch_args = ["-p1"],
)
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")

grpc_deps()

http_archive(
name = "rules_cc",
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.1.1/rules_cc-0.1.1.tar.gz"],
sha256 = "712d77868b3152dd618c4d64faaddefcc5965f90f5de6e6dd1d5ddcd0be82d42",
strip_prefix = "rules_cc-0.1.1",
load(
"//:repositories.bzl",
"gapic_generator_python",
"gapic_generator_register_toolchains",
)
gapic_generator_python()
gapic_generator_register_toolchains()

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps", "PROTOBUF_MAVEN_ARTIFACTS")
# This is actually already done within grpc_deps but calling this for Bazel convention.
protobuf_deps()

# Add rules_java to resolve the following error
# `The repository '@compatibility_proxy' could not be resolved: Repository '@compatibility_proxy' is not defined`
# Add rules_java to resolve compatibility proxy errors
load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies")

rules_java_dependencies()

# gRPC enforces a specific version of Go toolchain which conflicts with our build.
# All the relevant parts of grpc_extra_deps() are imported in this WORKSPACE file
# explicitly, that is why we do not call grpc_extra_deps() here and call
# apple_rules_dependencies and apple_support_dependencies macros explicitly.
# Load transitive proto dependencies and register proto toolchains
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()

load("@build_bazel_rules_apple//apple:repositories.bzl", "apple_rules_dependencies")
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
rules_proto_dependencies()

load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
rules_proto_toolchains()

# Load platform dependencies
load("@build_bazel_rules_apple//apple:repositories.bzl", "apple_rules_dependencies")
apple_rules_dependencies()

load("@build_bazel_apple_support//lib:repositories.bzl", "apple_support_dependencies")

apple_support_dependencies()

load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")

switched_rules_by_language(
name = "com_google_googleapis_imports",
gapic = True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ _UUID4_RE = re.compile(r"{{ uuid4_re }}")
{% endif %}


@pytest.fixture(autouse=True)
def disable_mtls_env():
with mock.patch.dict(
os.environ,
{
"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false",
"CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE": "false",
},
):
yield


async def mock_async_gen(data, chunk_size=1):
for i in range(0, len(data)): # pragma: NO COVER
chunk = data[i : i + chunk_size]
Expand Down
31 changes: 0 additions & 31 deletions packages/gapic-generator/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,6 @@ filegroup(

def gapic_generator_python():

_maybe(
http_archive,
name = "bazel_skylib",
strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b",
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"],
)

_grpc_version = "1.47.0"
_grpc_sha256 = "edf25f4db6c841853b7a29d61b0980b516dc31a1b6cdc399bcf24c1446a4a249"
_maybe(
http_archive,
name = "com_github_grpc_grpc",
sha256 = _grpc_sha256,
strip_prefix = "grpc-{}".format(_grpc_version),
url = "https://github.com/grpc/grpc/archive/v{}.zip".format(_grpc_version),
)

_maybe(
http_archive,
name = "pandoc_linux_arm_64",
Expand Down Expand Up @@ -66,20 +49,6 @@ def gapic_generator_python():
url = "https://github.com/jgm/pandoc/releases/download/3.7.0.2/pandoc-3.7.0.2-windows-x86_64.zip",
)

_rules_gapic_version = "0.5.4"
_maybe(
http_archive,
name = "rules_gapic",
strip_prefix = "rules_gapic-%s" % _rules_gapic_version,
urls = ["https://github.com/googleapis/rules_gapic/archive/v%s.tar.gz" % _rules_gapic_version],
)
_commit_sha = "2638026851b9110c280d75338581a752a4271340"
_maybe(
http_archive,
name = "com_google_googleapis",
strip_prefix = "googleapis-{}".format(_commit_sha),
urls = ["https://github.com/googleapis/googleapis/archive/{}.zip".format(_commit_sha)],
)

def gapic_generator_register_toolchains():
native.register_toolchains(
Expand Down
51 changes: 49 additions & 2 deletions packages/gapic-generator/rules_python_gapic/py_gapic.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,39 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_gapic//:gapic.bzl", "proto_custom_library", "unzipped_srcjar")
load("@rules_gapic//:gapic.bzl", "proto_custom_library", "unzipped_srcjar", "CustomProtoInfo")
load("@rules_python//python:defs.bzl", "py_library")
load("@gapic_generator_python_pip_deps//:requirements.bzl", "requirement")

# Load modern rules_proto Starlark ProtoInfo provider.
# Needed because modern rules_proto targets output Starlark ProtoInfo, whereas
# rules_gapic's proto_custom_library expects rules_gapic's CustomProtoInfo provider.
load("@rules_proto//proto:defs.bzl", StarlarkProtoInfo = "ProtoInfo")

# Compatibility adapter rule to convert modern rules_proto Starlark ProtoInfo
# into rules_gapic CustomProtoInfo provider required by proto_custom_library.
def _gapic_compat_proto_library_impl(ctx):
dep = ctx.attr.dep
starlark_proto = dep[StarlarkProtoInfo]
return [
dep[DefaultInfo],
# Construct CustomProtoInfo provider needed by rules_gapic's proto_custom_library.
# Must not return ProtoInfo here so proto_custom_library selects CustomProtoInfo (which has transitive_imports).
CustomProtoInfo(
direct_sources = starlark_proto.direct_sources,
check_deps_sources = starlark_proto.check_deps_sources,
# Map modern transitive_sources to CustomProtoInfo's transitive_imports field
transitive_imports = starlark_proto.transitive_sources,
),
]
Comment thread
parthea marked this conversation as resolved.
Comment thread
parthea marked this conversation as resolved.

gapic_compat_proto_library = rule(
implementation = _gapic_compat_proto_library_impl,
attrs = {
"dep": attr.label(mandatory = True, providers = [StarlarkProtoInfo]),
}
)

def _gapic_test_file_impl(ctx):
generated_test_file = ctx.actions.declare_file(ctx.label.name)

Expand Down Expand Up @@ -46,6 +75,22 @@ def py_gapic_library(
rest_numeric_enums = False,
deps = [],
**kwargs):

# We extract and propagate 'testonly' and 'tags' from kwargs to prevent Bazel dependency analysis
# errors and ensure wildcard builds (e.g. manual tags) behave correctly.
testonly = kwargs.get("testonly", False)
tags = kwargs.get("tags", [])
compat_srcs = []
for i, src in enumerate(srcs):
compat_name = "%s_compat_src_%d" % (name, i)
gapic_compat_proto_library(
name = compat_name,
dep = src,
testonly = testonly,
tags = tags,
)
compat_srcs.append(":%s" % compat_name)
Comment thread
parthea marked this conversation as resolved.

srcjar_target_name = "%s_srcjar" % name
srcjar_output_suffix = ".srcjar"

Expand All @@ -67,9 +112,11 @@ def py_gapic_library(
if rest_numeric_enums:
opt_args = opt_args + ["rest-numeric-enums"]

# Point deps to compat_srcs so proto_custom_library receives targets providing
# the CustomProtoInfo provider instead of raw Starlark ProtoInfo targets.
proto_custom_library(
name = srcjar_target_name,
deps = srcs,
deps = compat_srcs,
plugin = Label("@gapic_generator_python//:gapic_plugin"),
plugin_args = plugin_args,
plugin_file_args = file_args,
Expand Down
Loading
Loading