Add CI/CD pipelines, serve health checks, and worker CLI improvements #29
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: Validation | |
| on: | |
| pull_request: | |
| branches: [master] | |
| push: | |
| branches: [master] | |
| # Cancel previous runs when new commits are pushed | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Build | |
| run: cargo build --release | |
| - name: Upload binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: llmnet-binary | |
| path: target/release/llmnet | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Run tests | |
| run: cargo test --all-features | |
| validate-examples: | |
| name: Validate Examples | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: llmnet-binary | |
| path: ./bin | |
| - name: Make binary executable | |
| run: chmod +x ./bin/llmnet | |
| - name: Validate nemotron-router example | |
| run: ./bin/llmnet validate examples/nemotron-router.json | |
| - name: Validate openrouter-pipeline example | |
| run: ./bin/llmnet validate examples/openrouter-pipeline.json | |
| - name: Validate basic-chatbot example | |
| run: ./bin/llmnet validate examples/basic-chatbot.json | |
| - name: Validate dual-expert example | |
| run: ./bin/llmnet validate examples/dual-expert.json | |
| - name: Validate multi-layer-pipeline example | |
| run: ./bin/llmnet validate examples/multi-layer-pipeline.json | |
| - name: Validate conditional-routing example | |
| run: ./bin/llmnet validate examples/conditional-routing.json | |
| deploy-test: | |
| name: Deploy & Test Pipeline | |
| runs-on: ubuntu-latest | |
| needs: [build, test, validate-examples] | |
| # Only run on PRs to avoid unnecessary API usage | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: llmnet-binary | |
| path: ./bin | |
| - name: Make binary executable | |
| run: chmod +x ./bin/llmnet | |
| - name: Create runtime config with secret | |
| run: | | |
| sed 's/\$OPENROUTER_API_KEY_FREE/${{ secrets.OPENROUTER_API_KEY_FREE }}/g' \ | |
| examples/openrouter-pipeline.json > /tmp/runtime-config.json | |
| - name: Start llmnet server | |
| run: | | |
| ./bin/llmnet run /tmp/runtime-config.json & | |
| sleep 5 | |
| echo "Server started" | |
| - name: Health check | |
| run: | | |
| curl -f http://localhost:8080/health || exit 1 | |
| echo "Health check passed" | |
| - name: Test chat completion | |
| run: | | |
| response=$(curl -s -X POST http://localhost:8080/v1/chat/completions \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "llmnet", | |
| "messages": [{"role": "user", "content": "Say hello in exactly 3 words"}], | |
| "max_tokens": 50 | |
| }') | |
| echo "Response: $response" | |
| # Check that we got a valid response | |
| echo "$response" | grep -q "choices" || exit 1 | |
| echo "Chat completion test passed" | |
| deploy-test-multilayer: | |
| name: Deploy & Test Multi-Layer Pipeline | |
| runs-on: ubuntu-latest | |
| needs: [build, test, validate-examples] | |
| # Only run on PRs to avoid unnecessary API usage | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: llmnet-binary | |
| path: ./bin | |
| - name: Make binary executable | |
| run: chmod +x ./bin/llmnet | |
| - name: Create runtime config with secret | |
| run: | | |
| sed 's/\$OPENROUTER_API_KEY_FREE/${{ secrets.OPENROUTER_API_KEY_FREE }}/g' \ | |
| examples/multi-layer-pipeline.json > /tmp/runtime-config.json | |
| - name: Start llmnet server | |
| run: | | |
| ./bin/llmnet run /tmp/runtime-config.json & | |
| sleep 5 | |
| echo "Server started" | |
| - name: Health check | |
| run: | | |
| curl -f http://localhost:8080/health || exit 1 | |
| echo "Health check passed" | |
| - name: Test multi-layer technical query | |
| run: | | |
| response=$(curl -s -X POST http://localhost:8080/v1/chat/completions \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "llmnet", | |
| "messages": [{"role": "user", "content": "What is 2+2? Answer with just the number."}], | |
| "max_tokens": 50 | |
| }') | |
| echo "Technical Response: $response" | |
| echo "$response" | grep -q "choices" || exit 1 | |
| echo "Multi-layer technical test passed" | |
| - name: Test multi-layer creative query | |
| run: | | |
| response=$(curl -s -X POST http://localhost:8080/v1/chat/completions \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "llmnet", | |
| "messages": [{"role": "user", "content": "Write a haiku about the moon."}], | |
| "max_tokens": 100 | |
| }') | |
| echo "Creative Response: $response" | |
| echo "$response" | grep -q "choices" || exit 1 | |
| echo "Multi-layer creative test passed" | |
| deploy-test-conditional: | |
| name: Deploy & Test Conditional Routing | |
| runs-on: ubuntu-latest | |
| needs: [build, test, validate-examples] | |
| # Only run on PRs to avoid unnecessary API usage | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: llmnet-binary | |
| path: ./bin | |
| - name: Make binary executable | |
| run: chmod +x ./bin/llmnet | |
| - name: Create runtime config with secret | |
| run: | | |
| sed 's/\$OPENROUTER_API_KEY_FREE/${{ secrets.OPENROUTER_API_KEY_FREE }}/g' \ | |
| examples/conditional-routing.json > /tmp/runtime-config.json | |
| - name: Start llmnet server | |
| run: | | |
| ./bin/llmnet run /tmp/runtime-config.json & | |
| sleep 5 | |
| echo "Server started" | |
| - name: Health check | |
| run: | | |
| curl -f http://localhost:8080/health || exit 1 | |
| echo "Health check passed" | |
| - name: Test short input routing (should use short-input-handler) | |
| run: | | |
| response=$(curl -s -X POST http://localhost:8080/v1/chat/completions \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "llmnet", | |
| "messages": [{"role": "user", "content": "Hello world"}], | |
| "max_tokens": 50 | |
| }') | |
| echo "Short input response: $response" | |
| echo "$response" | grep -q "choices" || exit 1 | |
| echo "Short input conditional routing test passed" | |
| - name: Test long input routing (should use long-input-handler + refiner) | |
| run: | | |
| response=$(curl -s -X POST http://localhost:8080/v1/chat/completions \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "model": "llmnet", | |
| "messages": [{"role": "user", "content": "Please explain in detail the differences between procedural programming and object-oriented programming, including examples of each paradigm."}], | |
| "max_tokens": 200 | |
| }') | |
| echo "Long input response: $response" | |
| echo "$response" | grep -q "choices" || exit 1 | |
| echo "Long input conditional routing test passed" |