#!/usr/bin/env bash # ============================================================ # OpenClaw HF Space 强制推送脚本 # # 用法: # ./push-to-space.sh [HF_TOKEN] # # 示例: # ./push-to-space.sh GGSheng/page hf_xxxxx # # 方式1:直接提供参数 # ./scripts/push-to-space.sh GGSheng/page hf_xxxxx # # 方式2:设置环境变量 # export SPACE_REPO_ID="GGSheng/page" # export HF_TOKEN="hf_xxxxx" # ./scripts/push-to-space.sh # # 方式3:使用缓存的 token(默认从 ~/.cache/huggingface/token 读取) # ./scripts/push-to-space.sh GGSheng/page # # 环境变量 (可选): # SPACE_REPO_ID - Space 仓库 ID (如 GGSheng/page) # HF_TOKEN - Hugging Face API Token # HF_TOKEN_FILE - Token 文件路径 (默认 ~/.cache/huggingface/token) # # 说明: # 此脚本用于将本地代码强制推送到已存在的 Hugging Face Space # - 会覆盖 Space 中的所有文件 # - 排除 .git, logs, scripts, docs, tests 等非必要文件 # - 推送完成后会自动请求 Space 重启 # # 注意事项: # 1. 确保 HF_TOKEN 有 write 权限 # 2. Space 必须使用 Docker SDK # 3. 推送后 Space 会自动重启使更改生效 # ============================================================ update_readme_title() { local new_title="$1" local readme_file="$REPO_ROOT/README.md" local temp_file if [[ ! -f "$readme_file" ]]; then return 0 fi temp_file="$(mktemp)" if sed "s/^title:.*/title: $new_title/" "$readme_file" > "$temp_file"; then mv "$temp_file" "$readme_file" else rm -f "$temp_file" fi } restore_readme_title() { local original_title="$1" local readme_file="$REPO_ROOT/README.md" local temp_file if [[ ! -f "$readme_file" ]]; then return 0 fi temp_file="$(mktemp)" if sed "s/^title:.*/title: $original_title/" "$readme_file" > "$temp_file"; then mv "$temp_file" "$readme_file" else rm -f "$temp_file" fi } SPACE_REPO_ID="${1:-${SPACE_REPO_ID:-}}" HF_TOKEN="${2:-${HF_TOKEN:-}}" if [[ -z "$SPACE_REPO_ID" ]]; then echo "Usage: $0 [HF_TOKEN]" echo "" echo "Examples:" echo " $0 GGSheng/page hf_xxxxx" echo " SPACE_REPO_ID=GGSheng/page HF_TOKEN=hf_xxxxx $0" echo " $0 GGSheng/page" echo "" echo "Environment variables:" echo " SPACE_REPO_ID - Space 仓库 ID (如 GGSheng/page)" echo " HF_TOKEN - Hugging Face API Token" echo " HF_TOKEN_FILE - Token 文件路径 (默认 ~/.cache/huggingface/token)" exit 1 fi if [[ -z "$HF_TOKEN" ]]; then HF_TOKEN_FILE="${HF_TOKEN_FILE:-$HOME/.cache/huggingface/token}" if [[ -f "$HF_TOKEN_FILE" ]]; then HF_TOKEN="$(cat "$HF_TOKEN_FILE")" fi fi if [[ -z "$HF_TOKEN" ]]; then echo "Error: HF_TOKEN is required. Provide as 2nd arg, set HF_TOKEN env var, or ensure ~/.cache/huggingface/token exists." exit 1 fi SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)" SPACE_NAME="${SPACE_REPO_ID##*/}" echo "============================================" echo "OpenClaw HF Space Push Script" echo "============================================" echo "Space: $SPACE_REPO_ID" echo "Repo: $REPO_ROOT" echo "" cd "$REPO_ROOT" echo "[1/5] Logging into Hugging Face..." echo "$HF_TOKEN" | hf auth login --token "$HF_TOKEN" echo "" echo "[2/5] Saving original README title..." original_readme_title="$(sed -n 's/^title: *//p' "$REPO_ROOT/README.md" | head -n 1)" update_readme_title "$SPACE_NAME" restore_readme_on_exit() { restore_readme_title "${original_readme_title:-HF Space}" } trap restore_readme_on_exit EXIT echo "" echo "[3/5] Ensuring Space exists..." hf repos create "$SPACE_REPO_ID" --repo-type space --space-sdk docker --exist-ok echo "" echo "[4/5] Uploading files to Space..." hf upload "$SPACE_REPO_ID" . --repo-type space \ --exclude '.git/**' \ --exclude '.git' \ --exclude '.github/**' \ --exclude 'logs/**' \ --exclude '*.log' \ --exclude 'scripts/*.sh' \ --exclude 'docs/**' \ --exclude 'tests/**' \ --exclude 'LICENSE' \ --exclude '.dockerignore' \ --exclude '.python-version' \ --commit-message "fix: 强制推送更新 backup.py 修复逻辑" echo "" echo "[5/5] Requesting Space restart..." hf spaces restart "$SPACE_REPO_ID" echo "" echo "============================================" echo "Done! Space updated: https://huggingface.co/spaces/$SPACE_REPO_ID" echo "============================================"