splicer 2.4.1

Plan and generate middleware splice operations for WebAssembly component composition graphs.
Documentation
name: CI

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

env:
  CARGO_TERM_COLOR: always
  # Pinned tool versions shared across all jobs. Bump here once and
  # every install step picks it up.
  WAC_VERSION: "0.10.0"
  WASM_TOOLS_VERSION: "1.247.0"
  CVIZ_VERSION: "2.0.3"
  WKG_VERSION: "0.13.0"

jobs:
  # Figure out whether the PR / push touched code the fuzz harness
  # depends on. Downstream fuzz jobs depend on this so we don't burn
  # CI re-fuzzing unchanged code at a pinned seed.
  changes:
    name: Detect source changes
    runs-on: ubuntu-latest
    outputs:
      fuzz_relevant: ${{ steps.filter.outputs.fuzz_relevant }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            fuzz_relevant:
              - 'src/**'
              - 'wit/**'
              - 'tests/fuzz_and_run.rs'
              - 'Cargo.toml'
              - 'Cargo.lock'
              - '.github/workflows/ci.yml'

  lint:
    name: Format + Clippy
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      # Caching to increase performance as dependency tree grows
      - uses: Swatinem/rust-cache@v2

      - name: Check formatting
        run: cargo fmt --all -- --check

      - name: Run clippy
        run: cargo clippy --all-features --all-targets -- -D warnings

  # Run CLI across OS targets
  build_and_test:
    name: Build + Test (${{ matrix.os }})
    runs-on: ${{ matrix.os }}

    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive

      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: wasm32-wasip1

      # Caching per OS
      - uses: Swatinem/rust-cache@v2

      # The builtin smoke tests under tests/builtins_otel_*.rs read from
      # assets/builtins/<name>.wasm at runtime; that dir is no longer
      # checked in, so CI builds the components before `cargo test`.
      - uses: taiki-e/install-action@v2
        with:
          tool: wkg@${{ env.WKG_VERSION }},wasm-tools@${{ env.WASM_TOOLS_VERSION }}

      - name: Build builtins
        shell: bash
        run: make build-builtins

      - name: Build
        run: cargo build --locked --verbose

      - name: Run tests
        run: cargo test --locked --all-features --verbose --all-targets

  tier3_4_codegen:
   name: Tier-3/4 codegen pipeline
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@v4
     - uses: dtolnay/rust-toolchain@stable
       with:
         targets: wasm32-wasip1
     - uses: Swatinem/rust-cache@v2
     - name: Lib-level codegen tests
       run: cargo test --lib --locked -- --ignored --nocapture materialize_tier3_produces_a_component
     - name: End-to-end smoke
       run: cargo test --test tier3_4_smoke --locked -- --ignored --nocapture

  # Integration tests using the component-interposition submodule.
  # Runs the full splicer + wac + wasmtime pipeline against real components.
  integration:
   name: Integration Tests
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@v4
       with:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@1.93.0
       with:
         targets: wasm32-wasip1
     - uses: Swatinem/rust-cache@v2
     - uses: taiki-e/install-action@v2
       with:
         tool: wac-cli@${{ env.WAC_VERSION }},wasm-tools@${{ env.WASM_TOOLS_VERSION }},cviz@${{ env.CVIZ_VERSION }},wkg@${{ env.WKG_VERSION }}
     # Build builtins from the PR tree and point splicer at them via
     # SPLICER_BUILTINS_DIR so scenarios that inject builtins (e.g.
     # --builtin-hello-tier1) use the bytes under test rather than
     # whatever's published to OCI today.
     - name: Build builtins
       run: make build-builtins
     - name: Install splicer from the PR-under-test tree
       run: cargo install --path . --force
     - name: Run integration tests
       env:
         SPLICER_BUILTINS_DIR: ${{ github.workspace }}/assets/builtins
       run: cargo test --test integration -- --ignored --nocapture

  fuzz_and_run_canned:
   name: Fuzz + Run (canned)
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@v4
       with:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@stable
       with:
         targets: wasm32-wasip1
     - uses: Swatinem/rust-cache@v2
     - uses: taiki-e/install-action@v2
       with:
         tool: wac-cli@${{ env.WAC_VERSION }},wasm-tools@${{ env.WASM_TOOLS_VERSION }}
     - name: Canned shape catalog (tier-1 + tier-2)
       run: cargo test --test fuzz_and_run -- --ignored --nocapture canned

  fuzz_and_run_fuzz:
   name: Fuzz + Run (fuzz)
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@v4
       with:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@stable
       with:
         targets: wasm32-wasip1
     - uses: Swatinem/rust-cache@v2
     - uses: taiki-e/install-action@v2
       with:
         tool: wac-cli@${{ env.WAC_VERSION }},wasm-tools@${{ env.WASM_TOOLS_VERSION }}
     - name: Fuzz tier-1 + tier-2 (25 iters, depth 5)
       env:
         SPLICER_FUZZ_ITERS: "25"
         SPLICER_FUZZ_DEPTH: "5"
       run: cargo test --test fuzz_and_run -- --ignored --nocapture fuzz

  # Heavier fuzz run on every push to main — re-validates the merged
  # code against deeper shape trees than PR CI exercised. Gated on the
  # same path filter so a merge that doesn't touch fuzz-relevant paths
  # doesn't re-run this at the same pinned seed.
  fuzz_postmerge:
   name: Fuzz + Run (post-merge, heavy)
   runs-on: ubuntu-latest
   needs: changes
   if: github.event_name == 'push' && needs.changes.outputs.fuzz_relevant == 'true'
   steps:
     - uses: actions/checkout@v4
       with:
         submodules: recursive
     - uses: dtolnay/rust-toolchain@stable
       with:
         targets: wasm32-wasip1
     - uses: Swatinem/rust-cache@v2
     - uses: taiki-e/install-action@v2
       with:
         tool: wac-cli@${{ env.WAC_VERSION }},wasm-tools@${{ env.WASM_TOOLS_VERSION }}
     - name: Fuzz tier-1 + tier-2 (200 iters, depth 6, wider breadth)
       env:
         SPLICER_FUZZ_ITERS: "200"
         SPLICER_FUZZ_DEPTH: "6"
         SPLICER_FUZZ_TUPLE_MAX: "5"
         SPLICER_FUZZ_FIXED_LIST_MAX: "8"
       run: cargo test --test fuzz_and_run -- --ignored --nocapture fuzz