Spaces:
Running on Zero
Running on Zero
| # Deploy gradio-apps/compounding-test/ to a HuggingFace Space via | |
| # `git subtree push`. The monorepo stays the canonical source; the | |
| # Space repo holds only the contents of that one subdirectory. | |
| # | |
| # One-time setup (run by the user before first deploy): | |
| # git remote add hf-compounding-test https://huggingface.co/spaces/<owner>/<space> | |
| # # the remote name MUST be `hf-compounding-test` β this script looks for it | |
| # | |
| # Every deploy: | |
| # ./gradio-apps/compounding-test/deploy.sh # push current branch | |
| # ./gradio-apps/compounding-test/deploy.sh --dry-run # sanity checks only | |
| # ./gradio-apps/compounding-test/deploy.sh --force # force-push (first deploy only) | |
| set -euo pipefail | |
| REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" | |
| SPACE_DIR="$REPO_ROOT/gradio-apps/compounding-test" | |
| SPACE_PREFIX="gradio-apps/compounding-test" | |
| REMOTE_NAME="hf-compounding-test" | |
| TARGET_BRANCH="main" # HuggingFace Spaces use `main` as the deploy branch | |
| DRY_RUN=0 | |
| FORCE=0 | |
| for arg in "$@"; do | |
| case "$arg" in | |
| --dry-run) DRY_RUN=1 ;; | |
| --force) FORCE=1 ;; | |
| *) echo "Unknown flag: $arg" >&2; exit 1 ;; | |
| esac | |
| done | |
| # --------------------------------------------------------------------------- | |
| # Sanity checks (fail fast with clear messages) | |
| # --------------------------------------------------------------------------- | |
| cd "$REPO_ROOT" | |
| # 1. Space directory exists | |
| if [[ ! -d "$SPACE_DIR" ]]; then | |
| echo "β Space directory not found: $SPACE_DIR" >&2 | |
| exit 1 | |
| fi | |
| # 2. Required files exist at the Space root | |
| for required in app.py requirements.txt README.md; do | |
| if [[ ! -f "$SPACE_DIR/$required" ]]; then | |
| echo "β Missing required file at Space root: $SPACE_PREFIX/$required" >&2 | |
| exit 1 | |
| fi | |
| done | |
| # 3. README.md has the YAML header HF Spaces needs (sdk, app_file). | |
| # Without these, the Space won't build. | |
| if ! grep -q "^sdk: gradio" "$SPACE_DIR/README.md"; then | |
| echo "β $SPACE_PREFIX/README.md is missing 'sdk: gradio' in its YAML header." >&2 | |
| echo " HuggingFace Spaces require this to pick the Gradio runtime." >&2 | |
| exit 1 | |
| fi | |
| if ! grep -q "^app_file: app.py" "$SPACE_DIR/README.md"; then | |
| echo "β $SPACE_PREFIX/README.md is missing 'app_file: app.py' in its YAML header." >&2 | |
| exit 1 | |
| fi | |
| # 4. HF remote is configured | |
| if ! git remote get-url "$REMOTE_NAME" >/dev/null 2>&1; then | |
| echo "β Git remote '$REMOTE_NAME' not configured." >&2 | |
| echo "" >&2 | |
| echo " Add it once with:" >&2 | |
| echo " git remote add $REMOTE_NAME https://huggingface.co/spaces/<owner>/<space>" >&2 | |
| echo "" >&2 | |
| echo " (Replace <owner>/<space> with your actual HF Space path, e.g." >&2 | |
| echo " AshwinP/compounding-test.)" >&2 | |
| exit 1 | |
| fi | |
| REMOTE_URL="$(git remote get-url "$REMOTE_NAME")" | |
| # 5. Working tree is clean within the Space directory. Uncommitted changes | |
| # inside the prefix would be SILENTLY DROPPED by git subtree, which is | |
| # a footgun β fail loud instead. | |
| if ! git diff --quiet -- "$SPACE_PREFIX" || ! git diff --cached --quiet -- "$SPACE_PREFIX"; then | |
| echo "β Uncommitted changes inside $SPACE_PREFIX/:" >&2 | |
| git status --short -- "$SPACE_PREFIX" >&2 | |
| echo "" >&2 | |
| echo " Commit (or stash) these before deploying β git subtree only pushes" >&2 | |
| echo " what's in the commit history, so unstaged work would silently miss" >&2 | |
| echo " the deploy." >&2 | |
| exit 1 | |
| fi | |
| # 6. Tests pass. The parser + provider tests are the gate that protects the | |
| # deployed Space's behavior β if they're red, do not deploy. | |
| echo "β Running tests in $SPACE_PREFIX/..." | |
| if command -v python3 >/dev/null 2>&1; then | |
| if ! (cd "$SPACE_DIR" && python3 -m pytest test_diagnose.py -q 2>&1 | tail -5); then | |
| echo "β Tests failed. Fix before deploying." >&2 | |
| exit 1 | |
| fi | |
| else | |
| echo " (python3 not found β skipping test gate)" >&2 | |
| fi | |
| # --------------------------------------------------------------------------- | |
| # Report state | |
| # --------------------------------------------------------------------------- | |
| CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" | |
| CURRENT_SHA="$(git rev-parse --short HEAD)" | |
| echo "" | |
| echo "Ready to deploy:" | |
| echo " source prefix: $SPACE_PREFIX" | |
| echo " source commit: $CURRENT_SHA ($CURRENT_BRANCH)" | |
| echo " HF remote: $REMOTE_NAME ($REMOTE_URL)" | |
| echo " target branch: $TARGET_BRANCH" | |
| echo "" | |
| if [[ "$DRY_RUN" -eq 1 ]]; then | |
| echo "β Dry run β all sanity checks passed. No push performed." | |
| exit 0 | |
| fi | |
| # --------------------------------------------------------------------------- | |
| # Push to HuggingFace Space | |
| # --------------------------------------------------------------------------- | |
| # | |
| # Two push modes: | |
| # default: `git subtree push` β fast-forward only. Works for every deploy | |
| # after the first one (and for first deploys to a Space that has | |
| # never been initialized server-side). | |
| # --force: `git subtree split` to a temp branch, then `git push --force` | |
| # that branch to the remote's main. Required for the FIRST deploy | |
| # to a freshly-created HF Space, because HF auto-creates an initial | |
| # commit (README placeholder) that our subtree history can't | |
| # fast-forward over. `git subtree push --force` is NOT a valid flag | |
| # combo β only the split+push form works. | |
| if [[ "$FORCE" -eq 1 ]]; then | |
| TEMP_BRANCH="hf-deploy-$(date +%s)" | |
| echo "β Splitting $SPACE_PREFIX into temp branch $TEMP_BRANCH..." | |
| git subtree split --prefix="$SPACE_PREFIX" -b "$TEMP_BRANCH" >/dev/null | |
| echo "β Force-pushing $TEMP_BRANCH β $REMOTE_NAME/$TARGET_BRANCH..." | |
| if git push "$REMOTE_NAME" "$TEMP_BRANCH:$TARGET_BRANCH" --force; then | |
| git branch -D "$TEMP_BRANCH" >/dev/null | |
| echo "" | |
| echo "β Force-deploy pushed. HuggingFace will rebuild the Space shortly." | |
| echo " Track build status at: ${REMOTE_URL%.git}" | |
| else | |
| git branch -D "$TEMP_BRANCH" >/dev/null 2>&1 || true | |
| echo "" | |
| echo "β Force-push failed. Check authentication (huggingface-cli login)" >&2 | |
| echo " and Space permissions." >&2 | |
| exit 1 | |
| fi | |
| else | |
| echo "β Pushing subtree to $REMOTE_NAME/$TARGET_BRANCH..." | |
| if git subtree push --prefix="$SPACE_PREFIX" "$REMOTE_NAME" "$TARGET_BRANCH"; then | |
| echo "" | |
| echo "β Deploy pushed. HuggingFace will rebuild the Space shortly." | |
| echo " Track build status at: ${REMOTE_URL%.git}" | |
| else | |
| echo "" | |
| echo "β Push rejected (non-fast-forward). If this is the FIRST deploy to" >&2 | |
| echo " a freshly-created HF Space, HuggingFace seeded the repo with a" >&2 | |
| echo " placeholder README that our subtree history can't fast-forward" >&2 | |
| echo " over. Re-run with --force to overwrite it:" >&2 | |
| echo "" >&2 | |
| echo " $(basename "$0") --force" >&2 | |
| echo "" >&2 | |
| echo " CAUTION: --force overwrites whatever is currently on the Space's" >&2 | |
| echo " main branch. Safe for first deploys; review carefully otherwise." >&2 | |
| exit 1 | |
| fi | |
| fi | |