build(snap): let rust deps provide toolchain #280
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: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - "release/**" | |
| tags: | |
| - "v*" | |
| pull_request: | |
| branches: | |
| - main | |
| - "release/**" | |
| workflow_dispatch: | |
| inputs: | |
| windows_runtime_smoke: | |
| description: Run native Windows runtime smoke checks | |
| required: false | |
| default: false | |
| type: boolean | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_INCREMENTAL: "0" | |
| CARGO_HTTP_MULTIPLEXING: "false" | |
| CARGO_TERM_COLOR: always | |
| RUSTDOCFLAGS: -D warnings | |
| TMPDIR: /tmp | |
| RMUX_TMPDIR: /tmp | |
| jobs: | |
| linux-quality: | |
| name: Linux format, lint, and docs | |
| runs-on: ubuntu-latest | |
| env: | |
| RUST_MIN_STACK: "8388608" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| components: clippy, rustfmt | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Fetch locked dependencies | |
| run: cargo fetch --locked | |
| - name: Install audit tooling | |
| run: sudo apt-get update && sudo apt-get install -y --no-install-recommends ripgrep | |
| - name: cargo fmt | |
| run: cargo fmt --all -- --check | |
| - name: cargo clippy | |
| run: cargo clippy --workspace --all-targets --locked -- -D warnings | |
| - name: Await-under-lock audit | |
| run: scripts/audit-await-holding-lock.sh | |
| - name: rustdoc with warnings denied | |
| run: cargo doc --workspace --locked --no-deps | |
| linux-build: | |
| name: Linux workspace build | |
| runs-on: ubuntu-latest | |
| env: | |
| RUST_MIN_STACK: "8388608" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Fetch locked dependencies | |
| run: cargo fetch --locked | |
| - name: cargo build | |
| run: cargo build --workspace --locked | |
| wasm-crypto: | |
| name: WASM crypto build and supply-chain gate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| # Pin the exact rustc that reproduces the shipped browser blob (mirrored | |
| # in rmux-web-share PROVENANCE.json toolchain.rustc). A floating "stable" | |
| # changes codegen and would break byte-for-byte reproducibility — the | |
| # property rmux-web-share's verify-wasm-from-source.mjs gate enforces. | |
| toolchain: "1.94.1" | |
| targets: wasm32-unknown-unknown | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Fetch locked dependencies | |
| run: cargo fetch --locked | |
| # The browser bundle must NOT carry x25519-dalek/curve25519-dalek; the | |
| # WebCrypto path replaces them. cargo tree -i exits non-zero when the | |
| # package is absent, so success here means it leaked — fail closed. | |
| - name: Assert x25519-dalek is excluded from the WASM build | |
| run: | | |
| if cargo tree -p rmux-web-crypto --no-default-features --features wasm --target wasm32-unknown-unknown -i x25519-dalek >/dev/null 2>&1; then | |
| echo "::error::x25519-dalek must not enter the WASM crypto build" | |
| exit 1 | |
| fi | |
| echo "x25519-dalek correctly excluded from the WASM crypto build" | |
| # Regression guard for the browser test gate: the wasm-test feature set must | |
| # compile its test targets (tests/handshake.rs is x25519-gated out). | |
| - name: Compile the wasm-test gate | |
| run: cargo test -p rmux-web-crypto --no-default-features --features wasm-test --no-run --locked | |
| - name: Install pinned wasm-pack | |
| run: cargo install wasm-pack --version 0.13.1 --locked | |
| # Rebuild the exact blobs rmux-web-share ships, via the canonical recipe and | |
| # pinned toolchain, and publish them as an artifact for manual auditors. The | |
| # authoritative byte-equality-to-shipped check is cross-repo, in | |
| # rmux-web-share's verify-wasm-from-source.mjs (which rebuilds from this | |
| # source at the pinned commit); here we prove the recipe still produces the | |
| # browser primitive and expose the canonical bytes + their hashes. | |
| - name: Build and publish the browser WASM blobs | |
| env: | |
| RUSTUP_TOOLCHAIN: "1.94.1" | |
| run: | | |
| set -euo pipefail | |
| scripts/build-web-crypto-wasm.sh wasm | |
| mkdir -p "$RUNNER_TEMP/wasm-pkg" | |
| cp crates/rmux-web-crypto/pkg/rmux_web_crypto_wasm_bg.wasm \ | |
| crates/rmux-web-crypto/pkg/rmux_web_crypto_wasm.js \ | |
| "$RUNNER_TEMP/wasm-pkg/" | |
| # The Playwright-only blob shares the recipe; build it too so a break in | |
| # the test feature set is caught here, not in rmux-web-share CI. | |
| scripts/build-web-crypto-wasm.sh wasm-test | |
| { | |
| echo "### Browser WASM crypto blob (production)" | |
| echo "" | |
| echo "rustc 1.94.1 · wasm-bindgen 0.2.123 · wasm-opt off" | |
| echo "" | |
| echo '```' | |
| ( cd "$RUNNER_TEMP/wasm-pkg" && sha256sum rmux_web_crypto_wasm_bg.wasm rmux_web_crypto_wasm.js ) | |
| echo '```' | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 | |
| with: | |
| name: rmux-web-crypto-wasm | |
| path: ${{ runner.temp }}/wasm-pkg | |
| if-no-files-found: error | |
| linux-tests: | |
| name: Linux tests (${{ matrix.group }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - group: core | |
| packages: -p rmux-types -p rmux-os -p rmux-proto -p rmux-ipc -p rmux-core -p rmux-client -p rmux-render-core -p rmux-web-crypto | |
| - group: pty-sdk | |
| packages: -p rmux-pty -p rmux-sdk | |
| - group: server | |
| packages: -p rmux-server | |
| - group: app-ui | |
| packages: -p rmux -p ratatui-rmux -p xtask | |
| env: | |
| RUST_MIN_STACK: "8388608" | |
| RUST_TEST_THREADS: "1" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ matrix.group }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ matrix.group }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Fetch locked dependencies | |
| run: cargo fetch --locked | |
| - name: cargo test | |
| run: cargo test --locked --no-fail-fast ${{ matrix.packages }} | |
| linux-source-gates: | |
| name: Linux source boundary gates | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - name: Unsafe policy gate | |
| run: scripts/unsafe-check.sh | |
| - name: No network scoped runtime source scan | |
| run: scripts/no-network-in-runtime.sh | |
| - name: Platform neutrality source scan | |
| run: scripts/check-platform-neutrality.sh | |
| - name: No side effects in debug assertions | |
| run: scripts/no-debug-assert-side-effects.sh | |
| release-review-gate: | |
| name: Release review gate (no package) | |
| runs-on: ubuntu-latest | |
| env: | |
| RUST_MIN_STACK: "8388608" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| components: clippy, rustfmt | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Fetch locked dependencies | |
| run: cargo fetch --locked | |
| - name: Release review gate | |
| run: scripts/release-review-gate.sh --skip-package --target-dir target/release-review-ci | |
| snap-package: | |
| name: Snap package smoke | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - name: Build snap | |
| id: snapcraft | |
| uses: snapcore/action-build@3bdaa03e1ba6bf59a65f84a751d943d549a54e79 | |
| with: | |
| path: . | |
| - name: Smoke snap package | |
| run: scripts/smoke-snap-package.sh "${{ steps.snapcraft.outputs.snap }}" | |
| - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 | |
| with: | |
| name: rmux-snap-${{ github.sha }} | |
| path: ${{ steps.snapcraft.outputs.snap }} | |
| if-no-files-found: error | |
| nix-flake: | |
| name: Nix flake gate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - name: Install Nix | |
| uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 | |
| with: | |
| extra_nix_config: | | |
| experimental-features = nix-command flakes | |
| - name: nix flake check | |
| run: nix flake check | |
| - name: nix build | |
| run: nix build .#packages.x86_64-linux.default --no-link | |
| - name: nix run version matches Cargo.toml | |
| run: | | |
| set -euo pipefail | |
| expected="$(python3 - <<'PY' | |
| import pathlib | |
| import tomllib | |
| manifest = tomllib.loads(pathlib.Path("Cargo.toml").read_text()) | |
| print(manifest["workspace"]["package"]["version"]) | |
| PY | |
| )" | |
| actual="$(nix run . -- -V)" | |
| if [ "$actual" != "rmux $expected" ]; then | |
| echo "::error::expected 'rmux $expected', got '$actual'" | |
| exit 1 | |
| fi | |
| linux-sdk-smoke: | |
| name: Linux SDK v1 daemon smoke | |
| runs-on: ubuntu-latest | |
| env: | |
| RUST_MIN_STACK: "8388608" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: SDK v1 daemon smoke | |
| run: scripts/smoke-sdk-v1.sh | |
| linux-perf-smoke: | |
| name: Linux non-final performance smoke | |
| runs-on: ubuntu-latest | |
| env: | |
| RUST_MIN_STACK: "8388608" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Non-final local performance budget smoke | |
| run: scripts/perf-bench.sh --iterations 3 --line-count 10000 --output-dir target/perf/non-final-ci --fail-on-budget | |
| - name: Issue 34 responsiveness smoke | |
| env: | |
| RMUX_BIN: target/release/rmux | |
| run: scripts/smoke-issue34-responsiveness-unix.sh | |
| - name: RSS and FD drift smoke | |
| env: | |
| RMUX_BIN: target/release/rmux | |
| run: scripts/smoke-rss-fd-drift-unix.sh | |
| linux-dependency-audit: | |
| name: Linux dependency audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/bin/cargo-deny | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| key: cargo-deny-${{ runner.os }}-${{ runner.arch }}-0.19.5-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-deny-${{ runner.os }}-${{ runner.arch }}-0.19.5- | |
| - name: Install cargo-deny | |
| if: hashFiles('deny.toml') != '' | |
| run: | | |
| if ! command -v cargo-deny >/dev/null 2>&1; then | |
| cargo install cargo-deny --version 0.19.5 --locked | |
| fi | |
| - name: cargo deny check | |
| if: hashFiles('deny.toml') != '' | |
| run: cargo deny check | |
| platform-runtime: | |
| name: Platform build and smoke on ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - macos-15-intel | |
| - macos-15 | |
| - windows-latest | |
| env: | |
| RUST_MIN_STACK: "8388608" | |
| RUST_TEST_THREADS: "1" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ matrix.os }}-platform-runtime-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ matrix.os }}-platform-runtime- | |
| - name: Configure temporary paths | |
| shell: bash | |
| run: | | |
| echo "TMPDIR=$RUNNER_TEMP" >> "$GITHUB_ENV" | |
| echo "RMUX_TMPDIR=$RUNNER_TEMP" >> "$GITHUB_ENV" | |
| - name: Fetch locked dependencies | |
| run: cargo fetch --locked | |
| - name: cargo build | |
| run: cargo build --workspace --locked | |
| - name: cargo test portable crates | |
| if: runner.os != 'Windows' | |
| run: cargo test --locked --no-fail-fast -p rmux-types -p rmux-os -p rmux-proto -p rmux-ipc -p rmux-core -p rmux-client | |
| - name: cargo test macOS direct /tmp socket path | |
| if: runner.os == 'macOS' | |
| run: cargo test --locked -p rmux --test cli_surface socket_path_flag_can_start_directly_under_tmp -- --exact --test-threads=1 | |
| - name: cargo test workspace on Windows | |
| if: runner.os == 'Windows' | |
| run: cargo test --workspace --locked --no-fail-fast -- --test-threads=1 | |
| - name: rmux binary smoke | |
| run: cargo run --package rmux --bin rmux --locked -- -V | |
| windows-cross: | |
| name: Cross-target Windows build check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| targets: x86_64-pc-windows-gnu | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Install Windows GNU linker | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends gcc-mingw-w64-x86-64 | |
| - name: cargo build Windows target | |
| run: cargo build --workspace --locked --target x86_64-pc-windows-gnu | |
| windows-runtime-smoke: | |
| name: Native Windows runtime smoke | |
| if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.windows_runtime_smoke) | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 | |
| with: | |
| path: | | |
| ~/.cargo/git | |
| ~/.cargo/registry | |
| target | |
| key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- | |
| cargo-${{ runner.os }}-${{ runner.arch }}- | |
| - name: Windows hidden daemon smoke | |
| run: cargo test --locked --test internal_daemon_windows -- --nocapture | |
| - name: Windows named-pipe IPC smoke | |
| run: cargo test -p rmux-ipc --locked --test named_pipe_integration -- --nocapture |