#!/usr/bin/env bash # ── Deploy to HuggingFace Spaces ───────────────────────────────────────────── # Validates the file layout BEFORE pushing, because the most common failure is # integrations/ never reaching the Space (the HF web uploader skips folders), # which crashes startup with ModuleNotFoundError. # # Usage: ./deploy.sh # Example: ./deploy.sh plotweaver hausa-voice-agent set -euo pipefail USER="${1:-}" SPACE="${2:-}" if [[ -z "$USER" || -z "$SPACE" ]]; then echo "Usage: ./deploy.sh " exit 1 fi echo "── Validating layout ─────────────────────────────────────────" REQUIRED=( app.py pipeline.py nlu.py orchestrator.py vad.py streaming_asr.py requirements.txt README.md integrations/__init__.py integrations/crm.py integrations/sip.py integrations/whatsapp.py ) MISSING=0 for f in "${REQUIRED[@]}"; do if [[ -f "$f" ]]; then printf ' ✓ %s\n' "$f" else printf ' ✗ %s MISSING\n' "$f" MISSING=1 fi done if [[ $MISSING -eq 1 ]]; then echo "" echo "Refusing to deploy: files are missing. The Space would crash on boot." exit 1 fi echo "" echo "── Running tests ─────────────────────────────────────────────" python verify_boot.py || { echo "Boot check failed."; exit 1; } python test_app.py || { echo "App launch test failed."; exit 1; } python test_streaming.py || { echo "Streaming tests failed."; exit 1; } python test_regressions.py || { echo "NLU tests failed."; exit 1; } echo "" echo "── Pushing to Space ──────────────────────────────────────────" if [[ ! -d .git ]]; then git init -q git remote add origin "https://huggingface.co/spaces/${USER}/${SPACE}" fi git add -A # -A, not '.', so nothing is quietly skipped echo "" echo "Staged files:" git status --short echo "" read -r -p "Push these to ${USER}/${SPACE}? [y/N] " CONFIRM [[ "$CONFIRM" == "y" || "$CONFIRM" == "Y" ]] || { echo "Aborted."; exit 0; } git commit -q -m "Deploy Hausa Voice AI Agent" || echo "Nothing new to commit." git push -u origin main echo "" echo "Done → https://huggingface.co/spaces/${USER}/${SPACE}" echo "Set HF_TOKEN under Settings → Variables and secrets for best NLU quality."