From 3f958ac2fec721c0ded7509d7f764359d72f72d9 Mon Sep 17 00:00:00 2001 From: Dmitriy Kovalenko Date: Tue, 3 Nov 2026 03:56:35 +0000 Subject: [PATCH] Run Bazel CI locally without BuildBuddy credentials (#59055) ## What changed - Remove automatic BuildBuddy configuration and credential forwarding from Bazel CI, release, SDK, and voice builds. Strip remote execution CI configs in the shared wrapper while retaining explicit remote configurations for local use. - Use native Windows host tools and audio dependencies for Windows Bazel actions, forwarding the required toolchain and environment settings. - Initialize message-board MCP servers through a per-session `OnceCell` so server startup does not hold the shared registry lock across an await. - Expose the message-board test helper to the core Bazel package and update the runtime-auth test call for the `reauth` argument. GitOrigin-RevId: 5d5c1f4d71fa841090dea8eec8006380981fb65b --- .../run-argument-comment-lint/action.yml | 14 +- .../run-argument-comment-lint-bazel.sh | 2 +- .github/scripts/run-bazel-ci.sh | 142 ++++++--------- .github/scripts/run_bazel_with_buildbuddy.py | 103 +---------- .../scripts/test_run_bazel_with_buildbuddy.py | 163 ------------------ .github/scripts/test_rusty_v8_bazel.py | 18 +- .github/workflows/bazel.yml | 65 ++++--- .github/workflows/rust-ci.yml | 1 - .github/workflows/rust-release-windows.yml | 3 - .github/workflows/rust-release.yml | 4 - .github/workflows/rusty-v8-release.yml | 2 - .github/workflows/sdk.yml | 2 - .github/workflows/v8-canary.yml | 2 - .../core/src/client_runtime_auth_tests.rs | 1 + codex-rs/docs/bazel.md | 51 +----- codex-rs/ext/agent-message-board/src/mcp.rs | 47 ++--- codex-rs/message-board/BUILD.bazel | 5 + codex-rs/tui/src/app/tests/key_chords.rs | 4 +- .../app/tests/session_lifecycle_requests.rs | 2 +- codex-rs/tui/src/chatwidget/input_restore.rs | 2 +- .../chatwidget/tests/composer_submission.rs | 2 +- codex-rs/tui/src/style.rs | 6 +- codex-rs/tui/src/transcript_view.rs | 6 +- third_party/voice/cargo-ci/produce/action.yml | 6 +- .../voice/cargo-ci/windows-setup/action.yml | 33 ---- 25 files changed, 136 insertions(+), 550 deletions(-) delete mode 100644 third_party/voice/cargo-ci/windows-setup/action.yml diff --git a/.github/actions/run-argument-comment-lint/action.yml b/.github/actions/run-argument-comment-lint/action.yml index 5bcc77bdcf..eb1418dd8c 100644 --- a/.github/actions/run-argument-comment-lint/action.yml +++ b/.github/actions/run-argument-comment-lint/action.yml @@ -5,10 +5,6 @@ inputs: target: description: Runner target passed to prepare-bazel-ci. required: true - buildbuddy-api-key: - description: BuildBuddy API key used by Bazel CI. - required: false - default: "" runs: using: composite @@ -19,19 +15,19 @@ runs: cache-scope: bazel-argument-comment-lint - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - if: ${{ runner.os == 'Windows' && inputs.buildbuddy-api-key == '' }} + if: ${{ runner.os == 'Windows' }} with: python-version: "3.12" architecture: x64 - name: Prepare native Windows audio dependencies - if: ${{ runner.os == 'Windows' && inputs.buildbuddy-api-key == '' }} + if: ${{ runner.os == 'Windows' }} uses: ./third_party/voice/cargo-ci/windows-setup with: target: x86_64-pc-windows-msvc - name: Verify native Windows audio dependencies - if: ${{ runner.os == 'Windows' && inputs.buildbuddy-api-key == '' }} + if: ${{ runner.os == 'Windows' }} shell: bash run: | : "${VOICE_WINDOWS_BAZEL_REPOSITORY:?Windows voice tools are required}" @@ -56,8 +52,6 @@ runs: - name: Run argument comment lint on codex-rs via Bazel if: ${{ runner.os != 'Windows' }} - env: - BUILDBUDDY_API_KEY: ${{ inputs.buildbuddy-api-key }} shell: bash run: | bazel_targets="$(./tools/argument-comment-lint/list-bazel-targets.sh)" @@ -72,8 +66,6 @@ runs: - name: Run argument comment lint on codex-rs via Bazel if: ${{ runner.os == 'Windows' }} - env: - BUILDBUDDY_API_KEY: ${{ inputs.buildbuddy-api-key }} shell: bash run: | ./.github/scripts/run-argument-comment-lint-bazel.sh \ diff --git a/.github/scripts/run-argument-comment-lint-bazel.sh b/.github/scripts/run-argument-comment-lint-bazel.sh index b506227c78..c6607a89aa 100755 --- a/.github/scripts/run-argument-comment-lint-bazel.sh +++ b/.github/scripts/run-argument-comment-lint-bazel.sh @@ -9,7 +9,7 @@ if [[ "${RUNNER_OS:-}" == "Windows" ]]; then # lint aspect can run across the compatible crate graph instead of failing the # whole build after analysis. bazel_lint_args+=("--skip_incompatible_explicit_targets") - if [[ -z "${BUILDBUDDY_API_KEY:-}" && -n "${VOICE_WINDOWS_BAZEL_REPOSITORY:-}" ]]; then + if [[ -n "${VOICE_WINDOWS_BAZEL_REPOSITORY:-}" ]]; then : "${VOICE_WINDOWS_BAZEL_REPOSITORY:?Windows voice tools are required}" : "${VOICE_WINDOWS_SYSTEM_ROOT:?Windows SystemRoot is required}" : "${VOICE_WINDOWS_HOST_ARCH:?Windows host architecture is required}" diff --git a/.github/scripts/run-bazel-ci.sh b/.github/scripts/run-bazel-ci.sh index 07fa1ffe7b..2576e89a31 100755 --- a/.github/scripts/run-bazel-ci.sh +++ b/.github/scripts/run-bazel-ci.sh @@ -69,32 +69,11 @@ run_bazel_with_startup_args() { run_bazel "$@" } -ci_config=ci-linux -case "${RUNNER_OS:-}" in - macOS) - ci_config=ci-macos - ;; - Windows) - if [[ $windows_cross_compile -eq 1 ]]; then - ci_config=ci-windows-cross - else - ci_config=ci-windows - fi - ;; -esac - print_bazel_test_log_tails() { local console_log="$1" local testlogs_dir local -a bazel_info_args=(info) - if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then - # `bazel info` needs the same CI config as the failed test invocation so - # platform-specific output roots match. On Windows, omitting `ci-windows` - # would point at `local_windows-fastbuild` even when the test ran with the - # MSVC host platform under `local_windows_msvc-fastbuild`. - bazel_info_args+=("--config=${ci_config}") - fi # Only pass flags that affect Bazel's output-root selection or repository # lookup. Test/build-only flags such as execution logs or remote download @@ -255,10 +234,8 @@ if [[ ${#bazel_args[@]} -eq 0 || ${#bazel_targets[@]} -eq 0 ]]; then exit 1 fi -if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -z "${BUILDBUDDY_API_KEY:-}" ]]; then - # Windows cross-compilation depends on authenticated RBE. Preserve the local - # Windows build shape when credentials are unavailable. - ci_config=ci-windows +if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 ]]; then + # Run Windows actions with the native MSVC host platform. windows_msvc_host_platform=1 fi @@ -287,22 +264,9 @@ if [[ $remote_download_toplevel -eq 1 ]]; then post_config_bazel_args+=(--remote_download_toplevel) fi -if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -n "${BUILDBUDDY_API_KEY:-}" ]]; then - # `--enable_platform_specific_config` expands `common:windows` on Windows - # hosts after ordinary rc configs, which can override `ci-windows-cross`'s - # RBE host platform. Repeat the host platform on the command line so V8 and - # other genrules execute on Linux RBE workers instead of Git Bash locally. - # - # Bazel also derives the default genrule shell from the client host. Without - # an explicit shell executable, remote Linux actions can be asked to run - # `C:\Program Files\Git\usr\bin\bash.exe`. - post_config_bazel_args+=(--host_platform=//:rbe --shell_executable=/bin/bash) -fi -if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -z "${BUILDBUDDY_API_KEY:-}" ]]; then - # The Windows cross-compile config depends on authenticated remote - # execution. When credentials are unavailable, keep the local build shape - # and its lower concurrency cap. +if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 ]]; then + # Bound concurrent native Windows actions to fit the runner. post_config_bazel_args+=(--jobs=8) fi @@ -324,35 +288,49 @@ if [[ -n "${CODEX_BAZEL_EXECUTION_LOG_COMPACT_DIR:-}" ]]; then fi if [[ "${RUNNER_OS:-}" == "Windows" ]]; then - pass_windows_build_env=1 - if [[ $windows_cross_compile -eq 1 && -n "${BUILDBUDDY_API_KEY:-}" ]]; then - # Remote build actions execute on Linux RBE workers. Passing the Windows - # runner's build environment there makes Bazel genrules try to execute - # C:\Program Files\Git\usr\bin\bash.exe on Linux. - pass_windows_build_env=0 - fi - if [[ $pass_windows_build_env -eq 1 ]]; then - windows_action_env_vars=( - INCLUDE - LIB - LIBPATH - UCRTVersion - UniversalCRTSdkDir - VCINSTALLDIR - VCToolsInstallDir - WindowsLibPath - WindowsSdkBinPath - WindowsSdkDir - WindowsSDKLibVersion - WindowsSDKVersion + windows_action_env_vars=( + INCLUDE + LIB + LIBPATH + UCRTVersion + UniversalCRTSdkDir + VCINSTALLDIR + VCToolsInstallDir + WindowsLibPath + WindowsSdkBinPath + WindowsSdkDir + WindowsSDKLibVersion + WindowsSDKVersion + ) + + for env_var in "${windows_action_env_vars[@]}"; do + if [[ -n "${!env_var:-}" ]]; then + post_config_bazel_args+=("--action_env=${env_var}" "--host_action_env=${env_var}") + fi + done + + if [[ -n "${VOICE_WINDOWS_BAZEL_REPOSITORY:-}" ]]; then + # Reuse the verified native audio inputs for local CI's voice targets. + # These fixed values must be visible during Starlark analysis as well + # as action execution; inherited --action_env values are insufficient. + : "${VOICE_WINDOWS_SYSTEM_ROOT:?Windows SystemRoot is required}" + : "${VOICE_WINDOWS_HOST_ARCH:?Windows host architecture is required}" + # GNU-host lint jobs still need the LLVM linker for their build tools. + if [[ $windows_msvc_host_platform -eq 1 ]]; then + post_config_bazel_args+=("--config=ci-windows-msvc") + fi + post_config_bazel_args+=( + "--workspace_status_command=./scripts/workspace-status.cmd" + "--extra_toolchains=//third_party/voice:windows_pkg_config_toolchain,//third_party/voice:windows_cmake_toolchain" + "--repo_env=BAZEL_MSVC_RUNTIME_VISUAL_STUDIO_EULA=1" + "--inject_repository=voice_windows_tools=${VOICE_WINDOWS_BAZEL_REPOSITORY}" + "--//third_party/voice:windows_installed_tools=@voice_windows_tools//:tools" + "--action_env=SystemRoot=${VOICE_WINDOWS_SYSTEM_ROOT}" + "--host_action_env=SystemRoot=${VOICE_WINDOWS_SYSTEM_ROOT}" + "--action_env=PROCESSOR_ARCHITECTURE=${VOICE_WINDOWS_HOST_ARCH}" + "--host_action_env=PROCESSOR_ARCHITECTURE=${VOICE_WINDOWS_HOST_ARCH}" ) - - for env_var in "${windows_action_env_vars[@]}"; do - if [[ -n "${!env_var:-}" ]]; then - post_config_bazel_args+=("--action_env=${env_var}" "--host_action_env=${env_var}") - fi - done fi if [[ -z "${CODEX_BAZEL_WINDOWS_PATH:-}" ]]; then @@ -360,20 +338,10 @@ if [[ "${RUNNER_OS:-}" == "Windows" ]]; then exit 1 fi - if [[ $pass_windows_build_env -eq 1 ]]; then - post_config_bazel_args+=( - "--action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}" - "--host_action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}" - ) - elif [[ $windows_cross_compile -eq 1 ]]; then - # Remote build actions run on Linux RBE workers. Give their shell snippets - # a Linux PATH while preserving CODEX_BAZEL_WINDOWS_PATH below for local - # Windows test execution. - post_config_bazel_args+=( - "--action_env=PATH=/usr/bin:/bin" - "--host_action_env=PATH=/usr/bin:/bin" - ) - fi + post_config_bazel_args+=( + "--action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}" + "--host_action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}" + ) post_config_bazel_args+=("--test_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}") fi @@ -383,14 +351,8 @@ trap 'rm -f "$bazel_console_log"' EXIT bazel_run_args=( "${bazel_args[@]}" ) -if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then - echo "BuildBuddy API key is available; using remote Bazel configuration." - bazel_run_args+=("--config=${ci_config}") -else - echo "BuildBuddy API key is not available; using local Bazel configuration." - if [[ "${bazel_args[0]}" == "test" ]]; then - bazel_run_args+=("--test_env=INSTA_UPDATE=no") - fi +if [[ "${bazel_args[0]}" == "test" ]]; then + bazel_run_args+=("--test_env=INSTA_UPDATE=no") fi if (( ${#post_config_bazel_args[@]} > 0 )); then bazel_run_args+=("${post_config_bazel_args[@]}") @@ -399,7 +361,7 @@ set +e # Work around Bazel 9 remote repo contents cache / overlay materialization # failures seen in CI (for example "is not a symlink" or permission errors # while materializing external repos such as rules_perl). This only disables -# the startup-level repo contents cache; keyed runs still use BuildBuddy. +# the startup-level repo contents cache. run_bazel_with_startup_args \ --noexperimental_remote_repo_contents_cache \ "${bazel_run_args[@]}" \ diff --git a/.github/scripts/run_bazel_with_buildbuddy.py b/.github/scripts/run_bazel_with_buildbuddy.py index afbf0b656e..267b647ce3 100755 --- a/.github/scripts/run_bazel_with_buildbuddy.py +++ b/.github/scripts/run_bazel_with_buildbuddy.py @@ -1,21 +1,13 @@ #!/usr/bin/env python3 -import json import os import subprocess import sys from collections.abc import Mapping from collections.abc import Sequence -from pathlib import Path -OPENAI_REPOSITORY = "openai/codex" -# Remote configurations select cache/BES/download endpoints. Their -rbe forms -# also select the matching remote executor endpoint. -GENERIC_REMOTE_CONFIG = "buildbuddy-generic" -OPENAI_REMOTE_CONFIG = "buildbuddy-openai" -# These CI configurations require remote build execution. The wrapper supplies -# an RBE configuration, which also includes the common `remote` settings. +# These configs select remote execution, which is unavailable on CI runners. REMOTE_EXECUTION_CONFIGS = { "--config=ci-linux", "--config=ci-macos", @@ -56,68 +48,13 @@ def startup_args(args: Sequence[str], env: Mapping[str, str]) -> list[str]: for arg in configured_startup_args ): # Work around Bazel 9 overlay materialization failures seen in CI. This - # disables only the startup-level repo contents cache; keyed runs still - # use BuildBuddy. + # disables only the startup-level repo contents cache. injected_args.append("--noexperimental_remote_repo_contents_cache") return injected_args -# Only authenticated workflow runs executing trusted upstream code may use the -# OpenAI BuildBuddy host. A pull request event without proof that its head is -# in the upstream repository fails closed to the generic host. -def is_trusted_upstream_run(env: Mapping[str, str]) -> bool: - # `GITHUB_REPOSITORY` is easy to set locally. Requiring GitHub's workflow - # marker prevents a local command from opting itself into the OpenAI host. - if ( - env.get("GITHUB_ACTIONS") != "true" - or env.get("GITHUB_REPOSITORY") != OPENAI_REPOSITORY - ): - return False - # Non-PR workflow runs in `openai/codex` execute upstream refs, so they are - # trusted. Fork code reaches these workflows only through pull requests. - if env.get("GITHUB_EVENT_NAME") != "pull_request": - return True - - event_path = env.get("GITHUB_EVENT_PATH") - if not event_path: - return False - try: - event = json.loads(Path(event_path).read_text(encoding="utf-8")) - except (OSError, json.JSONDecodeError): - return False - - try: - return event["pull_request"]["head"]["repo"]["fork"] is False - except (KeyError, TypeError): - return False - - -def uses_openai_host(env: Mapping[str, str]) -> bool: - return bool(env.get("BUILDBUDDY_API_KEY")) and is_trusted_upstream_run(env) - - -def uses_remote_execution(args: Sequence[str]) -> bool: - try: - separator_idx = args.index("--") - except ValueError: - separator_idx = len(args) - return any(arg in REMOTE_EXECUTION_CONFIGS for arg in args[:separator_idx]) - - -def remote_config(args: Sequence[str], env: Mapping[str, str]) -> str | None: - if not env.get("BUILDBUDDY_API_KEY"): - return None - - config = OPENAI_REMOTE_CONFIG if uses_openai_host(env) else GENERIC_REMOTE_CONFIG - if uses_remote_execution(args): - config += "-rbe" - return config - - def bazel_args_without_remote_execution(args: Sequence[str]) -> list[str]: - # Remote CI configs require BuildBuddy credentials. Removing them preserves - # the local fallback used for fork pull requests. try: separator_idx = args.index("--") except ValueError: @@ -138,26 +75,7 @@ def bazel_args_with_remote_config( if command_idx is None: raise ValueError("expected a Bazel command") - config = remote_config(args, env) - if config is None: - configured_args = bazel_args_without_remote_execution(args) - else: - # `remote_config()` returns a configuration only when this key is present. - api_key = env["BUILDBUDDY_API_KEY"] - remote_args = [ - f"--config={config}", - f"--remote_header=x-buildbuddy-api-key={api_key}", - ] - - # Insert immediately after the Bazel command. This keeps wrapper-added - # options out of positional payloads and lets later CI configs override - # shared RBE defaults such as the Windows cross-compilation exec platforms. - configured_args = [ - *args[: command_idx + 1], - *remote_args, - *args[command_idx + 1 :], - ] - + configured_args = bazel_args_without_remote_execution(args) try: separator_idx = configured_args.index("--") except ValueError: @@ -188,21 +106,6 @@ def bazel_command(*args: str, env: Mapping[str, str] | None = None) -> list[str] def main() -> None: - config = remote_config(sys.argv[1:], os.environ) - if config is None: - print( - "BuildBuddy key unavailable; using local Bazel configuration.", - file=sys.stderr, - ) - else: - host_description = ( - "OpenAI tenant" if uses_openai_host(os.environ) else "generic" - ) - print( - f"Using {host_description} BuildBuddy configuration: {config}.", - file=sys.stderr, - ) - command = bazel_command(*sys.argv[1:]) if os.name == "nt": # Windows CRT exec can split arguments containing spaces and lose the diff --git a/.github/scripts/test_run_bazel_with_buildbuddy.py b/.github/scripts/test_run_bazel_with_buildbuddy.py index 522c3a41f8..c5dd6dc878 100644 --- a/.github/scripts/test_run_bazel_with_buildbuddy.py +++ b/.github/scripts/test_run_bazel_with_buildbuddy.py @@ -1,177 +1,15 @@ #!/usr/bin/env python3 -import json import os import subprocess import sys import unittest from pathlib import Path -from tempfile import TemporaryDirectory import run_bazel_with_buildbuddy class RunBazelWithBuildBuddyTest(unittest.TestCase): - def github_env( - self, - temp_dir: str, - *, - repository: str = "openai/codex", - fork: bool = False, - event_name: str = "pull_request", - ) -> dict[str, str]: - event_path = Path(temp_dir) / "event.json" - event_path.write_text( - json.dumps({"pull_request": {"head": {"repo": {"fork": fork}}}}), - encoding="utf-8", - ) - return { - "BUILDBUDDY_API_KEY": "token", - "GITHUB_ACTIONS": "true", - "GITHUB_EVENT_NAME": event_name, - "GITHUB_EVENT_PATH": str(event_path), - "GITHUB_REPOSITORY": repository, - } - - def test_keyless_invocation_drops_remote_ci_configuration(self) -> None: - self.assertIsNone( - run_bazel_with_buildbuddy.remote_config( - ["build", "--config=ci-linux", "//codex-rs/cli:codex"], - {}, - ) - ) - self.assertEqual( - run_bazel_with_buildbuddy.bazel_args_with_remote_config( - ["build", "--config=ci-linux", "--", "//codex-rs/cli:codex"], - {}, - ), - ["build", "--", "//codex-rs/cli:codex"], - ) - - def test_program_arguments_after_separator_do_not_select_or_lose_rbe(self) -> None: - args = ["run", "//codex-rs/cli:codex", "--", "--config=remote"] - - self.assertEqual( - run_bazel_with_buildbuddy.bazel_args_with_remote_config(args, {}), - args, - ) - self.assertEqual( - run_bazel_with_buildbuddy.remote_config( - args, {"BUILDBUDDY_API_KEY": "fork-token"} - ), - "buildbuddy-generic", - ) - - def test_upstream_push_selects_openai_rbe_before_target_separator(self) -> None: - with TemporaryDirectory() as temp_dir: - env = self.github_env(temp_dir, event_name="push") - - self.assertEqual( - run_bazel_with_buildbuddy.bazel_args_with_remote_config( - ["build", "--config=ci-linux", "--", "//codex-rs/cli:codex"], - env, - ), - [ - "build", - "--config=buildbuddy-openai-rbe", - "--remote_header=x-buildbuddy-api-key=token", - "--config=ci-linux", - "--", - "//codex-rs/cli:codex", - ], - ) - - def test_windows_cross_ci_configuration_follows_remote_configuration(self) -> None: - env = {"BUILDBUDDY_API_KEY": "fork-token"} - - self.assertEqual( - run_bazel_with_buildbuddy.bazel_args_with_remote_config( - ["build", "--config=ci-windows-cross", "//codex-rs/cli:codex"], - env, - ), - [ - "build", - "--config=buildbuddy-generic-rbe", - "--remote_header=x-buildbuddy-api-key=fork-token", - "--config=ci-windows-cross", - "//codex-rs/cli:codex", - ], - ) - - def test_query_remote_configuration_is_inserted_before_expression(self) -> None: - expression = 'kind("rust_library rule", //codex-rs/...)' - env = {"BUILDBUDDY_API_KEY": "fork-token"} - - for command in ("query", "cquery", "aquery"): - with self.subTest(command=command): - self.assertEqual( - run_bazel_with_buildbuddy.bazel_args_with_remote_config( - [ - command, - "--config=ci-windows-cross", - "--output=label", - expression, - ], - env, - ), - [ - command, - "--config=buildbuddy-generic-rbe", - "--remote_header=x-buildbuddy-api-key=fork-token", - "--config=ci-windows-cross", - "--output=label", - expression, - ], - ) - - def test_same_repository_pull_request_selects_openai_host(self) -> None: - with TemporaryDirectory() as temp_dir: - self.assertEqual( - run_bazel_with_buildbuddy.remote_config( - ["build", "--config=ci-v8"], self.github_env(temp_dir) - ), - "buildbuddy-openai-rbe", - ) - - def test_fork_pull_request_cannot_select_openai_host(self) -> None: - with TemporaryDirectory() as temp_dir: - env = self.github_env(temp_dir, fork=True) - - self.assertEqual( - run_bazel_with_buildbuddy.remote_config( - ["build", "--config=ci-v8"], env - ), - "buildbuddy-generic-rbe", - ) - - def test_run_in_fork_repository_cannot_select_openai_host(self) -> None: - with TemporaryDirectory() as temp_dir: - env = self.github_env(temp_dir, repository="contributor/codex") - - self.assertEqual( - run_bazel_with_buildbuddy.remote_config( - ["build", "--config=ci-v8"], env - ), - "buildbuddy-generic-rbe", - ) - - def test_pull_request_without_readable_event_payload_fails_closed(self) -> None: - for event_path in (None, "missing-event.json"): - env = { - "BUILDBUDDY_API_KEY": "token", - "GITHUB_ACTIONS": "true", - "GITHUB_EVENT_NAME": "pull_request", - "GITHUB_REPOSITORY": "openai/codex", - } - if event_path is not None: - env["GITHUB_EVENT_PATH"] = event_path - - with self.subTest(event_path=event_path): - self.assertEqual( - run_bazel_with_buildbuddy.remote_config(["build"], env), - "buildbuddy-generic", - ) - def test_bazel_command_uses_configured_binary_locally(self) -> None: self.assertEqual( run_bazel_with_buildbuddy.bazel_command( @@ -266,7 +104,6 @@ class RunBazelWithBuildBuddyTest(unittest.TestCase): env = os.environ.copy() env["CODEX_BAZEL_BIN"] = sys.executable env.pop("BAZEL_OUTPUT_USER_ROOT", None) - env.pop("BUILDBUDDY_API_KEY", None) env.pop("GITHUB_ACTIONS", None) result = subprocess.run( diff --git a/.github/scripts/test_rusty_v8_bazel.py b/.github/scripts/test_rusty_v8_bazel.py index 2fdb9c562a..b723683525 100644 --- a/.github/scripts/test_rusty_v8_bazel.py +++ b/.github/scripts/test_rusty_v8_bazel.py @@ -72,7 +72,7 @@ class RustyV8BazelTest(unittest.TestCase): with patch.object(rusty_v8_bazel, "MODULE_BAZEL", module_bazel): self.assertEqual("146.4.0", rusty_v8_bazel.command_version(None)) - def test_bazel_commands_use_shared_buildbuddy_remote_config_library(self) -> None: + def test_bazel_commands_use_shared_ci_options(self) -> None: with patch.dict(environ, {}, clear=True): self.assertEqual( [ @@ -86,22 +86,6 @@ class RustyV8BazelTest(unittest.TestCase): "//third_party/v8:release", ), ) - with patch.dict(environ, {"BUILDBUDDY_API_KEY": "token"}, clear=True): - self.assertEqual( - [ - "bazel", - "build", - "--config=buildbuddy-generic-rbe", - "--remote_header=x-buildbuddy-api-key=token", - "--config=ci-v8", - "//third_party/v8:release", - ], - rusty_v8_bazel.bazel_command( - "build", - "--config=ci-v8", - "//third_party/v8:release", - ), - ) def test_release_pair_labels_and_staged_names_distinguish_sandbox_artifacts( self, diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 9bf3ebf548..af8b5ba14b 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -17,9 +17,7 @@ jobs: test: # PRs use the sharded Windows cross-compiled test jobs below. Post-merge # pushes to main also run the native Windows test job for broader Windows - # signal without putting PR latency back on the critical path. When - # Code-mode unit tests run on every Bazel target. When authenticated RBE - # is available, the Windows-cross shards exercise the source-built V8 path. + # signal without putting PR latency back on the critical path. timeout-minutes: 30 strategy: fail-fast: false @@ -72,8 +70,6 @@ jobs: - name: Check MODULE.bazel.lock is up to date if: matrix.os == 'ubuntu-24.04' && matrix.target == 'x86_64-unknown-linux-gnu' - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: ./scripts/check-module-bazel-lock.sh @@ -86,8 +82,6 @@ jobs: echo "CODEX_COMPAT_RELEASES=$releases" >> "$GITHUB_ENV" - name: bazel test //... - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: | bazel_targets=( @@ -139,9 +133,7 @@ jobs: uses: ./.github/actions/check-clean-worktree test-windows-shard: - # Split the Windows Bazel test leg across separate Windows hosts. Jobs with - # BuildBuddy credentials use Linux RBE for build actions; test execution - # remains on a Windows runner. + # Build and test Windows shards on separate Windows runners. timeout-minutes: 30 strategy: fail-fast: false @@ -164,7 +156,7 @@ jobs: with: persist-credentials: false - - name: Test BuildBuddy Bazel wrapper + - name: Test Bazel command wrapper if: matrix.shard == 1 shell: pwsh run: python .github/scripts/test_run_bazel_with_buildbuddy.py @@ -184,11 +176,16 @@ jobs: # the PR-blocking critical path after the useful test work is done. cache-scope: bazel-test + - name: Prepare native Windows audio dependencies + if: runner.os == 'Windows' + uses: ./third_party/voice/cargo-ci/windows-setup + with: + target: x86_64-pc-windows-msvc + - name: bazel test shard env: BAZEL_TEST_SHARD: ${{ matrix.shard }} BAZEL_TEST_SHARD_COUNT: 4 - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: | set -euo pipefail @@ -283,9 +280,13 @@ jobs: target: x86_64-pc-windows-msvc cache-scope: bazel-${{ github.job }} + - name: Prepare native Windows audio dependencies + if: runner.os == 'Windows' + uses: ./third_party/voice/cargo-ci/windows-setup + with: + target: x86_64-pc-windows-msvc + - name: bazel test //... - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: | bazel_targets=( @@ -376,6 +377,12 @@ jobs: target: ${{ matrix.target }} cache-scope: bazel-${{ github.job }} + - name: Prepare native Windows audio dependencies + if: runner.os == 'Windows' + uses: ./third_party/voice/cargo-ci/windows-setup + with: + target: x86_64-pc-windows-msvc + - name: Resolve app-server/exec-server compatibility releases if: runner.os == 'Linux' env: @@ -385,8 +392,6 @@ jobs: echo "CODEX_COMPAT_RELEASES=$releases" >> "$GITHUB_ENV" - name: bazel build --config=clippy lint targets - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: | bazel_clippy_args=( @@ -397,19 +402,9 @@ jobs: bazel_wrapper_args=() bazel_target_list_args=() if [[ "${RUNNER_OS}" == "Windows" ]]; then - # Keep this aligned with the fast Windows Bazel test job: use - # Linux RBE for clippy build actions while targeting Windows - # gnullvm. Fork/community PRs without the BuildBuddy secret fall - # back inside `run-bazel-ci.sh` to the previous local Windows MSVC - # host-platform shape. bazel_wrapper_args+=(--windows-cross-compile) bazel_target_list_args+=(--windows-cross-compile) - if [[ -z "${BUILDBUDDY_API_KEY:-}" ]]; then - # The fork fallback can see incompatible explicit Windows-cross - # internal test binaries in the generated target list. Preserve - # the old local-fallback behavior there. - bazel_clippy_args+=(--skip_incompatible_explicit_targets) - fi + bazel_clippy_args+=(--skip_incompatible_explicit_targets) fi bazel_target_lines="$(./scripts/list-bazel-clippy-targets.sh "${bazel_target_list_args[@]}")" @@ -483,6 +478,12 @@ jobs: target: ${{ matrix.target }} cache-scope: bazel-${{ github.job }} + - name: Prepare native Windows audio dependencies + if: runner.os == 'Windows' + uses: ./third_party/voice/cargo-ci/windows-setup + with: + target: x86_64-pc-windows-msvc + - name: Resolve app-server/exec-server compatibility releases if: runner.os == 'Linux' env: @@ -492,8 +493,6 @@ jobs: echo "CODEX_COMPAT_RELEASES=$releases" >> "$GITHUB_ENV" - name: bazel build verify-release-build targets - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: | # This job exists to compile Rust code behind @@ -504,11 +503,7 @@ jobs: # Rust debug assertions explicitly. bazel_wrapper_args=() if [[ "${RUNNER_OS}" == "Windows" ]]; then - # This is build-only signal, so use the same Linux-RBE - # cross-compile path as the fast Windows test and clippy jobs. - # Fork/community PRs without the BuildBuddy secret fall back - # inside `run-bazel-ci.sh` to the previous local Windows MSVC - # host-platform shape. + # Use the same native host toolchain as the Windows test shards. bazel_wrapper_args+=(--windows-cross-compile) fi @@ -537,8 +532,6 @@ jobs: - name: Verify Bazel builds bwrap if: runner.os == 'Linux' - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: | ./.github/scripts/run-bazel-ci.sh \ diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 84cef8b9a1..f6c3ca0226 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -212,7 +212,6 @@ jobs: uses: ./.github/actions/run-argument-comment-lint with: target: ${{ runner.os }} - buildbuddy-api-key: ${{ secrets.BUILDBUDDY_API_KEY }} - name: Check for a clean worktree if: always() && !cancelled() && steps.argument_comment_lint_gate.outputs.run == 'true' diff --git a/.github/workflows/rust-release-windows.yml b/.github/workflows/rust-release-windows.yml index 7514d66474..cac95e6878 100644 --- a/.github/workflows/rust-release-windows.yml +++ b/.github/workflows/rust-release-windows.yml @@ -124,8 +124,6 @@ jobs: - name: Build Bazel release binaries and symbols if: ${{ matrix.build-system == 'bazel' }} uses: ./.github/actions/build-bazel-release - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} with: target: ${{ matrix.target }} bundle: ${{ matrix.bundle }} @@ -253,7 +251,6 @@ jobs: ARCH: ${{ matrix.arch }} VOICE_ARCH: ${{ matrix.arch }} # Use local Bazel while BuildBuddy credentials are unavailable. - BUILDBUDDY_API_KEY: "" run: | (cd codex-rs && cargo update --workspace) python .github/scripts/watch_voice_bazel.py "$(cygpath -w "$BASH")" ./.github/scripts/run-bazel-ci.sh \ diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index 4c6c9a4251..9878d3cdda 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -277,8 +277,6 @@ jobs: - name: Build Bazel release binaries and symbols if: ${{ matrix.build-system == 'bazel' }} uses: ./.github/actions/build-bazel-release - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} with: target: ${{ matrix.target }} bundle: ${{ matrix.bundle }} @@ -327,7 +325,6 @@ jobs: env: APP_TARGET: ${{ matrix.target }} # Use local Bazel while BuildBuddy credentials are unavailable. - BUILDBUDDY_API_KEY: "" run: | set -euo pipefail cd "$GITHUB_WORKSPACE" @@ -607,7 +604,6 @@ jobs: TARGET: ${{ matrix.target }} PREFIX: ${{ matrix.prefix }} # Use local Bazel while BuildBuddy credentials are unavailable. - BUILDBUDDY_API_KEY: "" run: | set -euo pipefail # Release tags bump Cargo.toml without rewriting the workspace lockfile. diff --git a/.github/workflows/rusty-v8-release.yml b/.github/workflows/rusty-v8-release.yml index 08e6d69632..2208fe96ea 100644 --- a/.github/workflows/rusty-v8-release.yml +++ b/.github/workflows/rusty-v8-release.yml @@ -168,7 +168,6 @@ jobs: - name: Build Bazel V8 release pair env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} PLATFORM: ${{ matrix.platform }} SANDBOX: ${{ matrix.sandbox }} TARGET: ${{ matrix.target }} @@ -200,7 +199,6 @@ jobs: - name: Stage release pair env: BAZEL_CONFIG: ${{ matrix.bazel_config }} - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} PLATFORM: ${{ matrix.platform }} SANDBOX: ${{ matrix.sandbox }} TARGET: ${{ matrix.target }} diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml index cc42db2d65..a920433188 100644 --- a/.github/workflows/sdk.yml +++ b/.github/workflows/sdk.yml @@ -79,8 +79,6 @@ jobs: - name: Build codex and the code-mode host with Bazel id: build_bazel - env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} shell: bash run: | set -euo pipefail diff --git a/.github/workflows/v8-canary.yml b/.github/workflows/v8-canary.yml index 65eca0493b..2beb49a085 100644 --- a/.github/workflows/v8-canary.yml +++ b/.github/workflows/v8-canary.yml @@ -181,7 +181,6 @@ jobs: - name: Build Bazel V8 release pair env: - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} PLATFORM: ${{ matrix.platform }} SANDBOX: ${{ matrix.sandbox }} TARGET: ${{ matrix.target }} @@ -211,7 +210,6 @@ jobs: - name: Stage release pair env: BAZEL_CONFIG: ${{ matrix.bazel_config }} - BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} PLATFORM: ${{ matrix.platform }} SANDBOX: ${{ matrix.sandbox }} TARGET: ${{ matrix.target }} diff --git a/codex-rs/core/src/client_runtime_auth_tests.rs b/codex-rs/core/src/client_runtime_auth_tests.rs index 35a41b68cd..432db1606b 100644 --- a/codex-rs/core/src/client_runtime_auth_tests.rs +++ b/codex-rs/core/src/client_runtime_auth_tests.rs @@ -118,6 +118,7 @@ async fn selected_runtime_transport_stays_revoked(mode: RuntimeAuthMode) { RequestRouteTelemetry::for_endpoint("/responses"), &http::HeaderMap::new(), /*parent_routing_affinity*/ None, + /*reauth*/ false, ) .await; assert!(matches!( diff --git a/codex-rs/docs/bazel.md b/codex-rs/docs/bazel.md index e85799d98d..6a740a0877 100644 --- a/codex-rs/docs/bazel.md +++ b/codex-rs/docs/bazel.md @@ -76,20 +76,7 @@ configurations. ### All remote configurations -GitHub Actions routes Bazel build and output-resolution commands through -`.github/scripts/run_bazel_with_buildbuddy.py`. Higher-level helpers such as -`.github/scripts/run-bazel-ci.sh` and `.github/scripts/rusty_v8_bazel.py` -delegate remote configuration selection to that wrapper. The wrapper reads the -GitHub Actions repository and event payload rather than relying on workflow -files to duplicate tenant-selection logic. It also normalizes GitHub Actions -startup options so all Bazel launches in a job reuse the same server and -in-memory analysis cache. Target-discovery and lockfile helpers delegate to the -same wrapper so their callers do not need to select CI-specific startup options. - -Loading-phase target-discovery `bazel query` commands run locally because they -only enumerate labels and do not need remote caches or execution. - -The `Cache/BES` host is also used for remote downloads. +CI executes Bazel actions on its runners. The following configurations are available for explicit local use. | Invocation/config | Key Required | Cache/BES | Build exec | Test exec | | ------------------------------------------- | ------------ | ---------------------- | ---------- | --------- | @@ -99,42 +86,6 @@ The `Cache/BES` host is also used for remote downloads. | `bazel ... --config=buildbuddy-openai` | Yes | `openai.buildbuddy.io` | Local | Local | | `bazel ... --config=buildbuddy-openai-rbe` | Yes | `openai.buildbuddy.io` | Remote | Remote | -Without an API key, the wrapper removes remote CI configurations and runs -locally. With a key, workflows choose the host as follows: - -| Run | Key | Uses OpenAI BuildBuddy Host | -| ------------------------------------------------ | --- | --------------------------- | -| Push to `main` in `openai/codex` | Yes | Yes | -| `workflow_dispatch` in `openai/codex` | Yes | Yes | -| Same-repository pull request in `openai/codex` | Yes | Yes | -| Fork pull request into `openai/codex` | No | No; local | -| Push or `workflow_dispatch` in a fork with a key | Yes | No; generic host | -| Pull request run in a fork repository with a key | Yes | No; generic host | - -CI configurations determine whether builds and tests execute remotely: - -| CI config | Remote config | Build exec | Test exec | -| ------------------- | ------------- | ----------- | ----------- | -| `ci-linux` | `*-rbe` | Remote host | Remote host | -| `ci-v8` | `*-rbe` | Remote host | Remote host | -| `ci-macos` | `*-rbe` | Remote host | Local | -| `ci-windows-cross` | `*-rbe` | Remote host | Local | -| `ci-windows` | non-RBE | Local | Local | -| Keyless CI fallback | none | Local | Local | - -To exercise the generic remote configuration with your key: - -```bash -BUILDBUDDY_API_KEY=... GITHUB_REPOSITORY=my-fork/codex \ - ./.github/scripts/run_bazel_with_buildbuddy.py \ - build --config=ci-linux //codex-rs/cli:codex -``` - -The wrapper selects the OpenAI host only inside GitHub Actions for a trusted -run in `openai/codex`. A missing or malformed pull request event -payload fails closed to the generic host. For local OpenAI host access, use -the `user.bazelrc` configuration above. - ## Evolving the setup When you add or change Rust dependencies, update the Cargo.toml/Cargo.lock as normal. diff --git a/codex-rs/ext/agent-message-board/src/mcp.rs b/codex-rs/ext/agent-message-board/src/mcp.rs index eb3ec368b9..441f5b7ae8 100644 --- a/codex-rs/ext/agent-message-board/src/mcp.rs +++ b/codex-rs/ext/agent-message-board/src/mcp.rs @@ -23,15 +23,16 @@ use codex_protocol::error::CodexErr; use codex_protocol::error::Result; use std::collections::HashMap; use std::sync::Arc; +use std::sync::Mutex; use std::sync::Weak; -use tokio::sync::Mutex; +use tokio::sync::OnceCell; /// Shared launchers opened by the existing board factory when the MCP flag is enabled. #[derive(Default)] pub struct McpBoards { - servers: Mutex>>, + servers: Mutex>>>, } -struct Binding(Arc); +struct Binding(Arc>); struct PendingMcpRefresh; impl McpBoards { @@ -42,25 +43,28 @@ impl McpBoards { caller: ThreadId, host: Arc, ) -> Result<()> { - let mut servers = self.servers.lock().await; - servers.retain(|_, server| server.strong_count() > 0); - let server = match servers.get(&tree).and_then(Weak::upgrade) { - Some(server) => server, - None => { - let server = Arc::new( - launch_in_memory() - .await - .map_err(|error| CodexErr::Io(std::io::Error::other(error)))?, - ); - servers.insert(tree, Arc::downgrade(&server)); - server - } + let slot = { + let mut servers = self + .servers + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + servers.retain(|_, server| server.strong_count() > 0); + let entry = servers.entry(tree).or_default(); + entry.upgrade().unwrap_or_else(|| { + let slot = Arc::new(OnceCell::new()); + *entry = Arc::downgrade(&slot); + slot + }) }; + let server = slot + .get_or_try_init(launch_in_memory) + .await + .map_err(|error| CodexErr::Io(std::io::Error::other(error)))?; server .bind_agent(tree, caller, host) .await .map_err(|error| CodexErr::Io(std::io::Error::other(error)))?; - store.insert(Binding(server)); + store.insert(Binding(slot)); store.insert(PendingMcpRefresh); Ok(()) } @@ -96,18 +100,21 @@ impl McpServerContributor for McpBoards { Box::pin(async move { let Some(binding) = context .thread_store() - .and_then(|store| store.get::()) + .and_then(ExtensionData::get::) else { return Vec::new(); }; - let Ok(authorization) = binding.0.authorization().to_str() else { + let Some(server) = binding.0.get() else { + return Vec::new(); + }; + let Ok(authorization) = server.authorization().to_str() else { return Vec::new(); }; vec![McpServerContribution::Set { name: "codex_message_board".into(), config: Box::new(McpServerConfig { transport: McpServerTransportConfig::StreamableHttp { - url: binding.0.url().into(), + url: server.url().into(), bearer_token_env_var: None, http_headers: Some([("Authorization".into(), authorization.into())].into()), env_http_headers: None, diff --git a/codex-rs/message-board/BUILD.bazel b/codex-rs/message-board/BUILD.bazel index a51e5a272c..8744470f2a 100644 --- a/codex-rs/message-board/BUILD.bazel +++ b/codex-rs/message-board/BUILD.bazel @@ -1,5 +1,10 @@ load("//:defs.bzl", "codex_rust_crate") +exports_files( + ["tests/common/mod.rs"], + visibility = ["//codex-rs/core:__pkg__"], +) + codex_rust_crate( name = "message-board", crate_name = "codex_message_board", diff --git a/codex-rs/tui/src/app/tests/key_chords.rs b/codex-rs/tui/src/app/tests/key_chords.rs index 991d5efcc4..89624bf43e 100644 --- a/codex-rs/tui/src/app/tests/key_chords.rs +++ b/codex-rs/tui/src/app/tests/key_chords.rs @@ -78,7 +78,7 @@ async fn empty_thread_backend_chord_preserves_draft_until_first_submission() -> .apply_external_edit("first draft".to_string()); app.chat_widget .set_new_backend_control(Some("Cloud".to_string())); - let screen = render_bottom_popup(&app.chat_widget, 80); + let screen = render_bottom_popup(&app.chat_widget, /*width*/ 80); insta::assert_snapshot!(screen.lines().find(|line| line.trim_start().starts_with("Cloud")).unwrap().trim(), @"Cloud ⌃x b to cycle"); // Cursor movement remains available while the backend selector is visible. @@ -110,7 +110,7 @@ async fn empty_thread_backend_chord_preserves_draft_until_first_submission() -> app.chat_widget.handle_key_event(KeyCode::Enter.into()); assert!( - !render_bottom_popup(&app.chat_widget, 80) + !render_bottom_popup(&app.chat_widget, /*width*/ 80) .lines() .any(|line| line.trim_start().starts_with("Cloud")) ); diff --git a/codex-rs/tui/src/app/tests/session_lifecycle_requests.rs b/codex-rs/tui/src/app/tests/session_lifecycle_requests.rs index 1e373fc440..ca94cd6ebf 100644 --- a/codex-rs/tui/src/app/tests/session_lifecycle_requests.rs +++ b/codex-rs/tui/src/app/tests/session_lifecycle_requests.rs @@ -4789,7 +4789,7 @@ fn fresh_session_keeps_its_name_and_draft_when_cycling_backends() -> Result<()> backends.session_at_mut(backends.displayed), AppEvent::ChooseNewSessionCheckout { name: None }, ).await?; - assert!(render_bottom_popup(&app.chat_widget, 80).contains("Use current Git worktree")); + assert!(render_bottom_popup(&app.chat_widget, /*width*/ 80).contains("Use current Git worktree")); app.chat_widget.handle_key_event(KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE)); assert_eq!(app.current_displayed_thread_id(), Some(thread_id)); assert_eq!(recorded_params(&requests, "thread/start").len(), 1); diff --git a/codex-rs/tui/src/chatwidget/input_restore.rs b/codex-rs/tui/src/chatwidget/input_restore.rs index e6dfcfad6c..4c00af8a49 100644 --- a/codex-rs/tui/src/chatwidget/input_restore.rs +++ b/codex-rs/tui/src/chatwidget/input_restore.rs @@ -577,7 +577,7 @@ impl ChatWidget { } pub(super) fn restore_composer_state(&mut self, composer: ThreadComposerState) { - self.restore_composer_state_with_shell_mode(composer, None); + self.restore_composer_state_with_shell_mode(composer, /*shell_mode*/ None); } fn restore_composer_state_with_shell_mode( diff --git a/codex-rs/tui/src/chatwidget/tests/composer_submission.rs b/codex-rs/tui/src/chatwidget/tests/composer_submission.rs index 81e949b919..88222d0ec0 100644 --- a/codex-rs/tui/src/chatwidget/tests/composer_submission.rs +++ b/codex-rs/tui/src/chatwidget/tests/composer_submission.rs @@ -1184,7 +1184,7 @@ async fn startup_draft_handoff_preserves_literal_and_shell_bang() { ] { let (mut source, _rx, _ops) = make_chatwidget_manual(/*model_override*/ None).await; source.bottom_pane.insert_str(&format!("x{text}")); - source.bottom_pane.set_composer_cursor(0); + source.bottom_pane.set_composer_cursor(/*cursor*/ 0); source.handle_key_event(KeyEvent::from(KeyCode::Delete)); let draft = source.composer_draft_snapshot(); assert_eq!(draft.text, text); diff --git a/codex-rs/tui/src/style.rs b/codex-rs/tui/src/style.rs index dab0e03dce..5f94a36f02 100644 --- a/codex-rs/tui/src/style.rs +++ b/codex-rs/tui/src/style.rs @@ -183,8 +183,10 @@ pub(crate) fn quiet_workspace_style() -> Style { let Some(bg) = default_bg() else { return base.fg(Color::Reset).bg(Color::Reset).dim(); }; - let fill = best_color(blend(user_message_bg_rgb(bg), bg, 0.40)); - let foreground = default_fg().map_or(Color::Reset, |fg| best_color(blend(fg, bg, 0.66))); + let fill = best_color(blend(user_message_bg_rgb(bg), bg, /*alpha*/ 0.40)); + let foreground = default_fg().map_or(Color::Reset, |fg| { + best_color(blend(fg, bg, /*alpha*/ 0.66)) + }); base.bg(fill).fg(readable_color_on(foreground, Some(fill))) } diff --git a/codex-rs/tui/src/transcript_view.rs b/codex-rs/tui/src/transcript_view.rs index 226ef9a7e3..940c97f1af 100644 --- a/codex-rs/tui/src/transcript_view.rs +++ b/codex-rs/tui/src/transcript_view.rs @@ -365,11 +365,11 @@ impl TranscriptView { lines.extend_from_slice(auxiliary); (!lines.is_empty()).then_some(lines) }; - self.sync_search_live_tail(width, None, lines); + self.sync_search_live_tail(width, /*key*/ None, lines); if self.detailed { - self.sync_live_tail(width, None, lines); + self.sync_live_tail(width, /*key*/ None, lines); } else { - self.sync_live_activity_tail(width, None, expanded && disclose, |width| { + self.sync_live_activity_tail(width, /*key*/ None, expanded && disclose, |width| { let activity = active.map_or_else(Vec::new, |cell| { if disclose && expanded { cell.expanded_hyperlink_lines(width) diff --git a/third_party/voice/cargo-ci/produce/action.yml b/third_party/voice/cargo-ci/produce/action.yml index 2265833070..d1d39fbfe1 100644 --- a/third_party/voice/cargo-ci/produce/action.yml +++ b/third_party/voice/cargo-ci/produce/action.yml @@ -7,9 +7,6 @@ inputs: windows-tools: description: Directory containing the public Windows voice bootstrap default: .github/scripts - buildbuddy-api-key: - description: Optional BuildBuddy credential for trusted CI builds - default: "" runs: using: composite steps: @@ -23,14 +20,13 @@ runs: cache-scope: cargo-voice-native - name: Set up Windows voice build tools if: runner.os == 'Windows' - uses: ./third_party/voice/cargo-ci/windows-setup + uses: ./.github/actions/setup-bazel-windows with: target: ${{ inputs.target }} windows-tools: ${{ inputs.windows-tools }} - name: Build and stage native dependencies shell: bash env: - BUILDBUDDY_API_KEY: ${{ inputs.buildbuddy-api-key }} TARGET: ${{ inputs.target }} run: | set -euo pipefail diff --git a/third_party/voice/cargo-ci/windows-setup/action.yml b/third_party/voice/cargo-ci/windows-setup/action.yml deleted file mode 100644 index c5b747175c..0000000000 --- a/third_party/voice/cargo-ci/windows-setup/action.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Set up Windows voice build tools -description: Prepare verified native Windows voice tools for Bazel. -inputs: - target: - description: Native Windows target triple - required: true - windows-tools: - description: Directory containing the public Windows voice bootstrap - default: .github/scripts -runs: - using: composite - steps: - - uses: ./.github/actions/setup-msvc-env - with: - target: ${{ inputs.target }} - - name: Install verified public Windows tools - shell: pwsh - env: - WINDOWS_TOOLS: ${{ inputs.windows-tools }} - TARGET: ${{ inputs.target }} - run: | - ./.github/scripts/compute-bazel-windows-path.ps1 - $manifest = Get-Content -Raw "$env:WINDOWS_TOOLS/voice-cygwin-snapshot.json" | ConvertFrom-Json - $pin = $manifest.archive - $archive = Join-Path $env:RUNNER_TEMP $pin.name - Invoke-WebRequest "https://github.com/openai/codex/releases/download/$($pin.tag)/$($pin.name)" -OutFile $archive - & "$env:WINDOWS_TOOLS/setup-voice-windows.ps1" -Target $env:TARGET -SnapshotArchive $archive - if (-not $env:SystemRoot) { throw "Windows SystemRoot is required" } - "VOICE_WINDOWS_SYSTEM_ROOT=$env:SystemRoot" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append - $hostArch = $env:PROCESSOR_ARCHITEW6432 - if (-not $hostArch) { $hostArch = $env:PROCESSOR_ARCHITECTURE } - if (-not $hostArch) { throw "Windows host architecture is required" } - "VOICE_WINDOWS_HOST_ARCH=$hostArch" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append