name: Sync to Hugging Face hub on: push: branches: [deployment] workflow_dispatch: jobs: sync-to-hub: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 lfs: true - name: Validate Hugging Face token id: hf_auth env: HF_TOKEN: ${{ secrets.HF_TOKEN }} run: | if [ -z "$HF_TOKEN" ]; then echo "::error::GitHub secret HF_TOKEN is not set." echo "Create a Hugging Face token with WRITE access to SolutionChallenge/solution_challenge_backend," echo "then add it at GitHub → Settings → Secrets and variables → Actions → HF_TOKEN." exit 1 fi pip install -q "huggingface_hub>=0.23.0" python <<'PY' import os, sys from huggingface_hub import HfApi token = os.environ["HF_TOKEN"] api = HfApi(token=token) try: who = api.whoami(cache=True) except Exception as exc: print(f"::error::HF_TOKEN is invalid or expired: {exc}", file=sys.stderr) sys.exit(1) username = who.get("name") or who.get("fullname") or "" if not username: print("::error::Could not resolve Hugging Face username from token.", file=sys.stderr) sys.exit(1) print(f"Authenticated as Hugging Face user: {username}") space_id = "SolutionChallenge/solution_challenge_backend" try: info = api.space_info(space_id, token=token) print(f"Space found: {info.id}") except Exception as exc: print( f"::error::Token for '{username}' cannot access {space_id}. " "Accept the Solution Challenge org invite, then use a WRITE token from a member with push access.", file=sys.stderr, ) print(f"Hub response: {exc}", file=sys.stderr) sys.exit(1) github_output = os.environ.get("GITHUB_OUTPUT", "") if github_output: with open(github_output, "a", encoding="utf-8") as out: out.write(f"username={username}\n") PY - name: Push to hub env: HF_TOKEN: ${{ secrets.HF_TOKEN }} HF_USER: ${{ steps.hf_auth.outputs.username }} HF_SPACE: SolutionChallenge/solution_challenge_backend run: | git config --global user.name "github-actions" git config --global user.email "github-actions@github.com" git checkout --orphan hf-deploy rm -rf cepheus guest-app scripts firebase.json # HF Picklescan blocks .npy — ensure pickle-free .f32emb, then strip .npy python3 backend/Face_Recognition/export_hf_embeddings.py || true find backend/Face_Recognition -name '*.npy' -delete # HF git rejects binary images via regular push — ship .f32emb only find backend/Face_Recognition -name '*.jpg' -delete find backend/Face_Recognition -name '*.jpeg' -delete find backend/Face_Recognition -name '*.png' -delete find backend/Face_Recognition -name '*.webp' -delete find backend/Face_Recognition/face_database -type d -name 'unknown_*' -exec rm -rf {} + 2>/dev/null || true mkdir -p backend/Face_Recognition/faces_db backend/Face_Recognition/temp_faces_db backend/Face_Recognition/face_database touch backend/Face_Recognition/face_database/.gitkeep find backend -name "*.pt" -delete find backend -name "*.mp4" -delete # Drop other large/binary artifacts not needed on the Space rm -f backend/Face_Recognition/test.jpg backend/Face_Recognition/input.mp4 2>/dev/null || true git add -A git commit -m "Deploy to Hugging Face" ENCODED_TOKEN=$(python3 -c "import os, urllib.parse; print(urllib.parse.quote(os.environ['HF_TOKEN'], safe=''))") git push --force "https://SolutionChallenge:${ENCODED_TOKEN}@huggingface.co/spaces/SolutionChallenge/solution_challenge_backend" hf-deploy:main