#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" LOCAL_TOKENS_FILE="${LOCAL_TOKENS_FILE:-$SCRIPT_DIR/local_tokens.sh}" if [[ -f "$LOCAL_TOKENS_FILE" ]]; then # shellcheck disable=SC1090 source "$LOCAL_TOKENS_FILE" fi REMOTE="${REMOTE:-hf}" BRANCH="${BRANCH:-main}" SKIP_VALIDATE=0 usage() { cat <<'EOF' Uso: ./scripts/publish_hf.sh [opcoes] O script: 1. troca para a branch main 2. valida backend e frontend 3. faz push para o Space do Hugging Face Opcoes: --branch NAME Branch a publicar (padrao: main) --remote NAME Remote do Hugging Face (padrao: hf) --skip-validate Pula compileall e build do frontend --help Mostra esta ajuda Autenticacao: - Se existir scripts/local_tokens.sh, ele sera carregado automaticamente. - Se HF_TOKEN estiver definido, o push usa URL autenticada temporaria. - Caso contrario, usa o remote local ja configurado. EOF } log() { printf '[publish-hf] %s\n' "$*" } fail() { printf '[publish-hf] erro: %s\n' "$*" >&2 exit 1 } require_cmd() { command -v "$1" >/dev/null 2>&1 || fail "comando obrigatorio ausente: $1" } ensure_clean_tracked_tree() { git diff --quiet || fail "ha alteracoes rastreadas nao commitadas; limpe a arvore antes do publish" git diff --cached --quiet || fail "ha alteracoes staged; finalize o commit antes do publish" } authenticated_hf_url() { local remote_url="$1" local token="${HF_TOKEN:-}" [[ -n "$token" ]] || { printf '%s\n' "$remote_url" return 0 } case "$remote_url" in https://huggingface.co/*) ;; *) printf '%s\n' "$remote_url" return 0 ;; esac local path="${remote_url#https://huggingface.co/}" local owner owner="$(python3 - "$path" <<'PY' import sys parts = [chunk for chunk in sys.argv[1].split("/") if chunk] if len(parts) >= 2 and parts[0] in {"spaces", "datasets", "models"}: print(parts[1]) elif parts: print(parts[0]) PY )" [[ -n "$owner" ]] || fail "nao consegui identificar o owner do remote do HF" printf 'https://%s:%s@huggingface.co/%s\n' "$owner" "$token" "$path" } while [[ $# -gt 0 ]]; do case "$1" in --branch) [[ $# -ge 2 ]] || fail "faltou valor para --branch" BRANCH="$2" shift 2 ;; --remote) [[ $# -ge 2 ]] || fail "faltou valor para --remote" REMOTE="$2" shift 2 ;; --skip-validate) SKIP_VALIDATE=1 shift ;; --help|-h) usage exit 0 ;; *) fail "opcao desconhecida: $1" ;; esac done require_cmd git require_cmd python3 git show-ref --verify --quiet "refs/heads/$BRANCH" || fail "branch local inexistente: $BRANCH" git remote get-url "$REMOTE" >/dev/null 2>&1 || fail "remote inexistente: $REMOTE" ensure_clean_tracked_tree git checkout "$BRANCH" >/dev/null if (( SKIP_VALIDATE == 0 )); then log "validando backend" python3 -m compileall backend/app >/dev/null log "buildando frontend" (cd frontend && npm run build >/dev/null) fi remote_url="$(git remote get-url "$REMOTE")" push_url="$(authenticated_hf_url "$remote_url")" log "publicando $BRANCH no remote $REMOTE" git push "$push_url" "$BRANCH:$BRANCH" log "concluido"