File size: 2,908 Bytes
b383610
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8691ce5
 
 
b383610
 
 
8691ce5
1bcb9d8
b383610
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"""Deploy the current working tree to the Hugging Face Space.

The Space (https://huggingface.co/spaces/lefft/contimp-app) builds from its own
copy of these files. This uploads the repo's working tree to the Space, which
triggers a rebuild. Merging to GitHub does NOT deploy — this is the deploy step.

Run after merging a change to main, from anywhere in the repo:

    uv run --with huggingface_hub python scripts/deploy.py -m "what changed"

Auth: uses your cached Hugging Face login (run `hf auth login` once; token lives
in ~/.cache/huggingface/). You must have write access to the Space. No app
secrets are involved here — those live in the Space's own Settings, never in
this repo. `.env` and other local-only files are excluded from the upload.
"""

import argparse
import sys
from pathlib import Path

SPACE_ID = "lefft/contimp-app"
REPO_ROOT = Path(__file__).resolve().parent.parent

# Everything that must never reach the Space (secrets, local env, caches, VCS,
# and Claude Code tooling — skills/settings/worktrees are dev-only and the Space
# does not need them; this also keeps stray git worktrees out of the upload).
IGNORE = [
    ".git/*", ".git*", ".venv/*", "__pycache__/*", "**/__pycache__/*",
    "*.pyc", ".env", ".env.*", ".pytest_cache/*",
    ".claude/*", ".claude",
    "docs/internal/*",  # internal design docs — never publish to the Space
]


def main() -> None:
    parser = argparse.ArgumentParser(description="Deploy working tree to the HF Space.")
    parser.add_argument("-m", "--message", default="Manual deploy from working tree",
                        help="Commit message for the Space upload")
    args = parser.parse_args()

    # Guard against uploading the wrong directory.
    if not (REPO_ROOT / "pyproject.toml").exists() or not (REPO_ROOT / "app").is_dir():
        sys.exit(f"refusing to deploy: {REPO_ROOT} doesn't look like the contimp-app repo")

    try:
        from huggingface_hub import HfApi
    except ImportError:
        sys.exit("huggingface_hub not installed. Run via: "
                 "uv run --with huggingface_hub python scripts/deploy.py")

    api = HfApi()
    try:
        who = api.whoami()
    except Exception:
        sys.exit("not logged in to Hugging Face. Run `hf auth login` first "
                 "(needs write access to the Space).")

    print(f"deploying {REPO_ROOT.name} as {who['name']} -> {SPACE_ID}")
    api.upload_folder(
        folder_path=str(REPO_ROOT),
        repo_id=SPACE_ID,
        repo_type="space",
        commit_message=args.message,
        ignore_patterns=IGNORE,
    )
    print("uploaded; the Space is rebuilding (~1-2 min).")
    print("  app:    https://lefft-contimp-app.hf.space")
    print("  verify: curl https://lefft-contimp-app.hf.space/api/health")
    print("  logs:   https://huggingface.co/spaces/lefft/contimp-app  (Settings -> Logs)")


if __name__ == "__main__":
    main()