Spaces:
Sleeping
Sleeping
chore: remove .github workflows from HF deployment
Browse files
.github/workflows/ci-cd-pipeline.yml
DELETED
|
@@ -1,470 +0,0 @@
|
|
| 1 |
-
name: SAAP CI/CD Pipeline
|
| 2 |
-
|
| 3 |
-
on:
|
| 4 |
-
push:
|
| 5 |
-
branches: [ main, develop ]
|
| 6 |
-
pull_request:
|
| 7 |
-
branches: [ main, develop ]
|
| 8 |
-
release:
|
| 9 |
-
types: [ published ]
|
| 10 |
-
|
| 11 |
-
env:
|
| 12 |
-
REGISTRY: ghcr.io
|
| 13 |
-
IMAGE_NAME_BACKEND: ${{ github.repository }}/backend
|
| 14 |
-
IMAGE_NAME_FRONTEND: ${{ github.repository }}/frontend
|
| 15 |
-
|
| 16 |
-
jobs:
|
| 17 |
-
# ==========================================
|
| 18 |
-
# JOB 1: Security Scanning
|
| 19 |
-
# ==========================================
|
| 20 |
-
security-scan:
|
| 21 |
-
name: Security Checks
|
| 22 |
-
runs-on: ubuntu-latest
|
| 23 |
-
steps:
|
| 24 |
-
- name: Checkout code
|
| 25 |
-
uses: actions/checkout@v4
|
| 26 |
-
with:
|
| 27 |
-
fetch-depth: 0
|
| 28 |
-
|
| 29 |
-
- name: Install Gitleaks
|
| 30 |
-
run: |
|
| 31 |
-
wget -q https://github.com/gitleaks/gitleaks/releases/download/v8.18.4/gitleaks_8.18.4_linux_x64.tar.gz
|
| 32 |
-
tar -xzf gitleaks_8.18.4_linux_x64.tar.gz
|
| 33 |
-
sudo mv gitleaks /usr/local/bin/
|
| 34 |
-
gitleaks version
|
| 35 |
-
|
| 36 |
-
- name: Run Gitleaks Scan
|
| 37 |
-
run: |
|
| 38 |
-
gitleaks detect --source . --config .gitleaks.toml --verbose --no-git
|
| 39 |
-
|
| 40 |
-
- name: Python Security Check (Safety)
|
| 41 |
-
run: |
|
| 42 |
-
pip install safety
|
| 43 |
-
safety check --file requirements.txt --output text || true
|
| 44 |
-
|
| 45 |
-
- name: Node.js Security Check (npm audit)
|
| 46 |
-
working-directory: ./frontend
|
| 47 |
-
run: |
|
| 48 |
-
npm install
|
| 49 |
-
npm audit --audit-level=moderate || true
|
| 50 |
-
|
| 51 |
-
# ==========================================
|
| 52 |
-
# JOB 2: Backend Testing (Python/FastAPI)
|
| 53 |
-
# ==========================================
|
| 54 |
-
backend-tests:
|
| 55 |
-
name: Backend Tests (Python)
|
| 56 |
-
runs-on: ubuntu-latest
|
| 57 |
-
needs: security-scan
|
| 58 |
-
|
| 59 |
-
services:
|
| 60 |
-
postgres:
|
| 61 |
-
image: postgres:15-alpine
|
| 62 |
-
env:
|
| 63 |
-
POSTGRES_USER: saap_test
|
| 64 |
-
POSTGRES_PASSWORD: test_password
|
| 65 |
-
POSTGRES_DB: saap_test
|
| 66 |
-
ports:
|
| 67 |
-
- 5432:5432
|
| 68 |
-
options: >-
|
| 69 |
-
--health-cmd pg_isready
|
| 70 |
-
--health-interval 10s
|
| 71 |
-
--health-timeout 5s
|
| 72 |
-
--health-retries 5
|
| 73 |
-
|
| 74 |
-
steps:
|
| 75 |
-
- name: Checkout code
|
| 76 |
-
uses: actions/checkout@v4
|
| 77 |
-
|
| 78 |
-
- name: Set up Python 3.11
|
| 79 |
-
uses: actions/setup-python@v5
|
| 80 |
-
with:
|
| 81 |
-
python-version: '3.11'
|
| 82 |
-
cache: 'pip'
|
| 83 |
-
|
| 84 |
-
- name: Install dependencies
|
| 85 |
-
run: |
|
| 86 |
-
python -m pip install --upgrade pip
|
| 87 |
-
pip install -r requirements.txt
|
| 88 |
-
pip install pytest pytest-cov pytest-asyncio
|
| 89 |
-
|
| 90 |
-
- name: Run Backend Tests
|
| 91 |
-
env:
|
| 92 |
-
DATABASE_URL: postgresql://saap_test:test_password@localhost:5432/saap_test
|
| 93 |
-
PYTHONPATH: ${{ github.workspace }}/backend
|
| 94 |
-
run: |
|
| 95 |
-
pytest backend/ -v --cov=backend --cov-report=xml --cov-report=term
|
| 96 |
-
|
| 97 |
-
- name: Upload Coverage to Codecov
|
| 98 |
-
uses: codecov/codecov-action@v3
|
| 99 |
-
with:
|
| 100 |
-
files: ./coverage.xml
|
| 101 |
-
flags: backend
|
| 102 |
-
name: backend-coverage
|
| 103 |
-
|
| 104 |
-
# ==========================================
|
| 105 |
-
# JOB 3: Frontend Testing (Vue.js)
|
| 106 |
-
# ==========================================
|
| 107 |
-
frontend-tests:
|
| 108 |
-
name: Frontend Tests (Vue.js)
|
| 109 |
-
runs-on: ubuntu-latest
|
| 110 |
-
needs: security-scan
|
| 111 |
-
|
| 112 |
-
steps:
|
| 113 |
-
- name: Checkout code
|
| 114 |
-
uses: actions/checkout@v4
|
| 115 |
-
|
| 116 |
-
- name: Set up Node.js 20
|
| 117 |
-
uses: actions/setup-node@v4
|
| 118 |
-
with:
|
| 119 |
-
node-version: '20'
|
| 120 |
-
cache: 'npm'
|
| 121 |
-
cache-dependency-path: frontend/package-lock.json
|
| 122 |
-
|
| 123 |
-
- name: Install dependencies
|
| 124 |
-
working-directory: ./frontend
|
| 125 |
-
run: npm ci
|
| 126 |
-
|
| 127 |
-
- name: Run ESLint
|
| 128 |
-
working-directory: ./frontend
|
| 129 |
-
run: npm run lint || true
|
| 130 |
-
|
| 131 |
-
- name: Run Frontend Tests
|
| 132 |
-
working-directory: ./frontend
|
| 133 |
-
run: npm run test:unit || echo "No tests configured yet"
|
| 134 |
-
|
| 135 |
-
- name: Build Frontend
|
| 136 |
-
working-directory: ./frontend
|
| 137 |
-
run: npm run build
|
| 138 |
-
|
| 139 |
-
# ==========================================
|
| 140 |
-
# JOB 4: Build Docker Images
|
| 141 |
-
# ==========================================
|
| 142 |
-
build-docker-images:
|
| 143 |
-
name: Build Docker Images
|
| 144 |
-
runs-on: ubuntu-latest
|
| 145 |
-
needs: [backend-tests, frontend-tests]
|
| 146 |
-
permissions:
|
| 147 |
-
contents: read
|
| 148 |
-
packages: write
|
| 149 |
-
|
| 150 |
-
steps:
|
| 151 |
-
- name: Checkout code
|
| 152 |
-
uses: actions/checkout@v4
|
| 153 |
-
|
| 154 |
-
- name: Set up Docker Buildx
|
| 155 |
-
uses: docker/setup-buildx-action@v3
|
| 156 |
-
|
| 157 |
-
- name: Log in to GitHub Container Registry
|
| 158 |
-
uses: docker/login-action@v3
|
| 159 |
-
with:
|
| 160 |
-
registry: ${{ env.REGISTRY }}
|
| 161 |
-
username: ${{ github.actor }}
|
| 162 |
-
password: ${{ secrets.GITHUB_TOKEN }}
|
| 163 |
-
|
| 164 |
-
- name: Extract metadata (tags, labels) for Backend
|
| 165 |
-
id: meta-backend
|
| 166 |
-
uses: docker/metadata-action@v5
|
| 167 |
-
with:
|
| 168 |
-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}
|
| 169 |
-
tags: |
|
| 170 |
-
type=ref,event=branch
|
| 171 |
-
type=ref,event=pr
|
| 172 |
-
type=semver,pattern={{version}}
|
| 173 |
-
type=semver,pattern={{major}}.{{minor}}
|
| 174 |
-
type=sha,prefix={{branch}}-
|
| 175 |
-
|
| 176 |
-
- name: Extract metadata (tags, labels) for Frontend
|
| 177 |
-
id: meta-frontend
|
| 178 |
-
uses: docker/metadata-action@v5
|
| 179 |
-
with:
|
| 180 |
-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}
|
| 181 |
-
tags: |
|
| 182 |
-
type=ref,event=branch
|
| 183 |
-
type=ref,event=pr
|
| 184 |
-
type=semver,pattern={{version}}
|
| 185 |
-
type=semver,pattern={{major}}.{{minor}}
|
| 186 |
-
type=sha,prefix={{branch}}-
|
| 187 |
-
|
| 188 |
-
- name: Build and push Backend Docker image
|
| 189 |
-
uses: docker/build-push-action@v5
|
| 190 |
-
with:
|
| 191 |
-
context: ./backend
|
| 192 |
-
file: ./backend/Dockerfile
|
| 193 |
-
push: ${{ github.event_name != 'pull_request' }}
|
| 194 |
-
tags: ${{ steps.meta-backend.outputs.tags }}
|
| 195 |
-
labels: ${{ steps.meta-backend.outputs.labels }}
|
| 196 |
-
cache-from: type=gha
|
| 197 |
-
cache-to: type=gha,mode=max
|
| 198 |
-
|
| 199 |
-
- name: Build and push Frontend Docker image
|
| 200 |
-
uses: docker/build-push-action@v5
|
| 201 |
-
with:
|
| 202 |
-
context: ./frontend
|
| 203 |
-
file: ./frontend/Dockerfile
|
| 204 |
-
push: ${{ github.event_name != 'pull_request' }}
|
| 205 |
-
tags: ${{ steps.meta-frontend.outputs.tags }}
|
| 206 |
-
labels: ${{ steps.meta-frontend.outputs.labels }}
|
| 207 |
-
cache-from: type=gha
|
| 208 |
-
cache-to: type=gha,mode=max
|
| 209 |
-
|
| 210 |
-
# ==========================================
|
| 211 |
-
# JOB 5: Create Deployment Package
|
| 212 |
-
# ==========================================
|
| 213 |
-
create-deployment-package:
|
| 214 |
-
name: Create Local Deployment Package
|
| 215 |
-
runs-on: ubuntu-latest
|
| 216 |
-
needs: build-docker-images
|
| 217 |
-
if: github.event_name == 'release'
|
| 218 |
-
|
| 219 |
-
steps:
|
| 220 |
-
- name: Checkout code
|
| 221 |
-
uses: actions/checkout@v4
|
| 222 |
-
|
| 223 |
-
- name: Create deployment package
|
| 224 |
-
run: |
|
| 225 |
-
mkdir -p deployment-package
|
| 226 |
-
cp docker-compose.yml deployment-package/
|
| 227 |
-
cp docker-compose.prod.yml deployment-package/
|
| 228 |
-
cp .env.example deployment-package/.env
|
| 229 |
-
cp README.md deployment-package/
|
| 230 |
-
cp QUICKSTART.md deployment-package/
|
| 231 |
-
|
| 232 |
-
# Create deployment instructions
|
| 233 |
-
cat > deployment-package/DEPLOYMENT.md << 'EOF'
|
| 234 |
-
# SAAP Lokales Deployment
|
| 235 |
-
|
| 236 |
-
## Voraussetzungen
|
| 237 |
-
- Docker 24.0 oder höher
|
| 238 |
-
- Docker Compose 2.20 oder höher
|
| 239 |
-
- 4 GB RAM minimum
|
| 240 |
-
- 10 GB Festplattenspeicher
|
| 241 |
-
|
| 242 |
-
## Schnellstart
|
| 243 |
-
|
| 244 |
-
1. **Konfiguration anpassen:**
|
| 245 |
-
```bash
|
| 246 |
-
cp .env.example .env
|
| 247 |
-
# .env-Datei editieren und API-Keys eintragen
|
| 248 |
-
```
|
| 249 |
-
|
| 250 |
-
2. **SAAP starten:**
|
| 251 |
-
```bash
|
| 252 |
-
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
| 253 |
-
```
|
| 254 |
-
|
| 255 |
-
3. **Status überprüfen:**
|
| 256 |
-
```bash
|
| 257 |
-
docker-compose ps
|
| 258 |
-
```
|
| 259 |
-
|
| 260 |
-
4. **Anwendung öffnen:**
|
| 261 |
-
- Frontend: http://localhost:5173
|
| 262 |
-
- Backend API: http://localhost:8000
|
| 263 |
-
- API Docs: http://localhost:8000/docs
|
| 264 |
-
|
| 265 |
-
## Verwaltung
|
| 266 |
-
|
| 267 |
-
- **Logs anzeigen:** `docker-compose logs -f`
|
| 268 |
-
- **Neustart:** `docker-compose restart`
|
| 269 |
-
- **Stoppen:** `docker-compose down`
|
| 270 |
-
- **Updates:** `docker-compose pull && docker-compose up -d`
|
| 271 |
-
|
| 272 |
-
## Kostenvergleich: Lokal vs. Cloud
|
| 273 |
-
|
| 274 |
-
| Kriterium | Lokal (SAAP) | AWS/Azure Cloud |
|
| 275 |
-
|-----------|--------------|-----------------|
|
| 276 |
-
| Monatliche Kosten | €0 (nur Stromkosten) | €200-500+ |
|
| 277 |
-
| Datenschutz | Vollständig lokal | Externen Servern |
|
| 278 |
-
| Latenz | <10ms | 50-200ms |
|
| 279 |
-
| Skalierung | Manuell | Automatisch |
|
| 280 |
-
| Wartung | Selbst | Managed |
|
| 281 |
-
|
| 282 |
-
## Support
|
| 283 |
-
Bei Fragen: https://github.com/satwareAG/saap/issues
|
| 284 |
-
EOF
|
| 285 |
-
|
| 286 |
-
- name: Create archive
|
| 287 |
-
run: |
|
| 288 |
-
cd deployment-package
|
| 289 |
-
tar -czf ../saap-deployment-${{ github.ref_name }}.tar.gz .
|
| 290 |
-
|
| 291 |
-
- name: Upload deployment package
|
| 292 |
-
uses: actions/upload-artifact@v4
|
| 293 |
-
with:
|
| 294 |
-
name: saap-deployment-package
|
| 295 |
-
path: saap-deployment-${{ github.ref_name }}.tar.gz
|
| 296 |
-
|
| 297 |
-
- name: Upload to Release
|
| 298 |
-
uses: softprops/action-gh-release@v1
|
| 299 |
-
if: github.event_name == 'release'
|
| 300 |
-
with:
|
| 301 |
-
files: saap-deployment-${{ github.ref_name }}.tar.gz
|
| 302 |
-
env:
|
| 303 |
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
| 304 |
-
|
| 305 |
-
# ==========================================
|
| 306 |
-
# JOB 6: Deploy to HuggingFace Spaces
|
| 307 |
-
# ==========================================
|
| 308 |
-
deploy-huggingface:
|
| 309 |
-
name: Deploy to HuggingFace Spaces
|
| 310 |
-
runs-on: ubuntu-latest
|
| 311 |
-
needs: [backend-tests, frontend-tests]
|
| 312 |
-
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
| 313 |
-
|
| 314 |
-
steps:
|
| 315 |
-
- name: Checkout code
|
| 316 |
-
uses: actions/checkout@v4
|
| 317 |
-
with:
|
| 318 |
-
fetch-depth: 0
|
| 319 |
-
|
| 320 |
-
- name: Setup Python
|
| 321 |
-
uses: actions/setup-python@v5
|
| 322 |
-
with:
|
| 323 |
-
python-version: '3.11'
|
| 324 |
-
|
| 325 |
-
- name: Install HuggingFace Hub
|
| 326 |
-
run: pip install huggingface_hub
|
| 327 |
-
|
| 328 |
-
- name: Debug - Check HF_TOKEN
|
| 329 |
-
run: |
|
| 330 |
-
if [ -z "${{ secrets.HF_TOKEN }}" ]; then
|
| 331 |
-
echo "❌ ERROR: HF_TOKEN secret not configured"
|
| 332 |
-
echo "Please add HF_TOKEN to repository secrets"
|
| 333 |
-
exit 1
|
| 334 |
-
else
|
| 335 |
-
echo "✅ HF_TOKEN is configured"
|
| 336 |
-
echo "Token length: ${#HF_TOKEN}"
|
| 337 |
-
fi
|
| 338 |
-
env:
|
| 339 |
-
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 340 |
-
|
| 341 |
-
- name: Prepare deployment files
|
| 342 |
-
run: |
|
| 343 |
-
echo "📦 Preparing HuggingFace deployment files..."
|
| 344 |
-
|
| 345 |
-
# Create huggingface deployment directory
|
| 346 |
-
mkdir -p huggingface_deploy
|
| 347 |
-
|
| 348 |
-
# Copy all necessary files
|
| 349 |
-
cp -r huggingface/* huggingface_deploy/
|
| 350 |
-
cp -r backend huggingface_deploy/
|
| 351 |
-
cp -r frontend huggingface_deploy/
|
| 352 |
-
cp requirements.txt huggingface_deploy/
|
| 353 |
-
|
| 354 |
-
# Verify critical files exist
|
| 355 |
-
echo "📋 Verifying deployment files:"
|
| 356 |
-
ls -la huggingface_deploy/
|
| 357 |
-
|
| 358 |
-
if [ ! -f "huggingface_deploy/Dockerfile" ]; then
|
| 359 |
-
echo "❌ ERROR: Dockerfile missing"
|
| 360 |
-
exit 1
|
| 361 |
-
fi
|
| 362 |
-
|
| 363 |
-
if [ ! -f "huggingface_deploy/README.md" ]; then
|
| 364 |
-
echo "⚠️ WARNING: README.md missing - creating default"
|
| 365 |
-
cat > huggingface_deploy/README.md << 'EOF'
|
| 366 |
-
---
|
| 367 |
-
title: SAAP - satware AI Autonomous Agent Platform
|
| 368 |
-
emoji: 🤖
|
| 369 |
-
colorFrom: purple
|
| 370 |
-
colorTo: blue
|
| 371 |
-
sdk: docker
|
| 372 |
-
app_port: 7860
|
| 373 |
-
pinned: false
|
| 374 |
-
license: mit
|
| 375 |
-
---
|
| 376 |
-
|
| 377 |
-
# SAAP - satware® AI Autonomous Agent Platform
|
| 378 |
-
|
| 379 |
-
Local autonomous multi-agent system for specialized AI agents.
|
| 380 |
-
|
| 381 |
-
**Features:**
|
| 382 |
-
- Multi-agent coordination (Jane, John, Lara, Theo, Justus, Leon, Luna)
|
| 383 |
-
- Real-time WebSocket communication
|
| 384 |
-
- Cost-efficient hybrid provider support
|
| 385 |
-
- Privacy-first local deployment
|
| 386 |
-
EOF
|
| 387 |
-
fi
|
| 388 |
-
|
| 389 |
-
echo "✅ Deployment files prepared"
|
| 390 |
-
|
| 391 |
-
- name: Upload to HuggingFace Space
|
| 392 |
-
env:
|
| 393 |
-
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 394 |
-
run: |
|
| 395 |
-
echo "🚀 Deploying to HuggingFace Spaces..."
|
| 396 |
-
|
| 397 |
-
cd huggingface_deploy
|
| 398 |
-
|
| 399 |
-
python << 'DEPLOY_SCRIPT'
|
| 400 |
-
import os
|
| 401 |
-
import sys
|
| 402 |
-
from huggingface_hub import HfApi, create_repo
|
| 403 |
-
|
| 404 |
-
# Configuration
|
| 405 |
-
repo_id = "Hwandji/saap"
|
| 406 |
-
token = os.environ.get("HF_TOKEN")
|
| 407 |
-
|
| 408 |
-
if not token:
|
| 409 |
-
print("❌ HF_TOKEN not found")
|
| 410 |
-
sys.exit(1)
|
| 411 |
-
|
| 412 |
-
print(f"📤 Uploading to HuggingFace Space: {repo_id}")
|
| 413 |
-
|
| 414 |
-
try:
|
| 415 |
-
api = HfApi(token=token)
|
| 416 |
-
|
| 417 |
-
# Upload all files
|
| 418 |
-
api.upload_folder(
|
| 419 |
-
folder_path=".",
|
| 420 |
-
repo_id=repo_id,
|
| 421 |
-
repo_type="space",
|
| 422 |
-
commit_message=f"Deploy from GitHub Actions - {os.environ.get('GITHUB_SHA', 'unknown')[:7]}"
|
| 423 |
-
)
|
| 424 |
-
|
| 425 |
-
print("✅ Successfully uploaded to HuggingFace")
|
| 426 |
-
print(f"🌐 Space URL: https://huggingface.co/spaces/{repo_id}")
|
| 427 |
-
|
| 428 |
-
except Exception as e:
|
| 429 |
-
print(f"❌ Deployment failed: {e}")
|
| 430 |
-
sys.exit(1)
|
| 431 |
-
DEPLOY_SCRIPT
|
| 432 |
-
|
| 433 |
-
- name: Deployment summary
|
| 434 |
-
run: |
|
| 435 |
-
echo "📊 Deployment Summary"
|
| 436 |
-
echo "===================="
|
| 437 |
-
echo "✅ Files uploaded to HuggingFace Spaces"
|
| 438 |
-
echo "🌐 Space: https://huggingface.co/spaces/Hwandji/saap"
|
| 439 |
-
echo "⏳ Note: Space restart may take 2-3 minutes"
|
| 440 |
-
echo "🔍 Check logs at: https://huggingface.co/spaces/Hwandji/saap/logs"
|
| 441 |
-
|
| 442 |
-
# ==========================================
|
| 443 |
-
# JOB 7: Deployment Success Notification
|
| 444 |
-
# ==========================================
|
| 445 |
-
notify-deployment:
|
| 446 |
-
name: Deployment Status
|
| 447 |
-
runs-on: ubuntu-latest
|
| 448 |
-
needs: [build-docker-images, create-deployment-package, deploy-huggingface]
|
| 449 |
-
if: always()
|
| 450 |
-
|
| 451 |
-
steps:
|
| 452 |
-
- name: Check deployment status
|
| 453 |
-
run: |
|
| 454 |
-
if [ "${{ needs.build-docker-images.result }}" = "success" ]; then
|
| 455 |
-
echo "✅ Docker Images erfolgreich gebaut"
|
| 456 |
-
echo "📦 Images verfügbar in GitHub Container Registry"
|
| 457 |
-
echo "🚀 Deployment-Package bereit für lokale Installation"
|
| 458 |
-
else
|
| 459 |
-
echo "❌ Deployment fehlgeschlagen"
|
| 460 |
-
exit 1
|
| 461 |
-
fi
|
| 462 |
-
|
| 463 |
-
if [ "${{ needs.deploy-huggingface.result }}" = "success" ]; then
|
| 464 |
-
echo "✅ HuggingFace Deployment erfolgreich"
|
| 465 |
-
echo "🌐 Space: https://huggingface.co/spaces/Hwandji/saap"
|
| 466 |
-
elif [ "${{ needs.deploy-huggingface.result }}" = "skipped" ]; then
|
| 467 |
-
echo "⏭️ HuggingFace Deployment übersprungen (nicht main branch)"
|
| 468 |
-
else
|
| 469 |
-
echo "❌ HuggingFace Deployment fehlgeschlagen"
|
| 470 |
-
fi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.github/workflows/deploy-huggingface.yml
DELETED
|
@@ -1,151 +0,0 @@
|
|
| 1 |
-
name: Deploy to HuggingFace Spaces
|
| 2 |
-
|
| 3 |
-
on:
|
| 4 |
-
push:
|
| 5 |
-
branches:
|
| 6 |
-
- main
|
| 7 |
-
workflow_dispatch:
|
| 8 |
-
inputs:
|
| 9 |
-
reason:
|
| 10 |
-
description: 'Deployment reason'
|
| 11 |
-
required: false
|
| 12 |
-
default: 'Manual deployment'
|
| 13 |
-
|
| 14 |
-
jobs:
|
| 15 |
-
deploy:
|
| 16 |
-
runs-on: ubuntu-latest
|
| 17 |
-
|
| 18 |
-
steps:
|
| 19 |
-
- name: Checkout repository
|
| 20 |
-
uses: actions/checkout@v4
|
| 21 |
-
with:
|
| 22 |
-
lfs: true
|
| 23 |
-
fetch-depth: 0
|
| 24 |
-
|
| 25 |
-
- name: Setup Python
|
| 26 |
-
uses: actions/setup-python@v5
|
| 27 |
-
with:
|
| 28 |
-
python-version: '3.10'
|
| 29 |
-
|
| 30 |
-
- name: Install HuggingFace Hub
|
| 31 |
-
run: |
|
| 32 |
-
pip install --upgrade huggingface_hub[cli]
|
| 33 |
-
echo "✅ HuggingFace Hub installed"
|
| 34 |
-
|
| 35 |
-
- name: Debug - Check HF_TOKEN
|
| 36 |
-
env:
|
| 37 |
-
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 38 |
-
run: |
|
| 39 |
-
# Check if token is set (without revealing it)
|
| 40 |
-
if [ -z "$HF_TOKEN" ]; then
|
| 41 |
-
echo "❌ ERROR: HF_TOKEN is not set!"
|
| 42 |
-
exit 1
|
| 43 |
-
else
|
| 44 |
-
echo "✅ HF_TOKEN is set (length: ${#HF_TOKEN} chars)"
|
| 45 |
-
fi
|
| 46 |
-
|
| 47 |
-
- name: Prepare deployment files
|
| 48 |
-
run: |
|
| 49 |
-
echo "Preparing files for HuggingFace Spaces deployment..."
|
| 50 |
-
|
| 51 |
-
# Create temporary deployment directory
|
| 52 |
-
mkdir -p hf-deploy
|
| 53 |
-
|
| 54 |
-
# Copy all necessary files
|
| 55 |
-
cp -r backend/ hf-deploy/
|
| 56 |
-
cp -r frontend/ hf-deploy/
|
| 57 |
-
cp requirements.txt hf-deploy/
|
| 58 |
-
cp huggingface/Dockerfile hf-deploy/Dockerfile
|
| 59 |
-
cp huggingface/README.md hf-deploy/README.md
|
| 60 |
-
cp huggingface/nginx.conf hf-deploy/
|
| 61 |
-
cp huggingface/supervisord.conf hf-deploy/
|
| 62 |
-
|
| 63 |
-
# Copy .dockerignore if it exists
|
| 64 |
-
if [ -f "huggingface/.dockerignore" ]; then
|
| 65 |
-
cp huggingface/.dockerignore hf-deploy/.dockerignore
|
| 66 |
-
echo "✅ .dockerignore copied"
|
| 67 |
-
fi
|
| 68 |
-
|
| 69 |
-
echo "✅ Files prepared in hf-deploy/"
|
| 70 |
-
|
| 71 |
-
- name: Upload to HuggingFace Space
|
| 72 |
-
env:
|
| 73 |
-
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 74 |
-
run: |
|
| 75 |
-
echo "Uploading to HuggingFace Space: Hwandji/saap"
|
| 76 |
-
|
| 77 |
-
# Create Python script for upload
|
| 78 |
-
cat > upload_to_hf.py << 'EOF'
|
| 79 |
-
import os
|
| 80 |
-
from pathlib import Path
|
| 81 |
-
from huggingface_hub import HfApi, login, create_repo
|
| 82 |
-
|
| 83 |
-
# Login with token
|
| 84 |
-
token = os.environ.get('HF_TOKEN')
|
| 85 |
-
if not token:
|
| 86 |
-
raise ValueError("HF_TOKEN not found in environment")
|
| 87 |
-
|
| 88 |
-
login(token=token)
|
| 89 |
-
print("✅ Successfully logged in to HuggingFace")
|
| 90 |
-
|
| 91 |
-
# Initialize API
|
| 92 |
-
api = HfApi()
|
| 93 |
-
|
| 94 |
-
# Create or get Space repository
|
| 95 |
-
repo_id = "Hwandji/saap"
|
| 96 |
-
print(f"Creating or accessing Space: {repo_id}...")
|
| 97 |
-
|
| 98 |
-
try:
|
| 99 |
-
# Try to create the Space (will succeed if doesn't exist, harmless if exists)
|
| 100 |
-
create_repo(
|
| 101 |
-
repo_id=repo_id,
|
| 102 |
-
repo_type="space",
|
| 103 |
-
space_sdk="docker",
|
| 104 |
-
exist_ok=True, # Don't error if already exists
|
| 105 |
-
private=False
|
| 106 |
-
)
|
| 107 |
-
print(f"✅ Space {repo_id} is ready")
|
| 108 |
-
except Exception as e:
|
| 109 |
-
print(f"⚠️ Note: {e}")
|
| 110 |
-
print("Continuing with upload...")
|
| 111 |
-
|
| 112 |
-
# Upload directory
|
| 113 |
-
print(f"Uploading files to {repo_id}...")
|
| 114 |
-
api.upload_folder(
|
| 115 |
-
folder_path="./hf-deploy",
|
| 116 |
-
repo_id=repo_id,
|
| 117 |
-
repo_type="space",
|
| 118 |
-
commit_message="🚀 Deploy from GitHub Actions",
|
| 119 |
-
ignore_patterns=[".git", ".github", "__pycache__", "*.pyc"]
|
| 120 |
-
)
|
| 121 |
-
|
| 122 |
-
print("✅ Successfully deployed to HuggingFace Spaces")
|
| 123 |
-
print(f"🌐 Space URL: https://huggingface.co/spaces/{repo_id}")
|
| 124 |
-
print(f"🌐 App URL: https://{repo_id.replace('/', '-')}.hf.space")
|
| 125 |
-
EOF
|
| 126 |
-
|
| 127 |
-
# Run the upload script
|
| 128 |
-
python upload_to_hf.py
|
| 129 |
-
|
| 130 |
-
- name: Deployment summary
|
| 131 |
-
if: success()
|
| 132 |
-
run: |
|
| 133 |
-
echo "## 🎉 Deployment Successful!" >> $GITHUB_STEP_SUMMARY
|
| 134 |
-
echo "" >> $GITHUB_STEP_SUMMARY
|
| 135 |
-
echo "**Space URL:** https://huggingface.co/spaces/Hwandji/saap" >> $GITHUB_STEP_SUMMARY
|
| 136 |
-
echo "**App URL:** https://Hwandji-saap.hf.space" >> $GITHUB_STEP_SUMMARY
|
| 137 |
-
echo "" >> $GITHUB_STEP_SUMMARY
|
| 138 |
-
echo "⏱️ The space may take 2-3 minutes to build and start." >> $GITHUB_STEP_SUMMARY
|
| 139 |
-
|
| 140 |
-
- name: Notify on failure
|
| 141 |
-
if: failure()
|
| 142 |
-
run: |
|
| 143 |
-
echo "## ❌ Deployment Failed!" >> $GITHUB_STEP_SUMMARY
|
| 144 |
-
echo "" >> $GITHUB_STEP_SUMMARY
|
| 145 |
-
echo "Please check the logs above for error details." >> $GITHUB_STEP_SUMMARY
|
| 146 |
-
echo "" >> $GITHUB_STEP_SUMMARY
|
| 147 |
-
echo "**Common issues:**" >> $GITHUB_STEP_SUMMARY
|
| 148 |
-
echo "- HF_TOKEN not configured in repository secrets" >> $GITHUB_STEP_SUMMARY
|
| 149 |
-
echo "- Token lacks WRITE permissions for Spaces" >> $GITHUB_STEP_SUMMARY
|
| 150 |
-
echo "- Token creator is not a member of 'satware' organization" >> $GITHUB_STEP_SUMMARY
|
| 151 |
-
echo "- Space 'Hwandji/saap' does not exist or is not accessible" >> $GITHUB_STEP_SUMMARY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|