Explorer
/opt/struktur/buzz/.github/workflows/mesh-lifecycle.yml
← Zurück ↓ Download
name: Mesh Lifecycle
# Relay-driven mesh lifecycle smoke: membership → signed discovery notes →
# relay-derived allowlist → join → CPU inference over QUIC → stranger denied
# (relay membership rejection + no routed inference, with a differential
# trusted-inference health proof so a dead serve node can't fake a denial).
# Runs the full Buzz "shared compute" join story with three real mesh-llm
# node processes on one runner, using the Buzz relay as the control plane
# (no hand-carried invite tokens). Mirrors the shape mesh-llm's own CI uses
# for its two-node smokes (tiny CPU model, one runner, real QUIC mesh).

on:
  push:
    branches: [main]
    paths:
      - 'crates/buzz-relay/examples/mesh_*.rs'
      - 'crates/buzz-relay/Cargo.toml'
      - 'crates/buzz-admin/**'
      - 'crates/buzz-test-client/**'
      - 'crates/buzz-ws-client/**'
      - 'Cargo.lock'
      - 'desktop/src-tauri/src/mesh_llm/**'
      - 'scripts/ci-mesh-lifecycle-smoke.sh'
      - 'scripts/start-relay-for-tests.sh'
      - '.github/workflows/mesh-lifecycle.yml'
  pull_request:
    paths:
      - 'crates/buzz-relay/examples/mesh_*.rs'
      - 'crates/buzz-relay/Cargo.toml'
      - 'crates/buzz-admin/**'
      - 'crates/buzz-test-client/**'
      - 'crates/buzz-ws-client/**'
      - 'Cargo.lock'
      - 'desktop/src-tauri/src/mesh_llm/**'
      - 'scripts/ci-mesh-lifecycle-smoke.sh'
      - 'scripts/start-relay-for-tests.sh'
      - '.github/workflows/mesh-lifecycle.yml'
  workflow_dispatch:

concurrency:
  group: mesh-lifecycle-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
  CARGO_TERM_COLOR: always

jobs:
  lifecycle-smoke:
    name: Relay-Driven Mesh Lifecycle Smoke
    runs-on: ubuntu-24.04
    timeout-minutes: 45
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

      - uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1

      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
        with:
          save-if: ${{ github.event_name != 'pull_request' }}

      # The mesh-llm SDK downloads a signed native runtime (llama.cpp CPU
      # build) on first init, and the serve node downloads the smoke model
      # from HuggingFace on first run. Key on the lockfile so a mesh pin bump
      # rolls the runtime cache; the model ref is stable.
      - name: Restore mesh runtime + model caches
        id: mesh-caches
        uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
        with:
          path: |
            ~/.cache/mesh-llm/native-runtimes
            ~/.cache/huggingface/hub
          key: mesh-lifecycle-${{ runner.os }}-smollm2-135m-${{ hashFiles('Cargo.lock') }}
          restore-keys: |
            mesh-lifecycle-${{ runner.os }}-smollm2-135m-

      - name: Start integration services
        run: |
          for attempt in 1 2 3; do
            if docker compose up -d postgres redis minio minio-init; then
              break
            fi
            if [ "$attempt" -eq 3 ]; then
              echo "docker compose up failed after 3 attempts" >&2
              exit 1
            fi
            echo "docker compose up failed (attempt $attempt), retrying in $((attempt * 5))s..." >&2
            sleep $((attempt * 5))
          done

      - name: Run relay-driven mesh lifecycle smoke
        run: ./scripts/ci-mesh-lifecycle-smoke.sh 2>&1 | tee /tmp/mesh-lifecycle-harness.log

      - name: Save mesh runtime + model caches
        if: github.ref == 'refs/heads/main' && steps.mesh-caches.outputs.cache-hit != 'true'
        uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
        with:
          path: |
            ~/.cache/mesh-llm/native-runtimes
            ~/.cache/huggingface/hub
          key: mesh-lifecycle-${{ runner.os }}-smollm2-135m-${{ hashFiles('Cargo.lock') }}

      - name: Upload relay + harness logs
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
        with:
          name: mesh-lifecycle-logs
          path: |
            /tmp/buzz-relay.log
            /tmp/mesh-lifecycle-harness.log
          if-no-files-found: ignore