ci(distro): add Rocky 10 package test + update to v0.75.0 artifacts #314
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Linux CI | |
| on: | |
| push: | |
| branches: [main, 'sid/**'] | |
| paths: | |
| - 'flake.nix' | |
| - 'flake.lock' | |
| - 'nix/**' | |
| - 'vendor/**' | |
| - 'cmuxd/**' | |
| - 'cmux-linux/**' | |
| - 'dist/linux/**' | |
| - 'ghostty' | |
| - '.github/workflows/linux-ci.yml' | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: linux-ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # ── Nix Flake: dev shell + checks ────────────────────────────────── | |
| nix-flake: | |
| name: Nix flake check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Strip non-version tags from ghostty | |
| run: git -C ghostty tag -l 'xcframework-*' | xargs git -C ghostty tag -d 2>/dev/null || true | |
| - uses: DeterminateSystems/nix-installer-action@main | |
| with: | |
| # relaxed sandbox allows __noChroot derivations (needed for | |
| # libghostty: Zig build-time tools require /lib64 dynamic linker) | |
| extra-conf: "sandbox = relaxed" | |
| - uses: DeterminateSystems/magic-nix-cache-action@main | |
| - name: Verify dev shell | |
| run: | | |
| nix develop --command bash -c ' | |
| echo "=== Dev Shell Verification ===" | |
| echo "Zig: $(zig version)" | |
| echo "pkg-config: $(pkg-config --version)" | |
| echo "GTK4: $(pkg-config --modversion gtk4 2>/dev/null || echo "not available on CI runner")" | |
| echo "Shell OK" | |
| ' | |
| - name: Run headless flake checks (required) | |
| run: | | |
| nix build .#checks.x86_64-linux.basic-version-check --print-build-logs | |
| nix build .#checks.x86_64-linux.cmux-linux-build-check --print-build-logs | |
| nix build .#checks.x86_64-linux.gtk4-version-check --print-build-logs | |
| - name: Run socket test suite check (best-effort) | |
| continue-on-error: true | |
| timeout-minutes: 45 | |
| run: nix build .#checks.x86_64-linux.socket-test-suite --print-build-logs | |
| - name: Run graphical flake check (best-effort) | |
| continue-on-error: true | |
| timeout-minutes: 30 | |
| run: nix build .#checks.x86_64-linux.basic-window-check-gnome --print-build-logs | |
| # ── Zig vendor libraries on Linux ────────────────────────────────── | |
| zig-libs-linux: | |
| name: Zig vendor libs (Linux) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Strip non-version tags from ghostty | |
| run: git -C ghostty tag -l 'xcframework-*' | xargs git -C ghostty tag -d 2>/dev/null || true | |
| - name: Install Zig | |
| uses: mlugg/setup-zig@v2 | |
| with: | |
| version: 0.15.2 | |
| use-cache: false | |
| - name: Install Linux dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libsecret-1-dev libnotify-dev pkg-config \ | |
| libgtk-4-dev libadwaita-1-dev \ | |
| libwebkitgtk-6.0-dev \ | |
| libfreetype-dev libharfbuzz-dev libfontconfig-dev \ | |
| libpng-dev libonig-dev libgl-dev \ | |
| glslang-tools spirv-cross | |
| - name: Build + test zig-ctap2 | |
| run: | | |
| cd vendor/ctap2 | |
| zig build -Doptimize=ReleaseFast | |
| zig build test 2>&1 || echo "Note: ctap2 tests may skip on Linux (USB HID is platform-specific)" | |
| echo "libctap2.a: $(ls -lh zig-out/lib/libctap2.a)" | |
| - name: Build + test zig-crypto | |
| run: | | |
| cd vendor/zig-crypto | |
| zig build -Doptimize=ReleaseFast | |
| zig build test | |
| echo "libzig-crypto.a: $(ls -lh zig-out/lib/libzig-crypto.a)" | |
| - name: Build + test zig-keychain | |
| run: | | |
| cd vendor/zig-keychain | |
| zig build -Doptimize=ReleaseFast | |
| zig build test | |
| echo "libzig-keychain.a: $(ls -lh zig-out/lib/libzig-keychain.a)" | |
| - name: Build cmuxd | |
| run: | | |
| if [ -d cmuxd ]; then | |
| cd cmuxd | |
| zig build -Doptimize=ReleaseFast | |
| echo "cmuxd: $(ls -lh zig-out/bin/cmuxd)" | |
| else | |
| echo "cmuxd directory not found, skipping" | |
| fi | |
| - name: Build libghostty | |
| run: | | |
| cd ghostty | |
| zig build -Dapp-runtime=none -Drenderer=opengl -Doptimize=ReleaseFast | |
| echo "libghostty.a: $(ls -lh zig-out/lib/libghostty.a)" | |
| echo "ghostty.h: $(ls -lh zig-out/include/ghostty.h)" | |
| - name: Build cmux-linux | |
| run: | | |
| cd cmux-linux | |
| zig build -Doptimize=ReleaseFast | |
| echo "cmux: $(ls -lh zig-out/bin/cmux)" | |
| - name: Test cmux-linux (config parser) | |
| run: | | |
| cd cmux-linux | |
| zig build test | |
| - name: Tier 0 — Validate desktop + metainfo files | |
| run: | | |
| sudo apt-get install -y desktop-file-utils appstream | |
| echo "=== Desktop entry validation ===" | |
| desktop-file-validate dist/linux/com.jesssullivan.cmux.desktop | |
| echo "=== AppStream metainfo validation ===" | |
| appstreamcli validate --no-net dist/linux/com.jesssullivan.cmux.metainfo.xml | |
| echo "=== Icon format checks ===" | |
| for icon in dist/linux/icons/*.png; do | |
| info=$(file "$icon") | |
| echo " $info" | |
| echo "$info" | grep -q "PNG image data" || { echo "FAIL: $icon is not a valid PNG"; exit 1; } | |
| done | |
| echo "Tier 0 validation passed" | |
| - name: Tier 1 — Static binary checks | |
| run: | | |
| BINARY="cmux-linux/zig-out/bin/cmux" | |
| export LD_LIBRARY_PATH="$PWD/ghostty/zig-out/lib:${LD_LIBRARY_PATH:-}" | |
| echo "=== ELF magic check ===" | |
| file "$BINARY" | grep -q "ELF 64-bit" || { echo "FAIL: not a 64-bit ELF"; exit 1; } | |
| echo "=== Executable bit ===" | |
| [ -x "$BINARY" ] || { echo "FAIL: not executable"; exit 1; } | |
| echo "=== Shared library dependencies ===" | |
| ldd "$BINARY" | |
| ldd "$BINARY" | grep -q "libgtk-4" || { echo "FAIL: libgtk-4 not linked"; exit 1; } | |
| ldd "$BINARY" | grep -q "libadwaita" || { echo "FAIL: libadwaita not linked"; exit 1; } | |
| echo "Static binary checks passed" | |
| - name: Tier 1 — Headless smoke test (Xvfb) | |
| continue-on-error: true | |
| run: | | |
| sudo apt-get install -y xvfb socat mesa-utils libgl1-mesa-dri | |
| # Start virtual framebuffer | |
| export DISPLAY=:99 | |
| Xvfb :99 -screen 0 800x600x24 & | |
| XVFB_PID=$! | |
| sleep 1 | |
| # Set up XDG runtime | |
| export XDG_RUNTIME_DIR=/tmp/xdg-runtime-smoke | |
| mkdir -p "$XDG_RUNTIME_DIR" | |
| chmod 700 "$XDG_RUNTIME_DIR" | |
| BINARY="cmux-linux/zig-out/bin/cmux" | |
| # libghostty.so is in ghostty/zig-out/lib | |
| export LD_LIBRARY_PATH="$PWD/ghostty/zig-out/lib:${LD_LIBRARY_PATH:-}" | |
| # Force software OpenGL (Xvfb has no GPU) | |
| # Ghostty requires GL 4.3; llvmpipe supports it but reports 3.3 by default | |
| export LIBGL_ALWAYS_SOFTWARE=1 | |
| export MESA_GL_VERSION_OVERRIDE=4.6COMPAT | |
| export MESA_GLSL_VERSION_OVERRIDE=460 | |
| echo "=== OpenGL info ===" | |
| glxinfo 2>/dev/null | grep -E "OpenGL version|OpenGL renderer|direct rendering" || echo "glxinfo not available" | |
| echo "=== Starting cmux-linux under Xvfb ===" | |
| timeout 8 "$BINARY" 2>/tmp/cmux-smoke-stderr.log & | |
| BINARY_PID=$! | |
| # Wait for socket creation (up to 5 seconds) | |
| SOCKET_FOUND=false | |
| for i in $(seq 1 10); do | |
| if [ -S "$XDG_RUNTIME_DIR/cmux.sock" ]; then | |
| SOCKET_FOUND=true | |
| echo "Socket created after ${i}x0.5s" | |
| break | |
| fi | |
| sleep 0.5 | |
| done | |
| if [ "$SOCKET_FOUND" = true ]; then | |
| echo "=== Socket permissions ===" | |
| ls -la "$XDG_RUNTIME_DIR/cmux.sock" | |
| echo "=== JSON-RPC ping test ===" | |
| RESPONSE=$(echo '{"id":1,"method":"system.ping","params":{}}' | \ | |
| socat -t2 - UNIX-CONNECT:"$XDG_RUNTIME_DIR/cmux.sock" 2>/dev/null || true) | |
| echo "Response: $RESPONSE" | |
| if echo "$RESPONSE" | grep -q "pong"; then | |
| echo "Socket ping: PASS" | |
| else | |
| echo "Socket ping: SKIP (method may not be wired yet)" | |
| fi | |
| else | |
| echo "Socket not created (expected — socket server may not be wired to GTK lifecycle yet)" | |
| fi | |
| echo "=== Clean shutdown test ===" | |
| if kill -0 $BINARY_PID 2>/dev/null; then | |
| kill -TERM $BINARY_PID 2>/dev/null || true | |
| # Wait up to 3 seconds for clean exit | |
| for i in $(seq 1 6); do | |
| kill -0 $BINARY_PID 2>/dev/null || break | |
| sleep 0.5 | |
| done | |
| if kill -0 $BINARY_PID 2>/dev/null; then | |
| echo "WARN: Process did not exit on SIGTERM, sending SIGKILL" | |
| kill -9 $BINARY_PID 2>/dev/null || true | |
| else | |
| echo "Clean shutdown: PASS" | |
| fi | |
| else | |
| echo "Process already exited before shutdown test" | |
| # Don't call wait — the PID may belong to timeout wrapper | |
| fi | |
| # Show any stderr from the binary | |
| if [ -f /tmp/cmux-smoke-stderr.log ]; then | |
| echo "=== Binary stderr ===" | |
| cat /tmp/cmux-smoke-stderr.log || true | |
| fi | |
| # Cleanup | |
| kill -9 $XVFB_PID 2>/dev/null || true | |
| rm -rf "$XDG_RUNTIME_DIR" | |
| echo "Headless smoke test completed" | |
| # ── Fedora 42 container: GTK4 4.18 ──────────────────────────────── | |
| fedora: | |
| name: Fedora 42 (GTK4 4.18) | |
| runs-on: ubuntu-latest | |
| container: fedora:42 | |
| steps: | |
| - name: Install git and dependencies | |
| run: | | |
| dnf install -y \ | |
| git \ | |
| gcc gcc-c++ \ | |
| pkg-config \ | |
| gtk4-devel \ | |
| libadwaita-devel \ | |
| webkitgtk6.0-devel \ | |
| libsecret-devel \ | |
| libnotify-devel \ | |
| wayland-devel \ | |
| wayland-protocols-devel \ | |
| freetype-devel harfbuzz-devel fontconfig-devel \ | |
| libpng-devel oniguruma-devel mesa-libGL-devel | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Strip non-version tags from ghostty | |
| run: git -C ghostty tag -l 'xcframework-*' | xargs git -C ghostty tag -d 2>/dev/null || true | |
| - name: Verify GTK4 version | |
| run: | | |
| GTK_VER=$(pkg-config --modversion gtk4) | |
| echo "GTK4 version: $GTK_VER" | |
| ADWAITA_VER=$(pkg-config --modversion libadwaita-1) | |
| echo "libadwaita version: $ADWAITA_VER" | |
| WEBKIT_VER=$(pkg-config --modversion webkitgtk-6.0) | |
| echo "WebKitGTK version: $WEBKIT_VER" | |
| - name: Install Zig | |
| uses: mlugg/setup-zig@v2 | |
| with: | |
| version: 0.15.2 | |
| use-cache: false | |
| - name: Build zig-ctap2 | |
| run: | | |
| cd vendor/ctap2 | |
| zig build -Doptimize=ReleaseFast | |
| - name: Build zig-crypto | |
| run: | | |
| cd vendor/zig-crypto | |
| zig build -Doptimize=ReleaseFast | |
| - name: Build zig-keychain | |
| run: | | |
| cd vendor/zig-keychain | |
| zig build -Doptimize=ReleaseFast | |
| - name: Build libghostty | |
| run: | | |
| cd ghostty | |
| zig build -Dapp-runtime=none -Drenderer=opengl -Doptimize=ReleaseFast | |
| - name: Build cmux-linux (Fedora) | |
| run: | | |
| cd cmux-linux | |
| zig build -Doptimize=ReleaseFast | |
| - name: Tier 0 — Validate desktop + metainfo (Fedora) | |
| run: | | |
| dnf install -y desktop-file-utils appstream | |
| desktop-file-validate dist/linux/com.jesssullivan.cmux.desktop | |
| appstreamcli validate --no-net dist/linux/com.jesssullivan.cmux.metainfo.xml | |
| echo "Tier 0 (Fedora) passed" | |
| # ── Arch Linux container: bleeding edge ──────────────────────────── | |
| arch: | |
| name: Arch Linux (bleeding edge) | |
| runs-on: ubuntu-latest | |
| container: archlinux:latest | |
| steps: | |
| - name: Install dependencies | |
| run: | | |
| pacman -Syu --noconfirm \ | |
| base-devel \ | |
| git \ | |
| pkg-config \ | |
| gtk4 \ | |
| libadwaita \ | |
| webkitgtk-6.0 \ | |
| libsecret \ | |
| libnotify \ | |
| wayland \ | |
| wayland-protocols \ | |
| freetype2 harfbuzz fontconfig \ | |
| libpng oniguruma mesa | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Strip non-version tags from ghostty | |
| run: git -C ghostty tag -l 'xcframework-*' | xargs git -C ghostty tag -d 2>/dev/null || true | |
| - name: Verify GTK4 version | |
| run: | | |
| GTK_VER=$(pkg-config --modversion gtk4) | |
| echo "GTK4 version: $GTK_VER" | |
| ADWAITA_VER=$(pkg-config --modversion libadwaita-1) | |
| echo "libadwaita version: $ADWAITA_VER" | |
| - name: Install Zig | |
| uses: mlugg/setup-zig@v2 | |
| with: | |
| version: 0.15.2 | |
| use-cache: false | |
| - name: Build zig-ctap2 | |
| run: | | |
| cd vendor/ctap2 | |
| zig build -Doptimize=ReleaseFast | |
| - name: Build zig-crypto | |
| run: | | |
| cd vendor/zig-crypto | |
| zig build -Doptimize=ReleaseFast | |
| - name: Build zig-keychain | |
| run: | | |
| cd vendor/zig-keychain | |
| zig build -Doptimize=ReleaseFast | |
| - name: Build libghostty | |
| run: | | |
| cd ghostty | |
| zig build -Dapp-runtime=none -Drenderer=opengl -Doptimize=ReleaseFast | |
| - name: Build cmux-linux (Arch) | |
| run: | | |
| cd cmux-linux | |
| zig build -Doptimize=ReleaseFast | |
| - name: Tier 0 — Validate desktop + metainfo (Arch) | |
| run: | | |
| pacman -S --noconfirm desktop-file-utils appstream | |
| desktop-file-validate dist/linux/com.jesssullivan.cmux.desktop | |
| appstreamcli validate --no-net dist/linux/com.jesssullivan.cmux.metainfo.xml | |
| echo "Tier 0 (Arch) passed" |