From dd02f1438c051231c43a28a6ad42d081905e4d22 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Tue, 14 Oct 2025 15:45:09 +0200 Subject: [PATCH 1/5] add script to download slang + make ci use it. --- .github/workflows/ci.yaml | 117 +++++++++++++++++++++--- .gitignore | 4 +- crates/slai-chat/README.md | 13 ++- crates/slai-chat/src/chat_llama2.rs | 5 +- crates/slai-chat/src/components/chat.rs | 22 ++--- download_slang.sh | 109 ++++++++++++++++++++++ 6 files changed, 235 insertions(+), 35 deletions(-) create mode 100755 download_slang.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ea891ac..d4521c4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,22 +2,80 @@ name: CI on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] env: CARGO_TERM_COLOR: always RUSTFLAGS: --deny warnings RUSTDOCFLAGS: --deny warnings + SLANG_TAG: 2025.18.2 jobs: + # Check formatting. + format: + name: Format + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + + - name: Run cargo fmt + run: cargo fmt --all -- --check + setup-slang: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + outputs: + slang-dir: ${{ steps.setup.outputs.slang-dir }} # Pass SLANG_DIR to dependent jobs + slang-cache-key: ${{ steps.setup.outputs.slang-cache-key }} # Pass SLANG_DIR to dependent jobs + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Slang + id: cache-slang + uses: actions/cache/restore@v4 # Restore first + with: + path: | + ~/.cache/slang # Matches script's default OUTPUT_DIR + key: slang-2025.18.2-${{ runner.os }}-${{ runner.arch }} + + - name: Setup Slang + id: setup + run: | + echo "version=${{ env.SLANG_TAG }}" >> $GITHUB_OUTPUT # Output for cache key + ./download_slang.sh --version ${{ env.SLANG_TAG }} + SLANG_DIR=$(./download_slang.sh --version ${{ env.SLANG_TAG }} | grep '^SLANG_DIR=' | cut -d'=' -f2-) + echo "slang-dir=$SLANG_DIR" >> $GITHUB_OUTPUT # Output for dependents + echo "slang-cache-key=slang-v${{ env.SLANG_TAG }}-${{ runner.os }}-${{ runner.arch }}" >> $GITHUB_OUTPUT + echo "SLANG_DIR=$SLANG_DIR" >> $GITHUB_ENV # For this job if needed + + - name: Save Slang Cache + if: steps.cache-slang.outputs.cache-hit != 'true' # Only save on miss + uses: actions/cache/save@v4 + with: + path: ~/.cache/slang + key: ${{ steps.setup.outputs.slang-cache-key }} # Run clippy lints. clippy: + needs: setup-slang # Depends on setup-slang name: Clippy runs-on: ubuntu-latest + env: + SLANG_DIR: ${{ needs.setup-slang.outputs.slang-dir }} timeout-minutes: 30 steps: + - run: echo "(env) SLANG_DIR=${{ env.SLANG_DIR }}" + - run: echo $SLANG_DIR - name: Checkout repository uses: actions/checkout@v4 @@ -29,36 +87,59 @@ jobs: - name: Install dependencies run: sudo apt-get update; sudo apt-get install --no-install-recommends libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev + - name: Retrieve Cache for Slang + uses: actions/cache/restore@v4 + with: + path: ~/.cache/slang + key: ${{ needs.setup-slang.outputs.slang-cache-key }} + - name: Populate target directory from cache uses: Leafwing-Studios/cargo-cache@v2 with: sweep-cache: true - name: Run clippy lints - run: cargo clippy --locked --workspace --all-targets --all-features -- --deny warnings + run: SLANG_DIR=${{ env.SLANG_DIR }} cargo clippy --locked --workspace --all-targets --all-features -- --deny warnings - # Check formatting. - format: - name: Format + # Check documentation. + doc: + needs: setup-slang # Depends on setup-slang + name: Docs runs-on: ubuntu-latest timeout-minutes: 30 + env: + SLANG_DIR: ${{ needs.setup-slang.outputs.slang-dir }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable + + - name: Install dependencies + run: sudo apt-get update; sudo apt-get install --no-install-recommends libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev + + - name: Retrieve Cache for Slang + uses: actions/cache/restore@v4 with: - components: rustfmt + path: ~/.cache/slang + key: ${{ needs.setup-slang.outputs.slang-cache-key }} - - name: Run cargo fmt - run: cargo fmt --all -- --check + - name: Populate target directory from cache + uses: Leafwing-Studios/cargo-cache@v2 + with: + sweep-cache: true - # Check documentation. - doc: - name: Docs + - name: Check documentation + run: SLANG_DIR=${{ env.SLANG_DIR }} cargo doc --locked --workspace --all-features --document-private-items --no-deps + # Testing. + test: + needs: setup-slang # Depends on setup-slang + name: Tests runs-on: ubuntu-latest timeout-minutes: 30 + env: + SLANG_DIR: ${{ needs.setup-slang.outputs.slang-dir }} steps: - name: Checkout repository uses: actions/checkout@v4 @@ -69,10 +150,16 @@ jobs: - name: Install dependencies run: sudo apt-get update; sudo apt-get install --no-install-recommends libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev + - name: Retrieve Cache for Slang + uses: actions/cache/restore@v4 + with: + path: ~/.cache/slang + key: ${{ needs.setup-slang.outputs.slang-cache-key }} + - name: Populate target directory from cache uses: Leafwing-Studios/cargo-cache@v2 with: sweep-cache: true - - - name: Check documentation - run: cargo doc --locked --workspace --all-features --document-private-items --no-deps \ No newline at end of file + - name: Run Cargo Tests + run: | + SLANG_DIR=${{ env.SLANG_DIR }} cargo test --verbose diff --git a/.gitignore b/.gitignore index 96c4569..0fe4180 100644 --- a/.gitignore +++ b/.gitignore @@ -111,4 +111,6 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser -.DS_store \ No newline at end of file +.DS_store + +downloaded_slang \ No newline at end of file diff --git a/crates/slai-chat/README.md b/crates/slai-chat/README.md index cbac86f..805515c 100644 --- a/crates/slai-chat/README.md +++ b/crates/slai-chat/README.md @@ -5,11 +5,18 @@ This is a basic chat interface for testing **slai**. Currently only supports: - Qwen 2. - Segment Anything. -In order to compile and run `slai-chat`, be sure to define the `SLANG_DIR` environment variable: -1. Download the Slang compiler libraries for your platform: https://github.com/shader-slang/slang/releases/tag/v2025.16 -2. Unzip the downloaded directory, and use its path as value to the `SLANG_DIR` environment variable: `SLANG_DIR=/path/to/slang`. +In order to compile and run `slai-chat`, be sure to define the `SLANG_DIR` environment variable. + +Either: + +- Run the script at the root of slai repository: `SLANG_DIR=$(./download_slang.sh | grep '^SLANG_DIR=' | cut -d'=' -f2-)` +- Or manually: + 1. Download the Slang compiler libraries for your platform: https://github.com/shader-slang/slang/releases/tag/v2025.16 + 2. Unzip the downloaded directory, and use its path as value to the `SLANG_DIR` environment variable: `SLANG_DIR=/path/to/slang`. Note that the variable must point to the root of the slang installation (i.e. the directory that contains `bin` and `lib`). + + To run the GUI natively: ```bash dx run --release --features desktop diff --git a/crates/slai-chat/src/chat_llama2.rs b/crates/slai-chat/src/chat_llama2.rs index ae01507..2cf9b57 100644 --- a/crates/slai-chat/src/chat_llama2.rs +++ b/crates/slai-chat/src/chat_llama2.rs @@ -178,10 +178,7 @@ impl ChatLlama2 { // Run the transformer. let mut encoder = backend.begin_encoding(); backend.write_buffer(state.rope_config_mut().buffer_mut(), &[rope_config])?; - backend.write_buffer( - state.rms_norm_config_mut().buffer_mut(), - &[rms_norm_config], - )?; + backend.write_buffer(state.rms_norm_config_mut().buffer_mut(), &[rms_norm_config])?; backend.write_buffer(state.attn_params_mut().buffer_mut(), &[attn_params])?; state .x diff --git a/crates/slai-chat/src/components/chat.rs b/crates/slai-chat/src/components/chat.rs index a89131c..a88db42 100644 --- a/crates/slai-chat/src/components/chat.rs +++ b/crates/slai-chat/src/components/chat.rs @@ -437,18 +437,16 @@ fn submit_prompt( let gpu = gpu.clone(); let llm = model.llm.clone(); execute(async move { - llm - .forward( - &gpu.backend, - prompt, - sampler, - chat_template, - next_pos, - |msg| { - Ok(out.unbounded_send(msg)?) - }) - .await - .unwrap() + llm.forward( + &gpu.backend, + prompt, + sampler, + chat_template, + next_pos, + |msg| Ok(out.unbounded_send(msg)?), + ) + .await + .unwrap() }); } diff --git a/download_slang.sh b/download_slang.sh new file mode 100755 index 0000000..0d1738f --- /dev/null +++ b/download_slang.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +# Default values +OS="" +OUTPUT_DIR="$HOME/.cache/slang" +SLANG_VERSION="" +SLANG_TAG="" +ASSET_SUFFIX="" +SLANG_URL_BASE="https://github.com/shader-slang/slang/releases/download" + +# Help message +usage() { + echo "Usage: $0 [--os ] [--output-dir ] [--version ]" + echo " --os: Target OS (default: auto-detect from current platform)" + echo " --output-dir: Directory to extract Slang (default: ~/.cache/slang)" + echo " --version: Slang version (e.g., 2025.18.2, default: latest)" + echo "Example: $0 --os linux --output-dir /tmp/slang" +} + +# Parse arguments +while [[ "$#" -gt 0 ]]; do + case $1 in + --os) OS="$2"; shift ;; + --output-dir) export OUTPUT_DIR="$2"; shift ;; + --version) export SLANG_VERSION="$2"; shift ;; + *) usage ; exit 1 ;; + esac + shift +done + +# Detect OS if not specified +if [[ -z "$OS" ]]; then + case "$(uname -s)" in + Linux*) OS="linux" ;; + Darwin*) + if [[ "$(uname -m)" == "arm64" ]]; then + OS="macos-aarch64" + else + OS="macos" + fi + ;; + CYGWIN*|MINGW*|MSYS*) OS="windows" ;; + *) echo "Error: Unable to detect OS. Specify --os (linux, macos, macos-arm64, windows)"; exit 1 ;; + esac +fi + +# Determine asset suffix based on OS +case "$OS" in + linux) ASSET_SUFFIX="linux-x86_64.zip" ;; + macos) ASSET_SUFFIX="macos-x86_64.zip" ;; + macos-aarch64) ASSET_SUFFIX="macos-aarch64.zip" ;; + windows) ASSET_SUFFIX="windows-x86_64.zip" ;; + *) echo "Error: Unsupported OS: $OS"; exit 1 ;; +esac + +# Get Slang version if not specified +if [[ -z "$SLANG_VERSION" ]]; then + export SLANG_TAG=$(curl -s https://api.github.com/repos/shader-slang/slang/releases/latest | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') + export SLANG_VERSION=$(echo "$SLANG_TAG" | sed 's/v//') # e.g., v2025.18.2 -> 2025.18.2 +else + export SLANG_TAG="v$SLANG_VERSION" +fi + +if [[ -z "$SLANG_VERSION" ]]; then + echo "Error: Could not determine Slang version" + exit 1 +fi + +# Set up paths +SLANG_DIR="$OUTPUT_DIR/slang-v$SLANG_VERSION-$OS" +ZIP_URL="$SLANG_URL_BASE/$SLANG_TAG/slang-$SLANG_VERSION-$ASSET_SUFFIX" +TEMP_ZIP="/tmp/slang-$SLANG_VERSION.zip" + +# Check if Slang is already extracted +if [[ -d "$SLANG_DIR" ]] && [[ -f "$SLANG_DIR/bin/slangc" || -f "$SLANG_DIR/bin/slangc.exe" ]]; then + echo "Using existing Slang at $SLANG_DIR" + echo "SLANG_DIR=$SLANG_DIR" + exit 0 +fi + +# Download Slang release +echo "Downloading Slang v$SLANG_VERSION for $OS from $ZIP_URL..." +mkdir -p "$OUTPUT_DIR" +curl -L -o "$TEMP_ZIP" "$ZIP_URL" || { echo "Error: Download failed for $ZIP_URL"; exit 1; } + +# Extract based on OS +echo "Extracting to $SLANG_DIR..." +if [[ "$OS" == "windows" ]]; then + # Windows: Assume 7z is available (or adjust for PowerShell/Expand-Archive) + 7z x "$TEMP_ZIP" -o"$SLANG_DIR" -y > /dev/null || { echo "Error: Extraction failed"; rm -f "$TEMP_ZIP"; exit 1; } +else + # Linux/macOS: Use unzip + unzip -q "$TEMP_ZIP" -d "$SLANG_DIR" || { echo "Error: Extraction failed"; rm -f "$TEMP_ZIP"; exit 1; } +fi + +# Clean up +rm -f "$TEMP_ZIP" + +# Verify extraction +if [[ ! -f "$SLANG_DIR/bin/slangc" && ! -f "$SLANG_DIR/bin/slangc.exe" ]]; then + echo "Error: Extraction incomplete, slangc not found in $SLANG_DIR/bin" + exit 1 +fi + +echo "Slang v$SLANG_VERSION extracted to $SLANG_DIR" +echo "SLANG_DIR=$SLANG_DIR" + +# For use in calling script +export SLANG_DIR \ No newline at end of file From c57272ddb0fca751778ae8f53896e4e4dc0e4ffd Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Tue, 14 Oct 2025 21:20:56 +0200 Subject: [PATCH 2/5] remove useless imports --- .github/workflows/ci.yaml | 17 +++++++---------- crates/slai-chat/src/components/home.rs | 1 - crates/slai-chat/src/main.rs | 1 - 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d4521c4..19e1054 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -47,16 +47,15 @@ jobs: with: path: | ~/.cache/slang # Matches script's default OUTPUT_DIR - key: slang-2025.18.2-${{ runner.os }}-${{ runner.arch }} + key: slang-v$SLANG_TAG-${{ runner.os }}-${{ runner.arch }} - name: Setup Slang id: setup run: | - echo "version=${{ env.SLANG_TAG }}" >> $GITHUB_OUTPUT # Output for cache key - ./download_slang.sh --version ${{ env.SLANG_TAG }} - SLANG_DIR=$(./download_slang.sh --version ${{ env.SLANG_TAG }} | grep '^SLANG_DIR=' | cut -d'=' -f2-) + echo "version=$SLANG_TAG" >> $GITHUB_OUTPUT # Output for cache key + SLANG_DIR=$(./download_slang.sh --version $SLANG_TAG | grep '^SLANG_DIR=' | cut -d'=' -f2-) echo "slang-dir=$SLANG_DIR" >> $GITHUB_OUTPUT # Output for dependents - echo "slang-cache-key=slang-v${{ env.SLANG_TAG }}-${{ runner.os }}-${{ runner.arch }}" >> $GITHUB_OUTPUT + echo "slang-cache-key=slang-v$SLANG_TAG-${{ runner.os }}-${{ runner.arch }}" >> $GITHUB_OUTPUT echo "SLANG_DIR=$SLANG_DIR" >> $GITHUB_ENV # For this job if needed - name: Save Slang Cache @@ -74,8 +73,6 @@ jobs: SLANG_DIR: ${{ needs.setup-slang.outputs.slang-dir }} timeout-minutes: 30 steps: - - run: echo "(env) SLANG_DIR=${{ env.SLANG_DIR }}" - - run: echo $SLANG_DIR - name: Checkout repository uses: actions/checkout@v4 @@ -99,7 +96,7 @@ jobs: sweep-cache: true - name: Run clippy lints - run: SLANG_DIR=${{ env.SLANG_DIR }} cargo clippy --locked --workspace --all-targets --all-features -- --deny warnings + run: SLANG_DIR=$SLANG_DIR cargo clippy --locked --workspace --all-targets --all-features -- --deny warnings # Check documentation. doc: @@ -131,7 +128,7 @@ jobs: sweep-cache: true - name: Check documentation - run: SLANG_DIR=${{ env.SLANG_DIR }} cargo doc --locked --workspace --all-features --document-private-items --no-deps + run: SLANG_DIR=$SLANG_DIR cargo doc --locked --workspace --all-features --document-private-items --no-deps # Testing. test: needs: setup-slang # Depends on setup-slang @@ -162,4 +159,4 @@ jobs: sweep-cache: true - name: Run Cargo Tests run: | - SLANG_DIR=${{ env.SLANG_DIR }} cargo test --verbose + SLANG_DIR=$SLANG_DIR cargo test --verbose diff --git a/crates/slai-chat/src/components/home.rs b/crates/slai-chat/src/components/home.rs index d82ca69..c2e517a 100644 --- a/crates/slai-chat/src/components/home.rs +++ b/crates/slai-chat/src/components/home.rs @@ -1,7 +1,6 @@ use crate::chat_template::ChatTemplate; use crate::llm::ChatLlm; use crate::{GgufMetadata, GpuInstanceCtx, LoadedModel, LoadedModelSignal, SelectedBackend}; -use async_std::sync::RwLock; use dioxus::prelude::*; use dioxus_markdown::Markdown; use rfd::FileHandle; diff --git a/crates/slai-chat/src/main.rs b/crates/slai-chat/src/main.rs index 8c73cc3..a9894a9 100644 --- a/crates/slai-chat/src/main.rs +++ b/crates/slai-chat/src/main.rs @@ -3,7 +3,6 @@ use crate::cli::Cli; use crate::llm::ChatLlm; use crate::prompt::Prompt; use crate::sampler::SamplerParams; -use async_std::sync::RwLock; use components::{Chat, Home}; use dioxus::prelude::*; use slang_hal::backend::Backend; From a300bcf85374a8a57b2ff28fe6456e3d5a7ccc92 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 20 Oct 2025 21:02:22 +0200 Subject: [PATCH 3/5] avoid cuda in ci ; fix minor clippy errors --- .github/workflows/ci.yaml | 4 ++-- crates/slai-chat/src/main.rs | 2 +- crates/slai/build.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 19e1054..4e6cf5f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -96,7 +96,7 @@ jobs: sweep-cache: true - name: Run clippy lints - run: SLANG_DIR=$SLANG_DIR cargo clippy --locked --workspace --all-targets --all-features -- --deny warnings + run: SLANG_DIR=$SLANG_DIR cargo clippy --locked --workspace --all-targets --features web,desktop,mobile,comptime_checks -- --deny warnings # Check documentation. doc: @@ -128,7 +128,7 @@ jobs: sweep-cache: true - name: Check documentation - run: SLANG_DIR=$SLANG_DIR cargo doc --locked --workspace --all-features --document-private-items --no-deps + run: SLANG_DIR=$SLANG_DIR cargo doc --locked --workspace --features web,desktop,mobile,comptime_checks --document-private-items --no-deps # Testing. test: needs: setup-slang # Depends on setup-slang diff --git a/crates/slai-chat/src/main.rs b/crates/slai-chat/src/main.rs index a9894a9..21adc8e 100644 --- a/crates/slai-chat/src/main.rs +++ b/crates/slai-chat/src/main.rs @@ -160,7 +160,7 @@ fn App() -> Element { match (&*gpu_wgpu.read_unchecked(), &*gpu_cuda.read_unchecked()) { (Some(Ok(gpu_wgpu)), Some(Ok(gpu_cuda))) => { use_context_provider(|| gpu_wgpu.clone()); - use_context_provider(|| gpu_cuda.clone()); + use_context_provider(|| *gpu_cuda); use_context_provider(|| LoadedModelSignal::new(None)); use_context_provider(|| Signal::new(PromptState::default())); diff --git a/crates/slai/build.rs b/crates/slai/build.rs index 6f0ecf5..293e726 100644 --- a/crates/slai/build.rs +++ b/crates/slai/build.rs @@ -24,7 +24,7 @@ pub fn main() { let out_dir = Path::new(&out_dir); let autogen_target = out_dir.join("autogen"); - for (target, ext) in targets { + for (target, _ext) in targets { std::fs::create_dir_all(&autogen_target).unwrap(); slang.compile_all(target, "./shaders", &autogen_target, &[]); } From 56213b42a39bd3ffdebb9f04a1ecdc77f19e3da8 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 20 Oct 2025 22:46:34 +0200 Subject: [PATCH 4/5] test only on linux --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4e6cf5f..786e0a5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -32,7 +32,7 @@ jobs: setup-slang: strategy: matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest] runs-on: ${{ matrix.os }} outputs: slang-dir: ${{ steps.setup.outputs.slang-dir }} # Pass SLANG_DIR to dependent jobs From dd66fd424546ac18be95d68e71703e0df9e931e6 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Wed, 29 Oct 2025 17:05:38 +0100 Subject: [PATCH 5/5] use matrix to test on macos too, update download slang script to alow changing slang dir name --- .github/workflows/ci.yaml | 85 ++++++++++++++++++++------------------- download_slang.sh | 12 +++++- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 786e0a5..fc3c866 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -32,45 +32,34 @@ jobs: setup-slang: strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-latest, macos-latest] + include: + - os-id: linux + os: ubuntu-latest + - os-id: macos-aarch64 + os: macos-latest runs-on: ${{ matrix.os }} - outputs: - slang-dir: ${{ steps.setup.outputs.slang-dir }} # Pass SLANG_DIR to dependent jobs - slang-cache-key: ${{ steps.setup.outputs.slang-cache-key }} # Pass SLANG_DIR to dependent jobs steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Cache Slang + - uses: actions/cache@v4 id: cache-slang - uses: actions/cache/restore@v4 # Restore first with: - path: | - ~/.cache/slang # Matches script's default OUTPUT_DIR - key: slang-v$SLANG_TAG-${{ runner.os }}-${{ runner.arch }} - - - name: Setup Slang + path: ~/.cache/slang/slang-v${{ env.SLANG_TAG }}-${{ matrix.os-id }} + key: slang-v${{ env.SLANG_TAG }}-${{ matrix.os-id }} + - name: Download slang + if: steps.cache-slang.outputs.cache-hit != 'true' # Only download on miss id: setup run: | - echo "version=$SLANG_TAG" >> $GITHUB_OUTPUT # Output for cache key - SLANG_DIR=$(./download_slang.sh --version $SLANG_TAG | grep '^SLANG_DIR=' | cut -d'=' -f2-) - echo "slang-dir=$SLANG_DIR" >> $GITHUB_OUTPUT # Output for dependents - echo "slang-cache-key=slang-v$SLANG_TAG-${{ runner.os }}-${{ runner.arch }}" >> $GITHUB_OUTPUT - echo "SLANG_DIR=$SLANG_DIR" >> $GITHUB_ENV # For this job if needed - - - name: Save Slang Cache - if: steps.cache-slang.outputs.cache-hit != 'true' # Only save on miss - uses: actions/cache/save@v4 - with: - path: ~/.cache/slang - key: ${{ steps.setup.outputs.slang-cache-key }} + ./download_slang.sh --os ${{ matrix.os-id }} --version $SLANG_TAG # Run clippy lints. clippy: needs: setup-slang # Depends on setup-slang name: Clippy runs-on: ubuntu-latest env: - SLANG_DIR: ${{ needs.setup-slang.outputs.slang-dir }} + SLANG_DIR: /home/runner/.cache/slang/slang-v2025.18.2-linux + SLANG_CACHE_KEY: slang-v2025.18.2-linux timeout-minutes: 30 steps: - name: Checkout repository @@ -87,8 +76,8 @@ jobs: - name: Retrieve Cache for Slang uses: actions/cache/restore@v4 with: - path: ~/.cache/slang - key: ${{ needs.setup-slang.outputs.slang-cache-key }} + path: ~/.cache/slang/slang-v${{ env.SLANG_TAG }}-linux + key: slang-v${{ env.SLANG_TAG }}-linux - name: Populate target directory from cache uses: Leafwing-Studios/cargo-cache@v2 @@ -105,7 +94,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 env: - SLANG_DIR: ${{ needs.setup-slang.outputs.slang-dir }} + SLANG_DIR: /home/runner/.cache/slang/slang-v2025.18.2-linux + SLANG_CACHE_KEY: slang-v2025.18.2-linux steps: - name: Checkout repository uses: actions/checkout@v4 @@ -119,8 +109,8 @@ jobs: - name: Retrieve Cache for Slang uses: actions/cache/restore@v4 with: - path: ~/.cache/slang - key: ${{ needs.setup-slang.outputs.slang-cache-key }} + path: ~/.cache/slang/slang-v${{ env.SLANG_TAG }}-linux + key: ${{ env.SLANG_CACHE_KEY }} - name: Populate target directory from cache uses: Leafwing-Studios/cargo-cache@v2 @@ -129,29 +119,42 @@ jobs: - name: Check documentation run: SLANG_DIR=$SLANG_DIR cargo doc --locked --workspace --features web,desktop,mobile,comptime_checks --document-private-items --no-deps - # Testing. - test: - needs: setup-slang # Depends on setup-slang + # Testing. + testing: + needs: setup-slang name: Tests - runs-on: ubuntu-latest - timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + include: + - slang-dir: /home/runner/.cache/slang/slang-v2025.18.2-linux + os: ubuntu-latest + - slang-dir: /Users/runner/.cache/slang/slang-v2025.18.2-macos-aarch64 + os: macos-latest + - slang-cache-key: slang-v2025.18.2-linux + os: ubuntu-latest + - slang-cache-key: slang-v2025.18.2-macos-aarch64 + os: macos-latest + runs-on: ${{ matrix.os }} env: - SLANG_DIR: ${{ needs.setup-slang.outputs.slang-dir }} + SLANG_DIR: ${{ matrix.slang-dir }} + SLANG_CACHE_KEY: ${{ matrix.slang-cache-key }} + timeout-minutes: 30 steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable - - name: Install dependencies + if: ${{ runner.os == 'linux' }} run: sudo apt-get update; sudo apt-get install --no-install-recommends libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev - - name: Retrieve Cache for Slang uses: actions/cache/restore@v4 with: - path: ~/.cache/slang - key: ${{ needs.setup-slang.outputs.slang-cache-key }} + fail-on-cache-miss: true + path: ~/.cache/slang/${{ matrix.slang-cache-key }} + key: ${{ matrix.slang-cache-key }} - name: Populate target directory from cache uses: Leafwing-Studios/cargo-cache@v2 diff --git a/download_slang.sh b/download_slang.sh index 0d1738f..4cad8dc 100755 --- a/download_slang.sh +++ b/download_slang.sh @@ -14,7 +14,8 @@ usage() { echo " --os: Target OS (default: auto-detect from current platform)" echo " --output-dir: Directory to extract Slang (default: ~/.cache/slang)" echo " --version: Slang version (e.g., 2025.18.2, default: latest)" - echo "Example: $0 --os linux --output-dir /tmp/slang" + echo " --slang-dir-name: Custom name for the Slang directory (default: slang-v-)" + echo "Example: $0 --os linux --output-dir /tmp/slang --version 2025.18.2 --slang-dir-name my-slang-2025.18.2-linux" } # Parse arguments @@ -23,6 +24,7 @@ while [[ "$#" -gt 0 ]]; do --os) OS="$2"; shift ;; --output-dir) export OUTPUT_DIR="$2"; shift ;; --version) export SLANG_VERSION="$2"; shift ;; + --slang-dir-name) SLANG_DIR_NAME="$2"; shift ;; *) usage ; exit 1 ;; esac shift @@ -66,8 +68,14 @@ if [[ -z "$SLANG_VERSION" ]]; then exit 1 fi +# Set up paths - use custom name if provided, otherwise use default +if [[ -z "$SLANG_DIR_NAME" ]]; then + SLANG_DIR_NAME="slang-v$SLANG_VERSION-$OS" +fi + + # Set up paths -SLANG_DIR="$OUTPUT_DIR/slang-v$SLANG_VERSION-$OS" +SLANG_DIR="$OUTPUT_DIR/$SLANG_DIR_NAME" ZIP_URL="$SLANG_URL_BASE/$SLANG_TAG/slang-$SLANG_VERSION-$ASSET_SUFFIX" TEMP_ZIP="/tmp/slang-$SLANG_VERSION.zip"