From b2bb5f319eb2f26993c0a3a120086669a786da87 Mon Sep 17 00:00:00 2001 From: Dorian Date: Sat, 21 Mar 2026 03:08:00 +0000 Subject: [PATCH] feat: add E2E smoke test script and CI/CD pipeline plan - Create scripts/smoke-test.sh for live server verification (7 checks) - Document planned GitHub Actions CI/CD pipeline in docs/ci-cd-plan.md - Integration tests deferred to future task (require test harness setup) Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/ci-cd-plan.md | 37 +++++++++++++++++++ scripts/smoke-test.sh | 86 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 docs/ci-cd-plan.md create mode 100755 scripts/smoke-test.sh diff --git a/docs/ci-cd-plan.md b/docs/ci-cd-plan.md new file mode 100644 index 00000000..9a7042b6 --- /dev/null +++ b/docs/ci-cd-plan.md @@ -0,0 +1,37 @@ +# CI/CD Pipeline Plan + +## CI Workflow (on push to main + PRs) + +### Jobs +1. **Rust checks** + - `cargo clippy --all-targets --all-features` (zero warnings) + - `cargo fmt --all -- --check` + - `cargo test --all-features` + +2. **Frontend checks** + - `npm run type-check` (vue-tsc) + - `npm run lint` (eslint) + - `npm test` (vitest) + +3. **Script validation** + - `bash -n` on all .sh files + - `shellcheck` on critical scripts + +### Merge policy +All checks must pass before merge. + +## Release Workflow (on tag push v*) + +### Jobs +1. Build Linux binary (cross-compile x86_64 + ARM64) +2. Build frontend (`npm run build`) +3. ISO build via SSH to build server +4. QEMU smoke test of ISO + +## Pre-requisites +- GitHub Actions runners with Rust toolchain +- SSH key for build server access +- Branch protection on main +- Image digest manifest from `scripts/image-versions.sh` + +## Estimated implementation: 2 weeks diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh new file mode 100755 index 00000000..b54a3074 --- /dev/null +++ b/scripts/smoke-test.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# Smoke test for Archipelago — verifies critical endpoints +# Usage: ./scripts/smoke-test.sh [host] +# Exit 0 if all pass, exit 1 on any failure. + +set -euo pipefail + +HOST="${1:-192.168.1.198}" +PASS=0 +FAIL=0 +FAILURES="" + +check() { + local name="$1" cmd="$2" + if eval "$cmd" >/dev/null 2>&1; then + echo " ✓ $name" + PASS=$((PASS + 1)) + else + echo " ✗ $name" + FAIL=$((FAIL + 1)) + FAILURES="$FAILURES\n - $name" + fi +} + +echo "=== Archipelago Smoke Test ===" +echo "Target: $HOST" +echo "" + +# 1. Health endpoint +check "GET /health returns OK" \ + "curl -sf http://${HOST}/health | grep -q '\"status\"'" + +# 2. Login via RPC +SESSION=$(curl -sf -X POST "http://${HOST}/rpc/v1" \ + -H 'Content-Type: application/json' \ + -d '{"method":"auth.login","params":{"password":"'"${TEST_PASSWORD:-password123}"'"}}' \ + -c - 2>/dev/null | grep session | awk '{print $NF}' || echo "") + +if [ -n "$SESSION" ]; then + echo " ✓ Login via RPC" + PASS=$((PASS + 1)) +else + echo " ✗ Login via RPC" + FAIL=$((FAIL + 1)) + FAILURES="$FAILURES\n - Login via RPC" +fi + +# 3. Authenticated RPC call +check "server.get-info returns JSON" \ + "curl -sf -X POST http://${HOST}/rpc/v1 \ + -H 'Content-Type: application/json' \ + -b 'session=${SESSION}' \ + -d '{\"method\":\"server.get-info\"}' | grep -q '\"result\"'" + +# 4. Container list +check "container.list returns JSON" \ + "curl -sf -X POST http://${HOST}/rpc/v1 \ + -H 'Content-Type: application/json' \ + -b 'session=${SESSION}' \ + -d '{\"method\":\"container.list\"}' | grep -q '\"result\"'" + +# 5. WebSocket upgrade +check "WebSocket upgrade (101)" \ + "curl -sf -o /dev/null -w '%{http_code}' \ + -H 'Upgrade: websocket' -H 'Connection: Upgrade' \ + -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \ + -H 'Sec-WebSocket-Version: 13' \ + http://${HOST}/ws/db | grep -q '101'" + +# 6. Static assets served +check "Frontend index.html served" \ + "curl -sf http://${HOST}/ | grep -q '