From feefb4f216db40312cc60a9085c07f3fb9689c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 21 Jun 2026 01:00:24 +0200 Subject: [PATCH 1/5] ci: run tests on PRs and before releases - Add reusable composite action .github/actions/setup-rust that installs the Rust toolchain, sets up cargo caching, and (only on Linux) installs the minimal system libraries gpui needs (wayland, x11-xcb, xkbcommon-x11, fontconfig, alsa, vulkan loader, openssl, zstd). - build.yml: trigger on pull_request:[main] in addition to push:[main]. Replace the previous single test step with two jobs: * test-linux -- fmt --check, clippy -D warnings and cargo test for the workspace excluding ui_gpui (Linux only). * test-gpui -- cargo test -p ui_gpui across Linux, macOS aarch64, macOS x86_64 and Windows. The existing release-style build matrix now needs both test jobs and is skipped for pull requests so PRs only pay for tests. - release.yml: prepend the same two test jobs and make prepare-version depend on them so a release is never cut on a red workspace. Also switch the release build steps over to the composite action and drop the inline Linux-deps block. - The old, much larger X11/XCB/mesa/xrandr/xinerama/xcursor/xi apt-get list is gone; the trimmed list mirrors what zed's CI actually uses for gpui. --- .github/actions/setup-rust/action.yml | 63 +++++++++++++++ .github/workflows/build.yml | 112 +++++++++++++++----------- .github/workflows/release.yml | 102 ++++++++++++----------- 3 files changed, 179 insertions(+), 98 deletions(-) create mode 100644 .github/actions/setup-rust/action.yml diff --git a/.github/actions/setup-rust/action.yml b/.github/actions/setup-rust/action.yml new file mode 100644 index 00000000..8d3cc24b --- /dev/null +++ b/.github/actions/setup-rust/action.yml @@ -0,0 +1,63 @@ +name: Setup Rust toolchain +description: >- + Installs the Rust toolchain, sets up cargo caching, and installs the minimal + Linux build dependencies required for the workspace (gpui in particular). +inputs: + toolchain: + description: Rust toolchain to install (e.g. stable, 1.79.0) + required: false + default: stable + target: + description: Optional rustup target triple to add (e.g. x86_64-unknown-linux-gnu) + required: false + default: "" + components: + description: Comma-separated list of rustup components (e.g. rustfmt,clippy) + required: false + default: "" + cache-key: + description: Shared cache key used by Swatinem/rust-cache + required: false + default: default + cache-save-if: + description: Whether to write back to the cache (set to "false" on PRs to avoid bloat) + required: false + default: "true" + +runs: + using: composite + steps: + - name: Install Rust toolchain + uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7 + with: + toolchain: ${{ inputs.toolchain }} + target: ${{ inputs.target }} + components: ${{ inputs.components }} + override: true + + - name: Cache cargo registry and target + uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + with: + shared-key: ${{ inputs.cache-key }} + save-if: ${{ inputs.cache-save-if }} + + # Minimal set of system libraries required to build the workspace on + # Linux. Mirrors the dependencies gpui pulls in (Wayland, X11/XCB, + # xkbcommon, fontconfig, alsa, vulkan loader) plus the few generic + # libraries used by other crates in the workspace (openssl, zstd). + - name: Install Linux dependencies + if: runner.os == 'Linux' + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + pkg-config \ + build-essential \ + libssl-dev \ + libzstd-dev \ + libfontconfig-dev \ + libwayland-dev \ + libx11-xcb-dev \ + libxkbcommon-x11-dev \ + libasound2-dev \ + libvulkan1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index adc35641..00e861fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,12 +3,73 @@ name: Build on: push: branches: [main] + pull_request: + branches: [main] env: CARGO_TERM_COLOR: always jobs: + test-linux: + name: Test workspace (Linux, excl. ui_gpui) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + components: rustfmt,clippy + cache-key: workspace-linux + cache-save-if: ${{ github.event_name != 'pull_request' }} + + - name: cargo fmt --check + run: cargo fmt --all -- --check + + # We exclude ui_gpui here because gpui is exercised separately on every + # supported platform in the `test-gpui` job. Linting / testing the rest + # of the workspace on Linux is sufficient. + - name: cargo clippy (workspace, excl. ui_gpui) + run: | + cargo clippy \ + --workspace --exclude ui_gpui --all-targets --locked \ + -- -D warnings + + - name: cargo test (workspace, excl. ui_gpui) + run: cargo test --workspace --exclude ui_gpui --locked + + test-gpui: + name: Test ui_gpui (${{ matrix.name }}) + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + name: linux-x86_64 + - os: macos-latest + name: macos-aarch64 + - os: macos-13 + name: macos-x86_64 + - os: windows-latest + name: windows-x86_64 + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-key: ui-gpui-${{ matrix.name }} + cache-save-if: ${{ github.event_name != 'pull_request' }} + + - name: cargo test -p ui_gpui + run: cargo test -p ui_gpui --locked + build: + needs: [test-linux, test-gpui] + # Skip the full release-build matrix for pull requests; running tests is + # enough to gate PRs and the cross-platform build matrix is expensive. + if: github.event_name != 'pull_request' strategy: fail-fast: false # Don't cancel other builds if one fails matrix: @@ -36,60 +97,13 @@ jobs: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup Rust - uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7 + uses: ./.github/actions/setup-rust with: - toolchain: stable target: ${{ matrix.target }} - override: true - - - name: Install Linux dependencies - if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get update - - # Install X11 and XCB development libraries - sudo apt-get install -y \ - build-essential \ - pkg-config \ - libx11-dev \ - libx11-xcb-dev \ - libxcb1-dev \ - libxcb-shape0-dev \ - libxcb-xfixes0-dev \ - libxcb-render0-dev \ - libxcb-render-util0-dev \ - libxcb-randr0-dev \ - libxcb-image0-dev \ - libxcb-util-dev \ - libxcb-cursor-dev \ - libxcb-keysyms1-dev \ - libxcb-icccm4-dev \ - libxkbcommon-dev \ - libxkbcommon-x11-dev \ - libgl1-mesa-dev \ - libglu1-mesa-dev \ - libxrandr-dev \ - libxinerama-dev \ - libxcursor-dev \ - libxi-dev - - # Debug output - echo "=== Checking X11-xcb availability ===" - pkg-config --exists x11-xcb && echo "✓ x11-xcb pkg-config found" || echo "✗ x11-xcb pkg-config missing" - pkg-config --libs x11-xcb 2>/dev/null && echo "✓ x11-xcb libs available" || echo "✗ x11-xcb libs not found" - - echo "=== Library search ===" - find /usr -name "*X11-xcb*" 2>/dev/null | head -5 || echo "No X11-xcb files found" - ldconfig -p | grep -i x11 | grep -i xcb || echo "X11-xcb not in ldconfig" - - echo "=== Environment for build ===" - export PKG_CONFIG_PATH="/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH" - echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" + cache-key: build-${{ matrix.name }} - name: Build uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3 - env: - PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig with: command: build args: --locked --release --target ${{ matrix.target }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 776796c8..8e4f7f8d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,58 @@ env: CARGO_TERM_COLOR: always jobs: + test-linux: + name: Test workspace (Linux, excl. ui_gpui) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + components: rustfmt,clippy + cache-key: workspace-linux + + - name: cargo fmt --check + run: cargo fmt --all -- --check + + - name: cargo clippy (workspace, excl. ui_gpui) + run: | + cargo clippy \ + --workspace --exclude ui_gpui --all-targets --locked \ + -- -D warnings + + - name: cargo test (workspace, excl. ui_gpui) + run: cargo test --workspace --exclude ui_gpui --locked + + test-gpui: + name: Test ui_gpui (${{ matrix.name }}) + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + name: linux-x86_64 + - os: macos-latest + name: macos-aarch64 + - os: macos-13 + name: macos-x86_64 + - os: windows-latest + name: windows-x86_64 + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-key: ui-gpui-${{ matrix.name }} + + - name: cargo test -p ui_gpui + run: cargo test -p ui_gpui --locked + prepare-version: + needs: [test-linux, test-gpui] runs-on: ubuntu-latest permissions: contents: write @@ -165,60 +216,13 @@ jobs: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup Rust - uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7 + uses: ./.github/actions/setup-rust with: - toolchain: stable target: ${{ matrix.target }} - override: true - - - name: Install Linux dependencies - if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get update - - # Install X11 and XCB development libraries - sudo apt-get install -y \ - build-essential \ - pkg-config \ - libx11-dev \ - libx11-xcb-dev \ - libxcb1-dev \ - libxcb-shape0-dev \ - libxcb-xfixes0-dev \ - libxcb-render0-dev \ - libxcb-render-util0-dev \ - libxcb-randr0-dev \ - libxcb-image0-dev \ - libxcb-util-dev \ - libxcb-cursor-dev \ - libxcb-keysyms1-dev \ - libxcb-icccm4-dev \ - libxkbcommon-dev \ - libxkbcommon-x11-dev \ - libgl1-mesa-dev \ - libglu1-mesa-dev \ - libxrandr-dev \ - libxinerama-dev \ - libxcursor-dev \ - libxi-dev - - # Debug output - echo "=== Checking X11-xcb availability ===" - pkg-config --exists x11-xcb && echo "✓ x11-xcb pkg-config found" || echo "✗ x11-xcb pkg-config missing" - pkg-config --libs x11-xcb 2>/dev/null && echo "✓ x11-xcb libs available" || echo "✗ x11-xcb libs not found" - - echo "=== Library search ===" - find /usr -name "*X11-xcb*" 2>/dev/null | head -5 || echo "No X11-xcb files found" - ldconfig -p | grep -i x11 | grep -i xcb || echo "X11-xcb not in ldconfig" - - echo "=== Environment for build ===" - export PKG_CONFIG_PATH="/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH" - echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" + cache-key: build-${{ matrix.name }} - name: Build uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3 - env: - PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig with: command: build args: --locked --release --target ${{ matrix.target }} From 490f492108a5fdad2d488914fb22af96a6742a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 21 Jun 2026 01:14:26 +0200 Subject: [PATCH 2/5] fix(command_executor): mark macOS-only sandbox helpers with cfg shell_command and canonical_working_dir are only used inside the #[cfg(target_os = "macos")] impl that wraps Seatbelt. Without a cfg gate they trip clippy's dead_code lint on Linux/Windows once the new CI test job runs there. Move them under #[cfg(target_os = "macos")] and drop the now-redundant target_family branches in shell_command (which under that cfg are always Unix anyway). --- .../src/sandboxed_executor.rs | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/crates/command_executor/src/sandboxed_executor.rs b/crates/command_executor/src/sandboxed_executor.rs index 671f2d9d..5f932d0b 100644 --- a/crates/command_executor/src/sandboxed_executor.rs +++ b/crates/command_executor/src/sandboxed_executor.rs @@ -325,34 +325,20 @@ impl SandboxedCommandExecutor { } } +#[cfg(target_os = "macos")] fn shell_command(command_line: &str, redirect_stderr: bool) -> (String, Vec) { - #[cfg(target_family = "unix")] - { - let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/bash".to_string()); - let mut args = Vec::new(); - args.push("-c".to_string()); - if redirect_stderr { - args.push(format!("{command_line} 2>&1")); - } else { - args.push(command_line.to_string()); - } - (shell, args) - } - - #[cfg(target_family = "windows")] - { - let shell = "cmd".to_string(); - let mut args = Vec::new(); - args.push("/C".to_string()); - if redirect_stderr { - args.push(format!("{command_line} 2>&1")); - } else { - args.push(command_line.to_string()); - } - (shell, args) + let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/bash".to_string()); + let mut args = Vec::new(); + args.push("-c".to_string()); + if redirect_stderr { + args.push(format!("{command_line} 2>&1")); + } else { + args.push(command_line.to_string()); } + (shell, args) } +#[cfg(target_os = "macos")] fn canonical_working_dir(working_dir: Option<&PathBuf>) -> Result { match working_dir { Some(dir) => { From a6a425d30567a4c1188d92c1013e24369a0b9ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 21 Jun 2026 01:17:35 +0200 Subject: [PATCH 3/5] ci: drop macos-x86_64 from gpui test matrix GitHub's macos-13 runners (which are the only way to get x86_64) have very low capacity and the job sat queued for >10 minutes during the first PR run while the aarch64, Linux and Windows jobs all completed in 4-8 minutes. Release builds still cover x86_64 macOS via the build matrix, so we don't lose meaningful coverage by dropping it here. aarch64 macOS continues to test gpui on the platform that matters most for the project's primary target. --- .github/workflows/build.yml | 2 -- .github/workflows/release.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 00e861fd..ee7b41b3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,8 +48,6 @@ jobs: name: linux-x86_64 - os: macos-latest name: macos-aarch64 - - os: macos-13 - name: macos-x86_64 - os: windows-latest name: windows-x86_64 runs-on: ${{ matrix.os }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8e4f7f8d..ce37fd90 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,8 +46,6 @@ jobs: name: linux-x86_64 - os: macos-latest name: macos-aarch64 - - os: macos-13 - name: macos-x86_64 - os: windows-latest name: windows-x86_64 runs-on: ${{ matrix.os }} From dcc94ae7e4d335e427b82a01fb94ab7be41acb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 21 Jun 2026 01:25:31 +0200 Subject: [PATCH 4/5] fix(command_executor): gate bail import on macOS bail! is only used inside the macOS-only canonical_working_dir helper. Without a cfg gate the import is unused on Linux/Windows and trips clippy's unused_imports lint. --- crates/command_executor/src/sandboxed_executor.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/command_executor/src/sandboxed_executor.rs b/crates/command_executor/src/sandboxed_executor.rs index 5f932d0b..1dcb177e 100644 --- a/crates/command_executor/src/sandboxed_executor.rs +++ b/crates/command_executor/src/sandboxed_executor.rs @@ -1,7 +1,9 @@ use std::path::PathBuf; use std::sync::Arc; -use anyhow::{Result, bail}; +use anyhow::Result; +#[cfg(target_os = "macos")] +use anyhow::bail; use async_trait::async_trait; use sandbox::{SandboxContext, SandboxPolicy}; #[cfg(not(target_os = "macos"))] From 85ec44961863228eeb75d666bd1df46f7ed0358d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 21 Jun 2026 01:31:04 +0200 Subject: [PATCH 5/5] fix(tests): drop assert!(true) in non-macOS sandbox placeholder clippy::assertions_on_constants flags assert!(true). The placeholder test exists only to document that the macOS-specific Seatbelt tests are intentionally skipped on other platforms, so the assertion has no value -- an empty body with a comment is just as informative. --- crates/code_assistant_core/src/tests/sandbox_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/code_assistant_core/src/tests/sandbox_tests.rs b/crates/code_assistant_core/src/tests/sandbox_tests.rs index 7a717c28..cc74597e 100644 --- a/crates/code_assistant_core/src/tests/sandbox_tests.rs +++ b/crates/code_assistant_core/src/tests/sandbox_tests.rs @@ -90,6 +90,6 @@ mod sandbox_tests_placeholder { #[test] fn sandbox_tests_skip_on_non_macos() { // Seatbelt enforcement is macOS-specific, so these tests are skipped elsewhere. - assert!(true); + // Intentionally empty body; presence of this test documents the platform skip. } }