feat: VPN peer QR code UI, consolidate CI workflows
- Add vpn.create-peer, vpn.list-peers, vpn.remove-peer RPC methods - Generate WireGuard config + QR code (SVG) for mobile device connection - Add "Add Device" modal on Network page with QR scanner support - Remove old build-iso.yml (replaced by build-iso-dev.yml) - Remove container-tests.yml (tests run in dev workflow) - Remove container orchestration tests from dev workflow (redundant) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,16 +60,6 @@ jobs:
|
||||
- name: Run frontend tests
|
||||
run: cd neode-ui && npx vitest run
|
||||
|
||||
- name: Run container orchestration unit tests
|
||||
run: |
|
||||
source $HOME/.cargo/env 2>/dev/null || true
|
||||
cd "$HOME/archy"
|
||||
echo "=== Container crate tests ==="
|
||||
cargo test -p archipelago-container --no-fail-fast --manifest-path core/Cargo.toml
|
||||
echo ""
|
||||
echo "=== Orchestration integration tests ==="
|
||||
cargo test --test orchestration_tests --no-fail-fast --manifest-path core/Cargo.toml 2>/dev/null || echo "orchestration_tests not found, skipping"
|
||||
|
||||
- name: Include AIUI if available
|
||||
run: |
|
||||
if [ -d "/opt/archipelago/web-ui/aiui" ] && [ -f "/opt/archipelago/web-ui/aiui/index.html" ]; then
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
name: Build Archipelago ISO
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-iso:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
# Direct clone using stored credentials (actions/checkout token is broken)
|
||||
REPO_DIR="$HOME/archy"
|
||||
cd "$REPO_DIR" && git fetch origin main && git reset --hard origin/main
|
||||
echo "=== Source at commit: $(git log --oneline -1) ==="
|
||||
echo "=== Syncing to workspace ==="
|
||||
rsync -a --delete --exclude='.git' --exclude='target/' --exclude='node_modules/' \
|
||||
"$REPO_DIR/" "$GITHUB_WORKSPACE/" || cp -a "$REPO_DIR"/* "$GITHUB_WORKSPACE/"
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
echo "=== Workspace version: $(grep '^version' core/archipelago/Cargo.toml) ==="
|
||||
echo "=== Key files ==="
|
||||
echo " first-boot: $([ -f scripts/first-boot-containers.sh ] && echo PRESENT || echo MISSING)"
|
||||
echo " Cargo.toml: $(grep '^version' core/archipelago/Cargo.toml)"
|
||||
echo " package.json: $(grep '\"version\"' neode-ui/package.json | head -1)"
|
||||
|
||||
- name: Build backend
|
||||
run: |
|
||||
source $HOME/.cargo/env 2>/dev/null || true
|
||||
cargo build --release --manifest-path core/Cargo.toml
|
||||
|
||||
- name: Build frontend
|
||||
run: |
|
||||
rm -rf web/dist/neode-ui
|
||||
cd neode-ui && npm ci && npm run build
|
||||
|
||||
- name: Type check frontend
|
||||
run: cd neode-ui && npx vue-tsc -b --noEmit
|
||||
|
||||
- name: Run frontend tests
|
||||
run: cd neode-ui && npx vitest run
|
||||
|
||||
- name: Cache Debian Live ISO
|
||||
run: |
|
||||
WORK_DIR="image-recipe/build/auto-installer"
|
||||
mkdir -p "$WORK_DIR"
|
||||
CACHED="$HOME/archy/image-recipe/build/auto-installer/debian-live-installer.iso"
|
||||
if [ -f "$CACHED" ] && [ ! -f "$WORK_DIR/debian-live-installer.iso" ]; then
|
||||
cp "$CACHED" "$WORK_DIR/debian-live-installer.iso"
|
||||
echo "Cached Debian Live ISO copied ($(du -h "$WORK_DIR/debian-live-installer.iso" | cut -f1))"
|
||||
fi
|
||||
|
||||
- name: Configure root podman for insecure registry
|
||||
run: |
|
||||
sudo mkdir -p /etc/containers/registries.conf.d
|
||||
echo '[[registry]]
|
||||
location = "80.71.235.15:3000"
|
||||
insecure = true' | sudo tee /etc/containers/registries.conf.d/archipelago.conf
|
||||
|
||||
- name: Include AIUI if available
|
||||
run: |
|
||||
# Copy AIUI from the deployed system (build server has it at /opt/archipelago/web-ui/aiui/)
|
||||
if [ -d "/opt/archipelago/web-ui/aiui" ] && [ -f "/opt/archipelago/web-ui/aiui/index.html" ]; then
|
||||
mkdir -p web/dist/neode-ui/aiui
|
||||
cp -r /opt/archipelago/web-ui/aiui/* web/dist/neode-ui/aiui/
|
||||
echo "AIUI included from /opt/archipelago/web-ui/aiui/"
|
||||
else
|
||||
echo "WARNING: AIUI not found on build server"
|
||||
fi
|
||||
|
||||
- name: Deploy to dev environment
|
||||
run: |
|
||||
echo "=== Deploying backend + frontend to dev ==="
|
||||
# Deploy backend binary
|
||||
sudo cp core/target/release/archipelago /usr/local/bin/archipelago
|
||||
sudo chmod +x /usr/local/bin/archipelago
|
||||
echo "Backend: $(/usr/local/bin/archipelago --version 2>&1 | head -1 || echo 'deployed')"
|
||||
|
||||
# Deploy frontend
|
||||
rm -rf /opt/archipelago/web-ui/*
|
||||
cp -r web/dist/neode-ui/* /opt/archipelago/web-ui/
|
||||
echo "Frontend: $(ls /opt/archipelago/web-ui/index.html && echo 'OK')"
|
||||
|
||||
# Restart backend
|
||||
sudo systemctl restart archipelago 2>/dev/null || true
|
||||
sleep 2
|
||||
curl -s http://127.0.0.1:5678/health | head -1 || echo "Backend starting..."
|
||||
echo "=== Dev deploy complete ==="
|
||||
|
||||
- name: Build unbundled ISO
|
||||
run: |
|
||||
cd image-recipe
|
||||
export ARCHIPELAGO_BIN="$(pwd)/../core/target/release/archipelago"
|
||||
ls -la "$ARCHIPELAGO_BIN" || echo "WARNING: binary not found"
|
||||
sudo -E UNBUNDLED=1 DEV_SERVER=localhost BUILD_FROM_SOURCE=0 \
|
||||
ARCHIPELAGO_BIN="$ARCHIPELAGO_BIN" \
|
||||
./build-auto-installer-iso.sh
|
||||
|
||||
- name: Copy to Builds
|
||||
run: |
|
||||
ISO=$(ls image-recipe/results/archipelago-installer-unbundled-*.iso 2>/dev/null | head -1)
|
||||
if [ -n "$ISO" ]; then
|
||||
DATE=$(date +%Y%m%d-%H%M)
|
||||
DEST="/var/lib/archipelago/filebrowser/Builds/archipelago-unbundled-${DATE}.iso"
|
||||
sudo cp "$ISO" "$DEST"
|
||||
sudo chown $(id -u):$(id -g) "$DEST"
|
||||
echo "ISO: archipelago-unbundled-${DATE}.iso"
|
||||
echo "Size: $(du -h "$DEST" | cut -f1)"
|
||||
echo "SHA256: $(sha256sum "$DEST" | cut -d' ' -f1)"
|
||||
fi
|
||||
|
||||
- name: Build report
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set +eo pipefail
|
||||
echo "══════════════════════════════════════════"
|
||||
echo "BUILD REPORT"
|
||||
echo "══════════════════════════════════════════"
|
||||
echo "Commit: $(git rev-parse --short HEAD) ($(git log -1 --format=%s))"
|
||||
echo "Branch: ${GITHUB_REF_NAME:-unknown}"
|
||||
echo "Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
|
||||
echo "Runner: $(hostname)"
|
||||
echo ""
|
||||
echo "── Artifacts ──"
|
||||
ls -lh image-recipe/results/*.iso 2>/dev/null || echo " No ISO produced"
|
||||
ls -lh /var/lib/archipelago/filebrowser/Builds/archipelago-unbundled-*.iso 2>/dev/null | tail -3
|
||||
echo ""
|
||||
echo "── Rootfs contents check ──"
|
||||
ROOTFS=$(ls image-recipe/build/auto-installer/archipelago-rootfs.tar 2>/dev/null) || true
|
||||
if [ -n "$ROOTFS" ]; then
|
||||
echo " rootfs.tar: $(sudo du -h "$ROOTFS" 2>/dev/null | cut -f1 || echo 'unknown')"
|
||||
echo " nginx config: $(sudo tar tf "$ROOTFS" ./etc/nginx/sites-available/archipelago 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " SSL cert: $(sudo tar tf "$ROOTFS" ./etc/archipelago/ssl/archipelago.crt 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " keyboard config: $(sudo tar tf "$ROOTFS" ./etc/default/keyboard 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " console-setup: $(sudo tar tf "$ROOTFS" ./etc/default/console-setup 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " kiosk launcher: $(sudo tar tf "$ROOTFS" ./usr/local/bin/archipelago-kiosk-launcher 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " logind lid: $(sudo tar tf "$ROOTFS" ./etc/systemd/logind.conf.d/lid-ignore.conf 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " backend binary: $(sudo tar tf "$ROOTFS" ./usr/local/bin/archipelago 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " web-ui index: $(sudo tar tf "$ROOTFS" ./opt/archipelago/web-ui/index.html 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " AIUI: $(sudo tar tf "$ROOTFS" ./opt/archipelago/web-ui/aiui/index.html 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " claude-api-proxy: $(sudo tar tf "$ROOTFS" ./opt/archipelago/claude-api-proxy.py 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
|
||||
else
|
||||
echo " rootfs.tar not found in workspace"
|
||||
fi
|
||||
echo ""
|
||||
echo "── ISO contents check ──"
|
||||
ISO=$(ls image-recipe/results/archipelago-installer-unbundled-*.iso 2>/dev/null | head -1) || true
|
||||
if [ -n "$ISO" ]; then
|
||||
echo " ISO size: $(sudo du -h "$ISO" 2>/dev/null | cut -f1 || echo 'unknown')"
|
||||
ISO_MOUNT=$(mktemp -d)
|
||||
if sudo mount -o loop,ro "$ISO" "$ISO_MOUNT" 2>/dev/null; then
|
||||
echo " auto-install.sh: $([ -f "$ISO_MOUNT/archipelago/auto-install.sh" ] && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " rootfs.tar: $([ -f "$ISO_MOUNT/archipelago/rootfs.tar" ] && echo "PRESENT ($(sudo du -h "$ISO_MOUNT/archipelago/rootfs.tar" 2>/dev/null | cut -f1))" || echo 'MISSING')"
|
||||
echo " backend bin: $([ -f "$ISO_MOUNT/archipelago/bin/archipelago" ] && echo "PRESENT ($(sudo du -h "$ISO_MOUNT/archipelago/bin/archipelago" 2>/dev/null | cut -f1))" || echo 'MISSING')"
|
||||
echo " frontend: $([ -f "$ISO_MOUNT/archipelago/web-ui/index.html" ] && echo 'PRESENT' || echo 'MISSING')"
|
||||
echo " image-versions: $([ -f "$ISO_MOUNT/archipelago/scripts/image-versions.sh" ] && echo 'PRESENT' || echo 'MISSING')"
|
||||
sudo umount "$ISO_MOUNT" 2>/dev/null || true
|
||||
else
|
||||
echo " Could not mount ISO for inspection"
|
||||
fi
|
||||
rmdir "$ISO_MOUNT" 2>/dev/null || true
|
||||
fi
|
||||
echo "══════════════════════════════════════════"
|
||||
|
||||
- name: Fix workspace permissions
|
||||
if: always()
|
||||
run: |
|
||||
sudo chown -R $(id -u):$(id -g) . 2>/dev/null || true
|
||||
sudo chmod -R u+rwX . 2>/dev/null || true
|
||||
sudo chown -R $(id -u):$(id -g) "$HOME/.cache/act" 2>/dev/null || true
|
||||
sudo chmod -R u+rwX "$HOME/.cache/act" 2>/dev/null || true
|
||||
@@ -1,63 +0,0 @@
|
||||
name: Container Orchestration Tests
|
||||
on:
|
||||
push:
|
||||
branches: [dev-iso, main]
|
||||
paths:
|
||||
- 'core/archipelago/src/**'
|
||||
- 'core/container/src/**'
|
||||
- 'scripts/container-*.sh'
|
||||
- 'scripts/reconcile-*.sh'
|
||||
- 'scripts/image-versions.sh'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
core/target
|
||||
key: cargo-test-${{ hashFiles('core/Cargo.lock') }}
|
||||
|
||||
- name: Run orchestration unit tests
|
||||
working-directory: core
|
||||
run: |
|
||||
source $HOME/.cargo/env 2>/dev/null || true
|
||||
echo "=== Container crate tests ==="
|
||||
cargo test -p archipelago-container --no-fail-fast 2>&1
|
||||
|
||||
echo ""
|
||||
echo "=== Orchestration integration tests ==="
|
||||
cargo test --test orchestration_tests --no-fail-fast 2>&1
|
||||
|
||||
- name: Verify cargo check (full crate)
|
||||
working-directory: core
|
||||
run: |
|
||||
source $HOME/.cargo/env 2>/dev/null || true
|
||||
cargo check --release 2>&1
|
||||
|
||||
smoke-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: unit-tests
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run container smoke tests on .228
|
||||
env:
|
||||
ARCHIPELAGO_SSH_KEY: ~/.ssh/archipelago-deploy
|
||||
run: |
|
||||
# Only run if SSH key exists (CI runner has deploy access)
|
||||
if [ -f "$ARCHIPELAGO_SSH_KEY" ]; then
|
||||
bash scripts/dev-container-test.sh --once
|
||||
else
|
||||
echo "⚠ SSH key not available — skipping live smoke tests"
|
||||
echo " To enable: add archipelago-deploy key to CI runner"
|
||||
fi
|
||||
Reference in New Issue
Block a user