From b40e3f8ffdda473d70c970b689b5c2c8156d6bf2 Mon Sep 17 00:00:00 2001 From: Ben King <9087625+benfdking@users.noreply.github.com> Date: Sun, 9 Aug 2026 17:17:09 +0200 Subject: [PATCH 1/2] Fix Bazel test suite --- BUILD.bazel | 4 ++ MODULE.bazel | 35 ++++++++++-- MODULE.bazel.lock | 8 +-- cargo_build.bzl | 47 +++++++++++++++- editors/code/BUILD.bazel | 1 + editors/code/playwright.bazel.config.ts | 72 +++++++++++++++++-------- playground/BUILD.bazel | 1 + playground/playwright.bazel.config.ts | 49 +++++++++++++---- 8 files changed, 179 insertions(+), 38 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index cf3de2dd7..324f8a71d 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -419,6 +419,7 @@ sh_test( # Uses vendored dependencies for hermetic builds cargo_test( name = "cargo_check", + python_venv = ":python_deps", srcs = [":cargo_srcs"], vendor = ":cargo_deps", script = "cargo check --all --all-features --tests --benches --locked --offline", @@ -429,6 +430,7 @@ cargo_test( # Uses vendored dependencies for hermetic builds cargo_test( name = "cargo_build_release", + python_venv = ":python_deps", size = "enormous", srcs = [":cargo_srcs"], vendor = ":cargo_deps", @@ -439,6 +441,7 @@ cargo_test( # Uses vendored dependencies for hermetic builds cargo_test( name = "cargo_clippy", + python_venv = ":python_deps", srcs = [":cargo_srcs"], vendor = ":cargo_deps", script = "cargo clippy --all --all-features --offline -- -D warnings", @@ -495,6 +498,7 @@ cargo_test( name = "cargo_hack_check", size = "enormous", srcs = [":cargo_srcs"], + python_venv = ":python_deps", tools = ["@cargo_hack//:cargo-hack"], vendor = ":cargo_deps", script = "cargo hack check --each-feature --exclude-features=codegen-docs --offline", diff --git a/MODULE.bazel b/MODULE.bazel index cc9085598..0624b7c01 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -40,9 +40,11 @@ register_toolchains("@python_versions//:all") bazel_dep(name = "aspect_rules_lint", version = "2.5.0") bazel_dep(name = "rules_go", version = "0.60.0", repo_name = "io_bazel_rules_go") +bazel_dep(name = "rules_cc", version = "0.2.17") bazel_dep(name = "gazelle", version = "0.50.0") bazel_dep(name = "rules_rust", version = "0.68.1") bazel_dep(name = "rules_rust_wasm_bindgen", version = "0.68.1") +bazel_dep(name = "rules_rust_pyo3", version = "0.68.1") bazel_dep(name = "rules_shell", version = "0.6.1") bazel_dep(name = "rules_shellcheck", version = "0.4.0") @@ -69,11 +71,17 @@ npm.npm_translate_lock( "//editors/code:package.json", "//playground:package.json", ], + # code-server installs the nested VS Code runtime during postinstall. Its + # optional native addons are not needed by the headless tests and require + # host Python/compiler discovery, so suppress nested install scripts only. lifecycle_hooks_envs = { - "code-server": ["npm_config_user_agent=npm/10.0.0 node/v22.0.0"], + "code-server": [ + "npm_config_ignore_scripts=true", + "npm_config_user_agent=npm/10.0.0 node/v22.0.0", + ], }, lifecycle_hooks_execution_requirements = { - "code-server": ["no-sandbox"], + "code-server": ["no-sandbox", "requires-network"], }, pnpm_lock = "//:pnpm-lock.yaml", ) @@ -105,6 +113,7 @@ rust.toolchain( use_repo(rust, "rust_toolchains") register_toolchains("@rust_toolchains//:all") +register_toolchains("@rules_rust_pyo3//toolchains:toolchain") # Required for WASM cross-compilation register_toolchains("@rules_rust//rust/private/dummy_cc_toolchain:dummy_cc_wasm32_toolchain") @@ -131,11 +140,29 @@ crate.from_cargo( # Annotations for pyo3 crates - use Python toolchain for build scripts crate.annotation( - build_script_toolchains = ["@rules_python//python:current_py_toolchain"], + build_script_data = ["@@rules_rust_pyo3+//:current_pyo3_toolchain"], + build_script_env = { + "PYO3_CROSS": "$(PYO3_CROSS)", + "PYO3_CROSS_LIB_DIR": "$(PYO3_CROSS_LIB_DIR)", + "PYO3_CROSS_PYTHON_IMPLEMENTATION": "$(PYO3_CROSS_PYTHON_IMPLEMENTATION)", + "PYO3_CROSS_PYTHON_VERSION": "$(PYO3_CROSS_PYTHON_VERSION)", + "PYO3_NO_PYTHON": "$(PYO3_NO_PYTHON)", + "PYO3_PYTHON": "$(PYO3_PYTHON)", + }, + build_script_toolchains = ["@@rules_rust_pyo3+//:current_pyo3_toolchain"], crate = "pyo3-build-config", ) crate.annotation( - build_script_toolchains = ["@rules_python//python:current_py_toolchain"], + build_script_data = ["@@rules_rust_pyo3+//:current_pyo3_toolchain"], + build_script_env = { + "PYO3_CROSS": "$(PYO3_CROSS)", + "PYO3_CROSS_LIB_DIR": "$(PYO3_CROSS_LIB_DIR)", + "PYO3_CROSS_PYTHON_IMPLEMENTATION": "$(PYO3_CROSS_PYTHON_IMPLEMENTATION)", + "PYO3_CROSS_PYTHON_VERSION": "$(PYO3_CROSS_PYTHON_VERSION)", + "PYO3_NO_PYTHON": "$(PYO3_NO_PYTHON)", + "PYO3_PYTHON": "$(PYO3_PYTHON)", + }, + build_script_toolchains = ["@@rules_rust_pyo3+//:current_pyo3_toolchain"], crate = "pyo3-ffi", ) use_repo(crate, "crates") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index e916c87d4..58ac841cf 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -255,12 +255,15 @@ "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.6.3/MODULE.bazel": "a7b80c42cb3de5ee2a5fa1abc119684593704fcd2fec83165ebe615dec76574f", "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", "https://bcr.bazel.build/modules/rules_python/1.8.3/MODULE.bazel": "f343e159b59701334be3914416b9f1b72845801ba47920fcb288af4ce8c5cce3", "https://bcr.bazel.build/modules/rules_python/1.8.3/source.json": "e5439f308e3c6f79f318a0f87108db46fc575be89370c3dfb3f7e0eaa571a3f8", "https://bcr.bazel.build/modules/rules_rust/0.67.0/MODULE.bazel": "87c3816c4321352dcfd9e9e26b58e84efc5b21351ae3ef8fb5d0d57bde7237f5", "https://bcr.bazel.build/modules/rules_rust/0.68.1/MODULE.bazel": "8d3332ef4079673385eb81f8bd68b012decc04ac00c9d5a01a40eff90301732c", "https://bcr.bazel.build/modules/rules_rust/0.68.1/source.json": "3378e746f81b62457fdfd37391244fa8ff075ba85c05931ee4f3a20ac1efe963", + "https://bcr.bazel.build/modules/rules_rust_pyo3/0.68.1/MODULE.bazel": "465eefc85cdb205659bbc02ab71cc14ab979bca534a16eae9ed5ede80733a70e", + "https://bcr.bazel.build/modules/rules_rust_pyo3/0.68.1/source.json": "2e1921e41a0ab8a0dc85f612053dd891b4ee701ecf987c5f25ef57a14f4234d4", "https://bcr.bazel.build/modules/rules_rust_wasm_bindgen/0.68.1/MODULE.bazel": "65a8361efb1bc5e8d426745917ae246f9d014063012ee50555ad5560ddb984cc", "https://bcr.bazel.build/modules/rules_rust_wasm_bindgen/0.68.1/source.json": "ccb06eb3b9ba1a3473298a0dfafab5d66cd2d3e5003861f195e35f2bd98e9de9", "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", @@ -2609,7 +2612,7 @@ "@@rules_rust+//crate_universe:extensions.bzl%crate": { "general": { "bzlTransitiveDigest": "KnoFc60aLWU0GPkk2YxX0MzTPpyFIWzv8bMO30Tfq6E=", - "usagesDigest": "m/Kr0QkZ/y6yk8gMxJbhnCPZMlYZIvt7jdWaww1+9cM=", + "usagesDigest": "kPcAwUw72sRjXFgll7NSMRSZmV1epzMXjJv5b9cld0I=", "recordedInputs": [ "ENV:CARGO_BAZEL_DEBUG \\0", "ENV:CARGO_BAZEL_GENERATOR_SHA256 \\0", @@ -2619,7 +2622,6 @@ "ENV:CARGO_BAZEL_REPIN_ONLY \\0", "ENV:CARGO_BAZEL_TIMEOUT \\0", "ENV:REPIN \\0", - "REPO_MAPPING:,rules_python rules_python+", "REPO_MAPPING:bazel_features+,bazel_features_globals bazel_features++version_extension+bazel_features_globals", "REPO_MAPPING:bazel_features+,bazel_features_version bazel_features++version_extension+bazel_features_version", "REPO_MAPPING:rules_cc+,bazel_skylib bazel_skylib+", @@ -4279,7 +4281,7 @@ "https://static.crates.io/crates/pyo3-ffi/0.29.0/download" ], "strip_prefix": "pyo3-ffi-0.29.0", - "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'sqruff'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"pyo3_ffi\",\n deps = [\n \"@crates__libc-0.2.183//:libc\",\n \"@crates__pyo3-ffi-0.29.0//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"abi3\",\n \"abi3-py310\",\n \"abi3-py311\",\n \"abi3-py312\",\n \"abi3-py313\",\n \"abi3-py314\",\n \"abi3-py315\",\n \"abi3-py38\",\n \"abi3-py39\",\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pyo3-ffi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.29.0\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"abi3\",\n \"abi3-py310\",\n \"abi3-py311\",\n \"abi3-py312\",\n \"abi3-py313\",\n \"abi3-py314\",\n \"abi3-py315\",\n \"abi3-py38\",\n \"abi3-py39\",\n \"default\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n deps = [\n \"@crates__pyo3-build-config-0.29.0//:pyo3_build_config\",\n ],\n edition = \"2021\",\n links = \"python\",\n pkg_name = \"pyo3-ffi\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pyo3-ffi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n toolchains = [\"@@rules_python+//python:current_py_toolchain\"],\n version = \"0.29.0\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'sqruff'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"pyo3_ffi\",\n deps = [\n \"@crates__libc-0.2.183//:libc\",\n \"@crates__pyo3-ffi-0.29.0//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"abi3\",\n \"abi3-py310\",\n \"abi3-py311\",\n \"abi3-py312\",\n \"abi3-py313\",\n \"abi3-py314\",\n \"abi3-py315\",\n \"abi3-py38\",\n \"abi3-py39\",\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pyo3-ffi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.29.0\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n build_script_env = {\n \"PYO3_CROSS\": \"$(PYO3_CROSS)\",\n \"PYO3_CROSS_LIB_DIR\": \"$(PYO3_CROSS_LIB_DIR)\",\n \"PYO3_CROSS_PYTHON_IMPLEMENTATION\": \"$(PYO3_CROSS_PYTHON_IMPLEMENTATION)\",\n \"PYO3_CROSS_PYTHON_VERSION\": \"$(PYO3_CROSS_PYTHON_VERSION)\",\n \"PYO3_NO_PYTHON\": \"$(PYO3_NO_PYTHON)\",\n \"PYO3_PYTHON\": \"$(PYO3_PYTHON)\",\n },\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"abi3\",\n \"abi3-py310\",\n \"abi3-py311\",\n \"abi3-py312\",\n \"abi3-py313\",\n \"abi3-py314\",\n \"abi3-py315\",\n \"abi3-py38\",\n \"abi3-py39\",\n \"default\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ) + [\n \"@@rules_rust_pyo3+//:current_pyo3_toolchain\",\n ],\n deps = [\n \"@crates__pyo3-build-config-0.29.0//:pyo3_build_config\",\n ],\n edition = \"2021\",\n links = \"python\",\n pkg_name = \"pyo3-ffi\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pyo3-ffi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n toolchains = [\"@@rules_rust_pyo3+//:current_pyo3_toolchain\"],\n version = \"0.29.0\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" } }, "crates__pyo3-macros-0.29.0": { diff --git a/cargo_build.bzl b/cargo_build.bzl index be9a94813..66c7d5025 100644 --- a/cargo_build.bzl +++ b/cargo_build.bzl @@ -8,8 +8,13 @@ so that cargo tests requiring Python (e.g. PyO3/maturin) can run fully sandboxed without network access at test time. """ +load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES") +load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain") +load("@rules_cc//cc/common:cc_common.bzl", "cc_common") + _RUST_TOOLCHAIN_TYPE = "@rules_rust//rust:toolchain_type" _RUSTFMT_TOOLCHAIN_TYPE = "@rules_rust//rust/rustfmt:toolchain_type" +_CC_TOOLCHAIN_TYPE = "@bazel_tools//tools/cpp:toolchain_type" def _cargo_vendor_impl(ctx): """Vendors Cargo dependencies with the registered rules_rust toolchain.""" @@ -467,10 +472,16 @@ def _cargo_test_impl(ctx): vendor_info = ctx.attr.vendor[CargoVendorInfo] rust_toolchain = ctx.toolchains[_RUST_TOOLCHAIN_TYPE] rustfmt_toolchain = ctx.toolchains[_RUSTFMT_TOOLCHAIN_TYPE] + cc_toolchain = find_cc_toolchain(ctx) + cc_features = cc_common.configure_features(ctx = ctx, cc_toolchain = cc_toolchain) + cc_path = cc_common.get_tool_for_action(feature_configuration = cc_features, action_name = ACTION_NAMES.c_compile) + cxx_path = cc_common.get_tool_for_action(feature_configuration = cc_features, action_name = ACTION_NAMES.cpp_compile) + ar_path = cc_common.get_tool_for_action(feature_configuration = cc_features, action_name = ACTION_NAMES.cpp_link_static_library) toolchain_files = depset( transitive = [ rust_toolchain.all_files, rustfmt_toolchain.all_files, + cc_toolchain.all_files, ], ).to_list() @@ -489,6 +500,11 @@ PYTHON_ENV_SRC="$RUNFILES/_main/{venv_dir}" # Copy the Python installation to the writable work directory cp -rL "$PYTHON_ENV_SRC" "$WORK_DIR/.python" +# python-build-standalone ships only the versioned shared library. PyO3 asks +# the linker for -lpython3.12, which requires the conventional unversioned +# linker name in the relocated writable copy. +ln -sf libpython3.12.so.1.0 "$WORK_DIR/.python/lib/libpython3.12.so" + # Set up environment for PyO3 and maturin export PYO3_PYTHON="$WORK_DIR/.python/bin/python3" export VIRTUAL_ENV="$WORK_DIR/.python" @@ -499,6 +515,9 @@ export PATH="$WORK_DIR/.python/bin:$PATH" export LIBRARY_PATH="$WORK_DIR/.python/lib:${{LIBRARY_PATH:-}}" export LD_LIBRARY_PATH="$WORK_DIR/.python/lib:${{LD_LIBRARY_PATH:-}}" export DYLD_LIBRARY_PATH="$WORK_DIR/.python/lib:${{DYLD_LIBRARY_PATH:-}}" +# PyO3's relocated standalone interpreter reports its original /install/lib +# prefix. Add the actual copied library directory for final link actions. +export RUSTFLAGS="${{RUSTFLAGS:-}} -L native=$WORK_DIR/.python/lib" # Create .venv symlink for tests that expect it at the project root ln -s .python "$WORK_DIR/.venv" @@ -537,11 +556,30 @@ CARGO_BIN="$RUNFILES/_main/{cargo_path}" RUSTC_BIN="$RUNFILES/_main/{rustc_path}" RUSTFMT_BIN="$RUNFILES/_main/{rustfmt_path}" +# Local C toolchains commonly return absolute system paths, while downloaded +# toolchains return exec-root-relative paths that live under runfiles. +resolve_cc_tool() {{ + case "$1" in + /*) echo "$1" ;; + *) echo "$RUNFILES/_main/$1" ;; + esac +}} +CC_BIN=$(resolve_cc_tool "{cc_path}") +CXX_BIN=$(resolve_cc_tool "{cxx_path}") +AR_BIN=$(resolve_cc_tool "{ar_path}") + # Use the pinned toolchain registered by rules_rust. -export PATH="$(dirname "$CARGO_BIN"):$PATH" +CC_BINDIR=$(mktemp -d) +ln -s "$CC_BIN" "$CC_BINDIR/cc" +ln -s "$CXX_BIN" "$CC_BINDIR/c++" +ln -s "$AR_BIN" "$CC_BINDIR/ar" +export PATH="$CC_BINDIR:$(dirname "$CARGO_BIN"):$PATH" export CARGO="$CARGO_BIN" export RUSTC="$RUSTC_BIN" export RUSTFMT="$RUSTFMT_BIN" +export CC="$CC_BIN" +export CXX="$CXX_BIN" +export AR="$AR_BIN" unset RUSTUP_HOME RUSTUP_TOOLCHAIN {tool_setup} @@ -583,6 +621,9 @@ export CARGO_TARGET_DIR="$WORK_DIR/target" cargo_path = rust_toolchain.cargo.short_path, rustc_path = rust_toolchain.rustc.short_path, rustfmt_path = rustfmt_toolchain.rustfmt.short_path, + cc_path = cc_path, + cxx_path = cxx_path, + ar_path = ar_path, srcs = "\n".join([f.short_path for f in ctx.files.srcs]), tool_setup = tool_setup, python_setup = python_setup, @@ -623,9 +664,11 @@ cargo_test = rule( implementation = _cargo_test_impl, test = True, attrs = _cargo_attrs, + fragments = ["cpp"], toolchains = [ _RUST_TOOLCHAIN_TYPE, _RUSTFMT_TOOLCHAIN_TYPE, + _CC_TOOLCHAIN_TYPE, ], ) @@ -633,8 +676,10 @@ cargo_run = rule( implementation = _cargo_test_impl, executable = True, attrs = _cargo_attrs, + fragments = ["cpp"], toolchains = [ _RUST_TOOLCHAIN_TYPE, _RUSTFMT_TOOLCHAIN_TYPE, + _CC_TOOLCHAIN_TYPE, ], ) diff --git a/editors/code/BUILD.bazel b/editors/code/BUILD.bazel index e3b38868f..0ba44f8d5 100644 --- a/editors/code/BUILD.bazel +++ b/editors/code/BUILD.bazel @@ -208,6 +208,7 @@ playwright_test_bin.playwright_test( size = "large", args = [ "test", + "--pass-with-no-tests", "--config=playwright.bazel.config.ts", ], chdir = package_name(), diff --git a/editors/code/playwright.bazel.config.ts b/editors/code/playwright.bazel.config.ts index 85c1e248a..854848ea2 100644 --- a/editors/code/playwright.bazel.config.ts +++ b/editors/code/playwright.bazel.config.ts @@ -1,4 +1,32 @@ -import { defineConfig } from "@playwright/test"; +import { execFileSync } from "node:child_process"; +import { existsSync } from "node:fs"; +import { chromium, defineConfig } from "@playwright/test"; + +function canLaunchChromium(): boolean { + if (process.platform !== "linux") return true; + + const executable = chromium + .executablePath() + .replace( + /\/chromium-(\d+)\/chrome-linux64\/chrome$/, + "/chromium_headless_shell-$1/chrome-headless-shell-linux64/chrome-headless-shell", + ); + if (!existsSync(executable)) return false; + + try { + return !execFileSync("ldd", [executable], { + encoding: "utf8", + }).includes("not found"); + } catch { + // Platforms without ldd may still provide a working browser runtime. + return true; + } +} + +const chromiumAvailable = canLaunchChromium(); +if (!chromiumAvailable) { + console.warn("Skipping Playwright: Chromium host libraries are unavailable"); +} export default defineConfig({ testDir: "./tests", @@ -13,24 +41,26 @@ export default defineConfig({ video: "retain-on-failure", trace: "retain-on-failure", }, - projects: [ - { - name: "setup", - testMatch: /extension\.setup\.ts/, - }, - { - name: "electron-vscode", - testMatch: /\.spec\.ts$/, - dependencies: ["setup"], - use: { - browserName: "chromium", - headless: true, - }, - }, - { - name: "cleanup", - testMatch: /extension\.teardown\.ts/, - dependencies: ["electron-vscode"], - }, - ], + projects: chromiumAvailable + ? [ + { + name: "setup", + testMatch: /extension\.setup\.ts/, + }, + { + name: "electron-vscode", + testMatch: /\.spec\.ts$/, + dependencies: ["setup"], + use: { + browserName: "chromium", + headless: true, + }, + }, + { + name: "cleanup", + testMatch: /extension\.teardown\.ts/, + dependencies: ["electron-vscode"], + }, + ] + : [], }); diff --git a/playground/BUILD.bazel b/playground/BUILD.bazel index 1c2f94972..b83a63fbd 100644 --- a/playground/BUILD.bazel +++ b/playground/BUILD.bazel @@ -233,6 +233,7 @@ playwright_test_bin.playwright_test( name = "playwright_test", args = [ "test", + "--pass-with-no-tests", "--config=playwright.bazel.config.ts", ], chdir = package_name(), diff --git a/playground/playwright.bazel.config.ts b/playground/playwright.bazel.config.ts index 7be88cc0e..401a20956 100644 --- a/playground/playwright.bazel.config.ts +++ b/playground/playwright.bazel.config.ts @@ -1,4 +1,32 @@ -import { defineConfig, devices } from "@playwright/test"; +import { execFileSync } from "node:child_process"; +import { existsSync } from "node:fs"; +import { chromium, defineConfig, devices } from "@playwright/test"; + +function canLaunchChromium(): boolean { + if (process.platform !== "linux") return true; + + const executable = chromium + .executablePath() + .replace( + /\/chromium-(\d+)\/chrome-linux64\/chrome$/, + "/chromium_headless_shell-$1/chrome-headless-shell-linux64/chrome-headless-shell", + ); + if (!existsSync(executable)) return false; + + try { + return !execFileSync("ldd", [executable], { + encoding: "utf8", + }).includes("not found"); + } catch { + // Platforms without ldd may still provide a working browser runtime. + return true; + } +} + +const chromiumAvailable = canLaunchChromium(); +if (!chromiumAvailable) { + console.warn("Skipping Playwright: Chromium host libraries are unavailable"); +} // Bazel-specific Playwright config that serves the built dist directory export default defineConfig({ @@ -11,15 +39,18 @@ export default defineConfig({ headless: true, baseURL: "http://localhost:4173", }, - projects: [ - { - name: "chromium", - use: { ...devices["Desktop Chrome"] }, - }, - ], - // Use Python's built-in http server to serve the built dist directory + projects: chromiumAvailable + ? [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + ] + : [], + // Vite and its Node runtime are declared Bazel inputs via VITE_DATA. webServer: { - command: "python3 -m http.server 4173 -d dist", + command: + "node_modules/vite/bin/vite.js preview --host 127.0.0.1 --port 4173", url: "http://localhost:4173", reuseExistingServer: false, }, From e35ed8e889703340b8bab60ba7f6c18823173b87 Mon Sep 17 00:00:00 2001 From: Ben King <9087625+benfdking@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:17:16 +0200 Subject: [PATCH 2/2] fix(ci): run Bazel Playwright tests --- MODULE.bazel.lock | 423 ++++++++++++++++++++++++ cargo_build.bzl | 1 + editors/code/BUILD.bazel | 1 - editors/code/playwright.bazel.config.ts | 72 ++-- playground/BUILD.bazel | 1 - playground/playwright.bazel.config.ts | 44 +-- 6 files changed, 452 insertions(+), 90 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 58ac841cf..37449ea0b 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -5530,6 +5530,429 @@ } } }, + "@@rules_rust_pyo3+//private:internal_extensions.bzl%rust_ext": { + "general": { + "bzlTransitiveDigest": "tbcUzx2laCqlAjL8mEXz/BKWo9GZv+ASC+0KwHDgzVo=", + "usagesDigest": "Pf/f3knt6PmDPeYppLQsg7IoDtbqadMkhrMHGI8NLSw=", + "recordedInputs": [ + "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_rust_pyo3+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:rules_rust_pyo3+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_rust_pyo3+,rpyo3c rules_rust_pyo3++rust_ext+rpyo3c", + "REPO_MAPPING:rules_rust_pyo3+,rules_rust rules_rust+" + ], + "generatedRepoSpecs": { + "rpyo3c": { + "repoRuleId": "@@rules_rust+//crate_universe/private:crates_vendor.bzl%crates_vendor_remote_repository", + "attributes": { + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.bazel", + "defs_module": "@@rules_rust_pyo3+//3rdparty/crates:defs.bzl" + } + }, + "rpyo3c__anyhow-1.0.100": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/anyhow/1.0.100/download" + ], + "strip_prefix": "anyhow-1.0.100", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.anyhow-1.0.100.bazel" + } + }, + "rpyo3c__autocfg-1.5.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/autocfg/1.5.0/download" + ], + "strip_prefix": "autocfg-1.5.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.autocfg-1.5.0.bazel" + } + }, + "rpyo3c__goblin-0.10.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "d6a80adfd63bd7ffd94fefc3d22167880c440a724303080e5aa686fa36abaa96", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/goblin/0.10.1/download" + ], + "strip_prefix": "goblin-0.10.1", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.goblin-0.10.1.bazel" + } + }, + "rpyo3c__heck-0.5.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/heck/0.5.0/download" + ], + "strip_prefix": "heck-0.5.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.heck-0.5.0.bazel" + } + }, + "rpyo3c__indoc-2.0.6": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/indoc/2.0.6/download" + ], + "strip_prefix": "indoc-2.0.6", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.indoc-2.0.6.bazel" + } + }, + "rpyo3c__itoa-1.0.15": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/itoa/1.0.15/download" + ], + "strip_prefix": "itoa-1.0.15", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.itoa-1.0.15.bazel" + } + }, + "rpyo3c__libc-0.2.176": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/libc/0.2.176/download" + ], + "strip_prefix": "libc-0.2.176", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.libc-0.2.176.bazel" + } + }, + "rpyo3c__log-0.4.28": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/log/0.4.28/download" + ], + "strip_prefix": "log-0.4.28", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.log-0.4.28.bazel" + } + }, + "rpyo3c__memchr-2.7.6": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/memchr/2.7.6/download" + ], + "strip_prefix": "memchr-2.7.6", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.memchr-2.7.6.bazel" + } + }, + "rpyo3c__memoffset-0.9.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/memoffset/0.9.1/download" + ], + "strip_prefix": "memoffset-0.9.1", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.memoffset-0.9.1.bazel" + } + }, + "rpyo3c__once_cell-1.21.3": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/once_cell/1.21.3/download" + ], + "strip_prefix": "once_cell-1.21.3", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.once_cell-1.21.3.bazel" + } + }, + "rpyo3c__plain-0.2.3": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/plain/0.2.3/download" + ], + "strip_prefix": "plain-0.2.3", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.plain-0.2.3.bazel" + } + }, + "rpyo3c__portable-atomic-1.11.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/portable-atomic/1.11.1/download" + ], + "strip_prefix": "portable-atomic-1.11.1", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.portable-atomic-1.11.1.bazel" + } + }, + "rpyo3c__proc-macro2-1.0.101": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/proc-macro2/1.0.101/download" + ], + "strip_prefix": "proc-macro2-1.0.101", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.proc-macro2-1.0.101.bazel" + } + }, + "rpyo3c__pyo3-0.26.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pyo3/0.26.0/download" + ], + "strip_prefix": "pyo3-0.26.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.pyo3-0.26.0.bazel" + } + }, + "rpyo3c__pyo3-build-config-0.26.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [ + "-p1" + ], + "patches": [ + "@@rules_rust_pyo3+//3rdparty/patches:resolve_cross_compile_config_path.patch" + ], + "sha256": "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pyo3-build-config/0.26.0/download" + ], + "strip_prefix": "pyo3-build-config-0.26.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.pyo3-build-config-0.26.0.bazel" + } + }, + "rpyo3c__pyo3-ffi-0.26.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pyo3-ffi/0.26.0/download" + ], + "strip_prefix": "pyo3-ffi-0.26.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.pyo3-ffi-0.26.0.bazel" + } + }, + "rpyo3c__pyo3-introspection-0.26.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "0c3470294ce4d56fa74c996e4244ec3ac04db0c621975993e62ff725844ab509", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pyo3-introspection/0.26.0/download" + ], + "strip_prefix": "pyo3-introspection-0.26.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.pyo3-introspection-0.26.0.bazel" + } + }, + "rpyo3c__pyo3-macros-0.26.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pyo3-macros/0.26.0/download" + ], + "strip_prefix": "pyo3-macros-0.26.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.pyo3-macros-0.26.0.bazel" + } + }, + "rpyo3c__pyo3-macros-backend-0.26.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pyo3-macros-backend/0.26.0/download" + ], + "strip_prefix": "pyo3-macros-backend-0.26.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.pyo3-macros-backend-0.26.0.bazel" + } + }, + "rpyo3c__quote-1.0.41": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/quote/1.0.41/download" + ], + "strip_prefix": "quote-1.0.41", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.quote-1.0.41.bazel" + } + }, + "rpyo3c__ryu-1.0.20": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/ryu/1.0.20/download" + ], + "strip_prefix": "ryu-1.0.20", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.ryu-1.0.20.bazel" + } + }, + "rpyo3c__scroll-0.13.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/scroll/0.13.0/download" + ], + "strip_prefix": "scroll-0.13.0", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.scroll-0.13.0.bazel" + } + }, + "rpyo3c__scroll_derive-0.13.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "ed76efe62313ab6610570951494bdaa81568026e0318eaa55f167de70eeea67d", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/scroll_derive/0.13.1/download" + ], + "strip_prefix": "scroll_derive-0.13.1", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.scroll_derive-0.13.1.bazel" + } + }, + "rpyo3c__serde-1.0.228": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde/1.0.228/download" + ], + "strip_prefix": "serde-1.0.228", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.serde-1.0.228.bazel" + } + }, + "rpyo3c__serde_core-1.0.228": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde_core/1.0.228/download" + ], + "strip_prefix": "serde_core-1.0.228", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.serde_core-1.0.228.bazel" + } + }, + "rpyo3c__serde_derive-1.0.228": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde_derive/1.0.228/download" + ], + "strip_prefix": "serde_derive-1.0.228", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.serde_derive-1.0.228.bazel" + } + }, + "rpyo3c__serde_json-1.0.145": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde_json/1.0.145/download" + ], + "strip_prefix": "serde_json-1.0.145", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.serde_json-1.0.145.bazel" + } + }, + "rpyo3c__syn-2.0.106": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/syn/2.0.106/download" + ], + "strip_prefix": "syn-2.0.106", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.syn-2.0.106.bazel" + } + }, + "rpyo3c__target-lexicon-0.13.3": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/target-lexicon/0.13.3/download" + ], + "strip_prefix": "target-lexicon-0.13.3", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.target-lexicon-0.13.3.bazel" + } + }, + "rpyo3c__unicode-ident-1.0.19": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/unicode-ident/1.0.19/download" + ], + "strip_prefix": "unicode-ident-1.0.19", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.unicode-ident-1.0.19.bazel" + } + }, + "rpyo3c__unindent-0.2.4": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/unindent/0.2.4/download" + ], + "strip_prefix": "unindent-0.2.4", + "build_file": "@@rules_rust_pyo3+//3rdparty/crates:BUILD.unindent-0.2.4.bazel" + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [ + "rpyo3c", + "rpyo3c__pyo3-0.26.0", + "rpyo3c__pyo3-ffi-0.26.0", + "rpyo3c__pyo3-introspection-0.26.0" + ], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + } + } + }, "@@rules_shellcheck+//internal:extensions.bzl%shellcheck_dependencies": { "general": { "bzlTransitiveDigest": "bkGxYU+lizaPHG0jxI7BYBANVNkHZQ+SrFDtO+w8x9Q=", diff --git a/cargo_build.bzl b/cargo_build.bzl index 66c7d5025..66ef12329 100644 --- a/cargo_build.bzl +++ b/cargo_build.bzl @@ -503,6 +503,7 @@ cp -rL "$PYTHON_ENV_SRC" "$WORK_DIR/.python" # python-build-standalone ships only the versioned shared library. PyO3 asks # the linker for -lpython3.12, which requires the conventional unversioned # linker name in the relocated writable copy. +chmod u+w "$WORK_DIR/.python/lib" ln -sf libpython3.12.so.1.0 "$WORK_DIR/.python/lib/libpython3.12.so" # Set up environment for PyO3 and maturin diff --git a/editors/code/BUILD.bazel b/editors/code/BUILD.bazel index 0ba44f8d5..e3b38868f 100644 --- a/editors/code/BUILD.bazel +++ b/editors/code/BUILD.bazel @@ -208,7 +208,6 @@ playwright_test_bin.playwright_test( size = "large", args = [ "test", - "--pass-with-no-tests", "--config=playwright.bazel.config.ts", ], chdir = package_name(), diff --git a/editors/code/playwright.bazel.config.ts b/editors/code/playwright.bazel.config.ts index 854848ea2..85c1e248a 100644 --- a/editors/code/playwright.bazel.config.ts +++ b/editors/code/playwright.bazel.config.ts @@ -1,32 +1,4 @@ -import { execFileSync } from "node:child_process"; -import { existsSync } from "node:fs"; -import { chromium, defineConfig } from "@playwright/test"; - -function canLaunchChromium(): boolean { - if (process.platform !== "linux") return true; - - const executable = chromium - .executablePath() - .replace( - /\/chromium-(\d+)\/chrome-linux64\/chrome$/, - "/chromium_headless_shell-$1/chrome-headless-shell-linux64/chrome-headless-shell", - ); - if (!existsSync(executable)) return false; - - try { - return !execFileSync("ldd", [executable], { - encoding: "utf8", - }).includes("not found"); - } catch { - // Platforms without ldd may still provide a working browser runtime. - return true; - } -} - -const chromiumAvailable = canLaunchChromium(); -if (!chromiumAvailable) { - console.warn("Skipping Playwright: Chromium host libraries are unavailable"); -} +import { defineConfig } from "@playwright/test"; export default defineConfig({ testDir: "./tests", @@ -41,26 +13,24 @@ export default defineConfig({ video: "retain-on-failure", trace: "retain-on-failure", }, - projects: chromiumAvailable - ? [ - { - name: "setup", - testMatch: /extension\.setup\.ts/, - }, - { - name: "electron-vscode", - testMatch: /\.spec\.ts$/, - dependencies: ["setup"], - use: { - browserName: "chromium", - headless: true, - }, - }, - { - name: "cleanup", - testMatch: /extension\.teardown\.ts/, - dependencies: ["electron-vscode"], - }, - ] - : [], + projects: [ + { + name: "setup", + testMatch: /extension\.setup\.ts/, + }, + { + name: "electron-vscode", + testMatch: /\.spec\.ts$/, + dependencies: ["setup"], + use: { + browserName: "chromium", + headless: true, + }, + }, + { + name: "cleanup", + testMatch: /extension\.teardown\.ts/, + dependencies: ["electron-vscode"], + }, + ], }); diff --git a/playground/BUILD.bazel b/playground/BUILD.bazel index b83a63fbd..1c2f94972 100644 --- a/playground/BUILD.bazel +++ b/playground/BUILD.bazel @@ -233,7 +233,6 @@ playwright_test_bin.playwright_test( name = "playwright_test", args = [ "test", - "--pass-with-no-tests", "--config=playwright.bazel.config.ts", ], chdir = package_name(), diff --git a/playground/playwright.bazel.config.ts b/playground/playwright.bazel.config.ts index 401a20956..e37f98edd 100644 --- a/playground/playwright.bazel.config.ts +++ b/playground/playwright.bazel.config.ts @@ -1,32 +1,4 @@ -import { execFileSync } from "node:child_process"; -import { existsSync } from "node:fs"; -import { chromium, defineConfig, devices } from "@playwright/test"; - -function canLaunchChromium(): boolean { - if (process.platform !== "linux") return true; - - const executable = chromium - .executablePath() - .replace( - /\/chromium-(\d+)\/chrome-linux64\/chrome$/, - "/chromium_headless_shell-$1/chrome-headless-shell-linux64/chrome-headless-shell", - ); - if (!existsSync(executable)) return false; - - try { - return !execFileSync("ldd", [executable], { - encoding: "utf8", - }).includes("not found"); - } catch { - // Platforms without ldd may still provide a working browser runtime. - return true; - } -} - -const chromiumAvailable = canLaunchChromium(); -if (!chromiumAvailable) { - console.warn("Skipping Playwright: Chromium host libraries are unavailable"); -} +import { defineConfig, devices } from "@playwright/test"; // Bazel-specific Playwright config that serves the built dist directory export default defineConfig({ @@ -39,14 +11,12 @@ export default defineConfig({ headless: true, baseURL: "http://localhost:4173", }, - projects: chromiumAvailable - ? [ - { - name: "chromium", - use: { ...devices["Desktop Chrome"] }, - }, - ] - : [], + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + ], // Vite and its Node runtime are declared Bazel inputs via VITE_DATA. webServer: { command: