| |
| """Deploy ClawEmail source to the HuggingFace Docker Space. |
| |
| The HF write token is read ONLY from the HF_TOKEN environment variable and is |
| never written to disk or printed. HF builds the image from source (Dockerfile |
| runs `npm run build`), so we upload the source tree minus build/secret dirs. |
| |
| Usage (PowerShell): |
| $env:HF_TOKEN = "hf_xxx"; python scripts/hf_deploy.py |
| """ |
| import os |
| import sys |
|
|
| REPO_ID = "Echocq/clawemail" |
| REPO_TYPE = "space" |
|
|
| IGNORE = [ |
| ".git/*", ".github/*", ".codex-run/*", ".claude/*", ".spec-workflow/*", |
| "node_modules/*", "*/node_modules/*", |
| |
| |
| "reference/*", |
| "dist/*", "data/*", "*.log", |
| ".env", ".env.*", |
| |
| "LOG.md", "TASK.md", "TASK_LOG.md", "PROJECT_ID.md", "PROJECT_CONTEXT.md", |
| "PROJECT_MAP.md", "AGENTS.md", "_archive/*", ".project/*", |
| |
| "archive/*", "*.secret.md", "*/*.secret.md", |
| ] |
|
|
|
|
| def _token_from_env_file() -> str | None: |
| |
| |
| path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env") |
| if not os.path.exists(path): |
| return None |
| for line in open(path, encoding="utf-8"): |
| line = line.strip() |
| if line.startswith("HF_TOKEN") and "=" in line: |
| return line.split("=", 1)[1].strip().strip('"').strip("'") |
| return None |
|
|
|
|
| def main() -> int: |
| token = os.environ.get("HF_TOKEN") or _token_from_env_file() |
| if not token: |
| print("ERROR: set HF_TOKEN env var or add HF_TOKEN to .env first.", file=sys.stderr) |
| return 2 |
|
|
| from huggingface_hub import HfApi |
| api = HfApi(token=token) |
|
|
| who = api.whoami() |
| print(f"auth ok as: {who.get('name')}") |
|
|
| root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| print(f"uploading {root} -> {REPO_ID}") |
| commit = api.upload_folder( |
| repo_id=REPO_ID, |
| repo_type=REPO_TYPE, |
| folder_path=root, |
| ignore_patterns=IGNORE, |
| commit_message="fix(cf): filter /admin/address aliases by provider domain β hide stale entries from old/other domains (e.g. legacy wahah.xyz) so each category shows only its own domain", |
| ) |
| print(f"uploaded: {getattr(commit, 'oid', commit)}") |
|
|
| api.restart_space(repo_id=REPO_ID) |
| print("restart triggered -> BUILDING") |
| return 0 |
|
|
|
|
| if __name__ == "__main__": |
| raise SystemExit(main()) |
|
|