ASHu2 commited on
Commit
b647614
·
unverified ·
1 Parent(s): 7d15ad7

feat: add GitHub Actions workflow for deploying Modal vision model to Hugging Face Space

Browse files
.github/workflows/deploy-hf-space-modal.yml ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Deploy to Hugging Face Space (Modal vision)
2
+
3
+ # Manual only: trigger from the GitHub Actions tab ("Run workflow") and pick the
4
+ # branch to deploy. Pushes the checked-out branch to the build-small-hackathon
5
+ # Space's `main`, where HF builds the root Dockerfile.
6
+ #
7
+ # Difference from deploy-hf-space.yml (the CPU test space): vision is ON and
8
+ # served from Modal. RG_USE_MODEL=1 + RG_USE_VISION_API=1 are forced here (not
9
+ # read from the shared repo var, which is 0 for the CPU space), and the vision
10
+ # API vars/secret are synced alongside the dialogue ones. Same repo/Dockerfile,
11
+ # different runtime config — HF Space variables override the Dockerfile ENV.
12
+ on:
13
+ workflow_dispatch:
14
+
15
+ concurrency:
16
+ group: deploy-hf-space-modal
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ deploy:
21
+ runs-on: ubuntu-latest
22
+ env:
23
+ HF_USER: build-small-hackathon
24
+ HF_SPACE: Rune-Goblin
25
+ steps:
26
+ - name: Checkout (full history)
27
+ uses: actions/checkout@v4
28
+ with:
29
+ fetch-depth: 0
30
+ lfs: true
31
+
32
+ - name: Set up Python
33
+ uses: actions/setup-python@v5
34
+ with:
35
+ python-version: "3.11"
36
+
37
+ - name: Install Hugging Face Hub client
38
+ run: python -m pip install --upgrade huggingface_hub
39
+
40
+ - name: Install Git Xet
41
+ run: |
42
+ curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/huggingface/xet-core/refs/heads/main/git_xet/install.sh | sh
43
+ git xet install
44
+ git xet --version
45
+
46
+ - name: Install Git LFS
47
+ run: |
48
+ sudo apt-get update
49
+ sudo apt-get install -y git-lfs
50
+ git lfs install
51
+
52
+ - name: Clean checkout before LFS migration
53
+ run: |
54
+ git reset --hard HEAD
55
+ git clean -fd
56
+
57
+ - name: Migrate binaries to LFS pointers for Space push
58
+ run: |
59
+ git lfs migrate import --yes --everything --include="*.wav,*.png,*.jpg,*.jpeg,*.mp3,*.ogg,*.gif"
60
+
61
+ - name: Sync Space runtime config
62
+ env:
63
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
64
+ GRADIO_SERVER_PORT: ${{ vars.GRADIO_SERVER_PORT }}
65
+ # Dialogue (unchanged — still the existing remote API)
66
+ RG_USE_DIALOGUE_API: ${{ vars.RG_USE_DIALOGUE_API }}
67
+ RG_DIALOGUE_API_URL: ${{ vars.RG_DIALOGUE_API_URL }}
68
+ RG_DIALOGUE_API_MODEL: ${{ vars.RG_DIALOGUE_API_MODEL }}
69
+ RG_DIALOGUE_API_TIMEOUT: ${{ vars.RG_DIALOGUE_API_TIMEOUT }}
70
+ RG_DIALOGUE_API_KEY: ${{ secrets.RG_DIALOGUE_API_KEY }}
71
+ # Vision via Modal (new)
72
+ RG_VISION_API_URL: ${{ vars.RG_VISION_API_URL }}
73
+ RG_VISION_API_MODEL: ${{ vars.RG_VISION_API_MODEL }}
74
+ RG_VISION_API_TIMEOUT: ${{ vars.RG_VISION_API_TIMEOUT }}
75
+ RG_VISION_API_KEY: ${{ secrets.RG_VISION_API_KEY }}
76
+ run: |
77
+ test -n "${HF_TOKEN}"
78
+ python - <<'PY'
79
+ import os
80
+ from huggingface_hub import HfApi
81
+
82
+ repo_id = f"{os.environ['HF_USER']}/{os.environ['HF_SPACE']}"
83
+ api = HfApi(token=os.environ["HF_TOKEN"])
84
+
85
+ # Forced ON for this deployment (do NOT read the shared RG_USE_MODEL
86
+ # repo var — that is 0 for the CPU test space).
87
+ variables = {
88
+ "RG_USE_MODEL": "1",
89
+ "RG_USE_VISION_API": "1",
90
+ "RG_USE_DIALOGUE_API": os.environ.get("RG_USE_DIALOGUE_API") or "1",
91
+ "GRADIO_SERVER_PORT": os.environ.get("GRADIO_SERVER_PORT") or "7860",
92
+ }
93
+ optional_variables = {
94
+ "RG_DIALOGUE_API_URL": os.environ.get("RG_DIALOGUE_API_URL", ""),
95
+ "RG_DIALOGUE_API_MODEL": os.environ.get("RG_DIALOGUE_API_MODEL", ""),
96
+ "RG_DIALOGUE_API_TIMEOUT": os.environ.get("RG_DIALOGUE_API_TIMEOUT", ""),
97
+ "RG_VISION_API_URL": os.environ.get("RG_VISION_API_URL", ""),
98
+ "RG_VISION_API_MODEL": os.environ.get("RG_VISION_API_MODEL", ""),
99
+ # First cast after scale-to-zero pays an L4 cold start; give the
100
+ # client room to wait it out instead of falling back to the rule
101
+ # engine. Override via the repo variable if needed.
102
+ "RG_VISION_API_TIMEOUT": os.environ.get("RG_VISION_API_TIMEOUT", "") or "180",
103
+ }
104
+ secrets = {
105
+ "RG_DIALOGUE_API_KEY": os.environ.get("RG_DIALOGUE_API_KEY", ""),
106
+ "RG_VISION_API_KEY": os.environ.get("RG_VISION_API_KEY", ""),
107
+ }
108
+
109
+ for key, value in optional_variables.items():
110
+ if value:
111
+ variables[key] = value
112
+
113
+ for key, value in variables.items():
114
+ api.add_space_variable(repo_id=repo_id, key=key, value=value)
115
+ print(f"set variable {key}")
116
+
117
+ for key, value in secrets.items():
118
+ if value:
119
+ api.add_space_secret(repo_id=repo_id, key=key, value=value)
120
+ print(f"set secret {key}")
121
+ PY
122
+
123
+ - name: Push to HF Space
124
+ env:
125
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
126
+ run: |
127
+ test -n "${HF_TOKEN}"
128
+ git push --force \
129
+ "https://${HF_USER}:${HF_TOKEN}@huggingface.co/spaces/${HF_USER}/${HF_SPACE}" \
130
+ "HEAD:main"