open-navigator / scripts /huggingface /deploy-huggingface.sh
jcbowyer's picture
Clean HuggingFace deployment without binary files
61d29fc
#!/bin/bash
# Quick deployment script for Hugging Face Spaces
# Deploys all three apps: Documentation, Frontend, and API
#
# Pre-deployment checks:
# 1. Docusaurus build verification (catches config errors early)
# 2. Docker build test (validates full deployment)
#
# Usage:
# ./deploy-huggingface.sh # Deploy with all tests
# ./deploy-huggingface.sh --skip-test # Skip tests (not recommended)
set -e
# Load environment variables from .env file if it exists
if [ -f ".env" ]; then
echo "πŸ“ Loading environment variables from .env..."
set -a # automatically export all variables
source .env
set +a
echo ""
fi
# Parse command line arguments
SKIP_TEST=false
while [[ $# -gt 0 ]]; do
case $1 in
--skip-test)
SKIP_TEST=true
shift
;;
*)
HF_USERNAME_ARG="$1"
shift
;;
esac
done
echo "πŸš€ Open Navigator - Hugging Face Deployment"
echo "==========================================================="
echo ""
# Check if HF username is provided (env var or argument)
if [ -z "$HF_USERNAME" ] && [ -z "$HF_USERNAME_ARG" ]; then
echo "❌ Error: Hugging Face username required"
echo ""
echo "Usage Option 1 (.env file - RECOMMENDED):"
echo " Add to .env file: HF_USERNAME=your_username"
echo " ./deploy-huggingface.sh"
echo ""
echo "Usage Option 2 (Environment Variable):"
echo " export HF_USERNAME=your_username"
echo " ./deploy-huggingface.sh"
echo ""
echo "Usage Option 3 (Command Argument):"
echo " ./deploy-huggingface.sh YOUR_HF_USERNAME"
echo ""
echo "Usage Option 4 (Skip Docker test - not recommended):"
echo " ./deploy-huggingface.sh YOUR_HF_USERNAME --skip-test"
echo ""
echo "Example:"
echo " echo 'HF_USERNAME=CommunityOne' >> .env"
echo " ./deploy-huggingface.sh"
echo ""
exit 1
fi
# Use argument if provided, otherwise use env var
if [ -n "$HF_USERNAME_ARG" ]; then
HF_USERNAME="$HF_USERNAME_ARG"
fi
# Deploy to the Space with custom domain configured
SPACE_NAME="open-navigator"
HF_REPO="https://huggingface.co/spaces/${HF_USERNAME}/${SPACE_NAME}"
HF_REMOTE="hf-www" # Use hf-www remote for custom domain Space
echo "πŸ“‹ Deployment Configuration"
echo " Username: $HF_USERNAME"
echo " Space: $SPACE_NAME"
echo " Remote: $HF_REMOTE"
echo " URL: $HF_REPO"
echo " Custom Domain: https://www.communityone.com"
echo ""
# Activate virtual environment if it exists
if [ -d ".venv" ]; then
echo "πŸ”§ Activating virtual environment..."
source .venv/bin/activate
fi
# Check if huggingface-hub is installed
if ! command -v hf &> /dev/null; then
echo "πŸ“¦ Installing huggingface-hub..."
pip install huggingface-hub
fi
# Authenticate with HuggingFace
echo "πŸ” Checking Hugging Face authentication..."
if ! hf whoami &> /dev/null; then
# Not logged in - try to login with token from .env
if [ -n "$HUGGINGFACE_TOKEN" ]; then
echo "πŸ”‘ Logging in with HUGGINGFACE_TOKEN from .env..."
if hf auth login --token "$HUGGINGFACE_TOKEN" --add-to-git-credential; then
echo "βœ… Successfully authenticated with token from .env"
else
echo "❌ Failed to authenticate with HUGGINGFACE_TOKEN"
echo "Please check your token in .env file"
exit 1
fi
else
echo "❌ Not logged in to Hugging Face"
echo ""
echo "Option 1: Add HUGGINGFACE_TOKEN to .env file (RECOMMENDED)"
echo " Get token from: https://huggingface.co/settings/tokens"
echo " Add to .env: HUGGINGFACE_TOKEN=hf_..."
echo ""
echo "Option 2: Login manually"
echo " hf auth login"
echo ""
exit 1
fi
else
echo "βœ… Already authenticated as: $(hf whoami)"
fi
echo ""
# Clean up old Docker artifacts to prevent disk space issues
echo "🧹 Cleaning up old Docker artifacts..."
docker stop open-navigator-test-container 2>/dev/null || true
docker rm open-navigator-test-container 2>/dev/null || true
docker rmi open-navigator-hf-test 2>/dev/null || true
echo ""
# Verify Docusaurus build before Docker (faster feedback on config errors)
echo "πŸ“š Verifying Docusaurus build..."
echo "This catches configuration errors before the slow Docker build"
echo ""
if [ -d "website/node_modules" ]; then
echo "βœ… Node modules already installed"
else
echo "πŸ“¦ Installing website dependencies..."
cd website
npm ci --prefer-offline --no-audit || npm install --prefer-offline --no-audit
cd ..
fi
echo ""
echo "πŸ”¨ Building documentation site..."
if (cd website && npm run build); then
echo ""
echo "βœ… Docusaurus build succeeded!"
echo ""
else
echo ""
echo "❌ Docusaurus build failed!"
echo ""
echo "Common issues:"
echo " - Duplicate plugin configurations (e.g., gtag in both preset and themeConfig)"
echo " - Invalid frontmatter in .md files"
echo " - Broken internal links"
echo " - Missing dependencies"
echo ""
echo "Fix the errors above before deploying."
echo "Test locally with: cd website && npm run build"
echo ""
exit 1
fi
# Run Docker build test before deployment (unless skipped)
if [ "$SKIP_TEST" = true ]; then
echo "⚠️ Skipping pre-deployment Docker build test (--skip-test flag)"
echo ""
else
echo "πŸ§ͺ Running pre-deployment Docker build test..."
echo "This ensures the build works before pushing to Hugging Face"
echo ""
if [ -f "./test-huggingface-build.sh" ]; then
chmod +x ./test-huggingface-build.sh
if ./test-huggingface-build.sh; then
echo ""
echo "βœ… Pre-deployment test passed!"
echo ""
else
echo ""
echo "❌ Pre-deployment test failed!"
echo ""
echo "Please fix the Docker build issues before deploying."
echo "Run './test-huggingface-build.sh' to test locally."
echo ""
echo "To deploy anyway (not recommended), use:"
echo " ./deploy-huggingface.sh $HF_USERNAME --skip-test"
echo ""
exit 1
fi
else
echo "⚠️ Warning: test-huggingface-build.sh not found"
echo "Skipping pre-deployment test"
echo ""
fi
fi
# Ask to create space if it doesn't exist
echo "🌟 Creating Hugging Face Space (if it doesn't exist)..."
hf repo create --type space --space-sdk docker "${HF_USERNAME}/${SPACE_NAME}" --exist-ok || true
echo ""
# Update cache-bust timestamps to force fresh build
echo "πŸ”„ Updating cache-bust timestamps to force fresh build..."
TIMESTAMP=$(date +%Y-%m-%d-%H-%M)
COMMIT_HASH=$(git rev-parse --short HEAD)
CACHE_BUST="${TIMESTAMP}-${COMMIT_HASH}"
echo " Timestamp: $TIMESTAMP"
echo " Commit: $COMMIT_HASH"
echo " Cache-bust: $CACHE_BUST"
# Update Docusaurus cache-bust
sed -i.bak "s/ARG CACHE_BUST=.*/ARG CACHE_BUST=${CACHE_BUST}/" Dockerfile
sed -i.bak "s/echo \"Cache bust: .*/echo \"Cache bust: ${CACHE_BUST}\" \&\&/" Dockerfile
# Update Frontend cache-bust
sed -i.bak "s/ARG CACHE_BUST_FRONTEND=.*/ARG CACHE_BUST_FRONTEND=${CACHE_BUST}/" Dockerfile
sed -i.bak "s/echo \"Frontend build cache bust: .*/echo \"Frontend build cache bust: \$CACHE_BUST_FRONTEND\" \&\& npm run build/" Dockerfile
# Remove backup files
rm -f Dockerfile.bak
echo "βœ… Cache-bust timestamps updated to: $CACHE_BUST"
echo ""
# Create deployment branch
echo "πŸ”§ Preparing deployment branch (clean, no binary history)..."
# Make sure we're on main
git checkout main
# Create a new orphan branch (no history) to avoid binary file issues
git branch -D huggingface-deploy 2>/dev/null || true
git checkout --orphan huggingface-deploy
# Copy Dockerfile for HF (they look for "Dockerfile" not "Dockerfile.huggingface")
echo "πŸ“ Configuring Dockerfile..."
cp Dockerfile.huggingface Dockerfile
# Copy README for Space description
echo "πŸ“ Configuring README..."
cp .huggingface/README.md README_HF.md
# Remove large binary files from being staged
# (HF Spaces rejects large binary files in git)
echo "πŸ“ Optimizing deployment (excluding binary files)..."
# Reset index to avoid staging unwanted files
git rm -rf --cached . 2>/dev/null || true
# Add deployment config files (small, safe to force)
git add -f Dockerfile README_HF.md .huggingface/ .gitignore .dockerignore
# Add source code WITHOUT -f to respect .gitignore (excludes node_modules automatically)
git add agents/ api/ config/ discovery/ extraction/ pipeline/ scripts/ tests/ visualization/
git add databricks/ examples/ models/ neon/ notebooks/
git add requirements*.txt setup.py main.py Makefile *.sh *.md *.yml *.yaml
git add CITATIONS.md CONTRIBUTING.md LICENSE INTEL_ARC_QUICKSTART.md
# Add frontend/website source EXCLUDING node_modules (gitignore handles this)
echo "🧹 Adding frontend/website sources (node_modules auto-excluded by .gitignore)..."
git add frontend/ website/
# Verify node_modules are NOT staged
NODE_MODULES_COUNT=$(git diff --cached --name-only | grep "node_modules" | wc -l)
if [ "$NODE_MODULES_COUNT" -gt 0 ]; then
echo "❌ ERROR: node_modules were staged ($NODE_MODULES_COUNT files)"
echo "This should not happen. Check .gitignore configuration."
exit 1
fi
echo "βœ… Verified: No node_modules in staging area"
echo "πŸ’Ύ Committing clean deployment (no git history)..."
git commit -m "Clean HuggingFace deployment without binary files" --allow-empty
# Add HF remote if it doesn't exist
if git remote get-url $HF_REMOTE &> /dev/null; then
echo "βœ… Hugging Face remote already configured ($HF_REMOTE)"
else
echo "πŸ”— Adding Hugging Face remote ($HF_REMOTE)..."
git remote add $HF_REMOTE "$HF_REPO"
fi
# Push to Hugging Face
echo ""
echo "πŸ“€ Pushing to Hugging Face Spaces..."
echo "This will trigger a build (takes ~10-15 minutes)"
echo ""
git push $HF_REMOTE huggingface-deploy:main --force
echo ""
echo "βœ… Deployment initiated!"
echo ""
echo "==========================================================="
echo "πŸŽ‰ Next Steps:"
echo "==========================================================="
echo ""
echo "1. View your Space:"
echo " https://huggingface.co/spaces/${HF_USERNAME}/${SPACE_NAME}"
echo ""
echo "2. Configure hardware (REQUIRED for Docker):"
echo " - Go to Settings β†’ Resource configuration"
echo " - Select 'CPU Basic' (~\$22/month minimum)"
echo ""
echo "3. Add API keys as secrets:"
echo " - Go to Settings β†’ Variables and secrets"
echo " - Add these secrets:"
echo " β€’ OPENAI_API_KEY"
echo " β€’ ANTHROPIC_API_KEY"
echo " β€’ HUGGINGFACE_TOKEN"
echo ""
echo "4. Monitor build progress:"
echo " - Click 'Logs' tab in your Space"
echo " - Build takes ~10-15 minutes"
echo ""
echo "5. Access your apps:"
echo " - Main App: https://www.communityone.com/"
echo " - Documentation: https://www.communityone.com/docs/"
echo " - API: https://www.communityone.com/api/docs"
echo ""
echo " (Also available at: https://${HF_USERNAME}-${SPACE_NAME//./-}.hf.space/)"
echo ""
echo "==========================================================="
echo ""
echo "πŸ“– Full guide: ./HUGGINGFACE_DEPLOYMENT.md"
echo ""