Spaces:
Runtime error
Runtime error
File size: 5,260 Bytes
b9ed97d | 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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | name: HF β GitHub Sync
# Trigger on every push to main (GitHub β HF direction)
# and hourly to pull any HF-side changes back (HF β GitHub direction)
on:
push:
branches: [main]
schedule:
- cron: '0 * * * *' # hourly HF pull-check
workflow_dispatch:
inputs:
force_direction:
description: 'Force sync direction (hf-wins | gh-wins | auto)'
required: false
default: 'auto'
env:
HF_REPO_TYPE: space # model | dataset | space
HF_REPO: ${{ vars.HF_REPO }} # e.g. your-org/codecraftlab
jobs:
sync:
name: Sync HuggingFace β GitHub
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout (full history)
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git identity
run: |
git config user.email "sync-bot@codecraftlab.noreply"
git config user.name "CodeCraftLab Sync Bot"
- name: Install git-lfs
run: |
sudo apt-get install -y git-lfs
git lfs install
- name: Add HuggingFace remote
run: |
git remote add hf \
"https://user:${{ secrets.HF_TOKEN }}@huggingface.co/${HF_REPO_TYPE}s/${HF_REPO}"
git fetch hf --prune
- name: Detect divergence and resolve
id: sync
env:
FORCE_DIRECTION: ${{ github.event.inputs.force_direction || 'auto' }}
run: |
set -euo pipefail
HF_HEAD=$(git rev-parse hf/main 2>/dev/null || echo "NONE")
GH_HEAD=$(git rev-parse HEAD)
if [ "$HF_HEAD" = "NONE" ]; then
echo "action=push-to-hf" >> "$GITHUB_OUTPUT"
echo "reason=HF remote has no main branch β initial push"
exit 0
fi
BASE=$(git merge-base HEAD hf/main 2>/dev/null || echo "NONE")
if [ "$FORCE_DIRECTION" = "hf-wins" ]; then
echo "action=hf-wins" >> "$GITHUB_OUTPUT"
echo "reason=Forced HF-wins override"
elif [ "$FORCE_DIRECTION" = "gh-wins" ]; then
echo "action=push-to-hf" >> "$GITHUB_OUTPUT"
echo "reason=Forced GH-wins override"
elif [ "$HF_HEAD" = "$GH_HEAD" ]; then
echo "action=in-sync" >> "$GITHUB_OUTPUT"
echo "reason=Already in sync"
elif [ "$BASE" = "$GH_HEAD" ]; then
# HF is ahead β pull HF β GitHub
echo "action=hf-wins" >> "$GITHUB_OUTPUT"
echo "reason=GitHub is behind HF β fast-forward"
elif [ "$BASE" = "$HF_HEAD" ]; then
# GitHub is ahead β push GitHub β HF
echo "action=push-to-hf" >> "$GITHUB_OUTPUT"
echo "reason=HF is behind GitHub β pushing"
else
# Both diverged β HF is source of truth
echo "action=hf-wins" >> "$GITHUB_OUTPUT"
echo "reason=CONFLICT: both diverged β HF wins (source of truth)"
fi
- name: "[In-sync] Nothing to do"
if: steps.sync.outputs.action == 'in-sync'
run: echo "β
HF and GitHub are in sync β no action required."
- name: "[Push] GitHub β HuggingFace"
if: steps.sync.outputs.action == 'push-to-hf'
run: |
echo "π€ Pushing GitHub β HuggingFace"
git push hf main
- name: "[HF Wins] HuggingFace β GitHub"
if: steps.sync.outputs.action == 'hf-wins'
run: |
echo "π₯ HuggingFace wins β overwriting GitHub main"
git reset --hard hf/main
git push origin main --force-with-lease || git push origin main --force
- name: Summary
if: always()
run: |
echo "### Sync Result" >> "$GITHUB_STEP_SUMMARY"
echo "- **Action:** ${{ steps.sync.outputs.action }}" >> "$GITHUB_STEP_SUMMARY"
echo "- **Trigger:** ${{ github.event_name }}" >> "$GITHUB_STEP_SUMMARY"
echo "- **Branch:** main" >> "$GITHUB_STEP_SUMMARY"
# ------------------------------------------------------------------
# Validate HF Space config on every push
# ------------------------------------------------------------------
validate-space-config:
name: Validate HF Space README config
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check README frontmatter
run: |
python3 - <<'EOF'
import re, sys
with open("README.md") as f:
content = f.read()
match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
if not match:
print("β README is missing HF Space YAML frontmatter")
sys.exit(1)
frontmatter = match.group(1)
required_keys = ["title", "sdk", "app_port", "license"]
missing = [k for k in required_keys if k + ":" not in frontmatter]
if missing:
print(f"β Missing frontmatter keys: {missing}")
sys.exit(1)
if "sdk: streamlit" in frontmatter:
print("β sdk is still 'streamlit' β should be 'docker' for FastAPI")
sys.exit(1)
print("β
HF Space frontmatter is valid")
EOF
|