#!/bin/bash # Publish WiFi-DensePose pre-trained models to HuggingFace Hub # # Retrieves the HuggingFace API token from Google Cloud Secrets, # then uploads model files from dist/models/ to a HuggingFace repo. # # Prerequisites: # - gcloud CLI authenticated with access to cognitum-20260110 # - Python 3.8+ with pip # - Model files present in dist/models/ # # Usage: # bash scripts/publish-huggingface.sh # bash scripts/publish-huggingface.sh --repo ruvnet/wifi-densepose-pretrained --version v0.5.4 # bash scripts/publish-huggingface.sh --dry-run set -euo pipefail # ---------- defaults ---------- REPO="ruvnet/wifi-densepose-pretrained" VERSION="" GCLOUD_PROJECT="cognitum-20260110" SECRET_NAME="HUGGINGFACE_API_KEY" MODEL_DIR="dist/models" DRY_RUN=false # ---------- parse args ---------- while [[ $# -gt 0 ]]; do case "$1" in --repo) REPO="$2"; shift 2 ;; --version) VERSION="$2"; shift 2 ;; --model-dir) MODEL_DIR="$2"; shift 2 ;; --project) GCLOUD_PROJECT="$2"; shift 2 ;; --secret) SECRET_NAME="$2"; shift 2 ;; --dry-run) DRY_RUN=true; shift ;; -h|--help) echo "Usage: bash scripts/publish-huggingface.sh [OPTIONS]" echo "" echo "Options:" echo " --repo REPO HuggingFace repo (default: ruvnet/wifi-densepose-pretrained)" echo " --version VERSION Version tag (default: auto from git describe)" echo " --model-dir DIR Model directory (default: dist/models)" echo " --project PROJECT GCloud project (default: cognitum-20260110)" echo " --secret SECRET GCloud secret name (default: HUGGINGFACE_API_KEY)" echo " --dry-run Show what would be uploaded without uploading" echo " -h, --help Show this help" exit 0 ;; *) echo "Unknown option: $1"; exit 1 ;; esac done # ---------- auto-detect version ---------- if [ -z "$VERSION" ]; then VERSION=$(git describe --tags --always 2>/dev/null || echo "dev") echo "Auto-detected version: ${VERSION}" fi # ---------- validate model files ---------- EXPECTED_FILES=( "pretrained-encoder.onnx" "pretrained-heads.onnx" "pretrained.rvf" "room-profiles.json" "collection-witness.json" "config.json" "README.md" ) echo "=== WiFi-DensePose HuggingFace Publisher ===" echo "Repo: ${REPO}" echo "Version: ${VERSION}" echo "Model dir: ${MODEL_DIR}" echo "" MISSING=0 for f in "${EXPECTED_FILES[@]}"; do if [ -f "${MODEL_DIR}/${f}" ]; then SIZE=$(stat --printf="%s" "${MODEL_DIR}/${f}" 2>/dev/null || stat -f "%z" "${MODEL_DIR}/${f}" 2>/dev/null || echo "?") echo " [OK] ${f} (${SIZE} bytes)" else echo " [MISSING] ${f}" MISSING=$((MISSING + 1)) fi done if [ "$MISSING" -gt 0 ]; then echo "" echo "WARNING: ${MISSING} expected file(s) missing from ${MODEL_DIR}/" echo "The upload will proceed with available files only." echo "" fi # Count actual files to upload FILE_COUNT=$(find "${MODEL_DIR}" -maxdepth 1 -type f | wc -l) if [ "$FILE_COUNT" -eq 0 ]; then echo "ERROR: No files found in ${MODEL_DIR}/. Nothing to upload." exit 1 fi # ---------- dry run ---------- if [ "$DRY_RUN" = true ]; then echo "" echo "[DRY RUN] Would upload ${FILE_COUNT} files to https://huggingface.co/${REPO}" echo "[DRY RUN] Files:" find "${MODEL_DIR}" -maxdepth 1 -type f -exec basename {} \; | sort | while read -r fname; do echo " - ${fname}" done echo "[DRY RUN] Version tag: ${VERSION}" echo "" echo "Run without --dry-run to actually upload." exit 0 fi # ---------- retrieve HuggingFace token ---------- echo "" echo "Retrieving HuggingFace token from GCloud Secrets..." HF_TOKEN=$(gcloud secrets versions access latest \ --secret="${SECRET_NAME}" \ --project="${GCLOUD_PROJECT}" 2>/dev/null) if [ -z "$HF_TOKEN" ]; then echo "ERROR: Failed to retrieve secret '${SECRET_NAME}' from project '${GCLOUD_PROJECT}'." echo "Make sure you are authenticated: gcloud auth login" echo "And have access to the secret: gcloud secrets list --project=${GCLOUD_PROJECT}" exit 1 fi echo "Token retrieved successfully." # ---------- install huggingface_hub if needed ---------- if ! python3 -c "import huggingface_hub" 2>/dev/null; then echo "Installing huggingface_hub..." pip3 install --quiet huggingface_hub fi # ---------- upload via Python ---------- echo "" echo "Uploading to https://huggingface.co/${REPO} ..." python3 - <