import os import shutil import tempfile from git import Repo from huggingface_hub import HfApi import gradio as gr HF_TOKEN = os.getenv("HF_TOKEN") def clone_and_push( github_repo_url: str, target_space: str, commit_message: str = "Sync from GitHub" ): """ Clone a GitHub repo and push it to a Hugging Face Space """ if not HF_TOKEN: return "❌ HF_TOKEN not set in Space secrets." tmp_dir = tempfile.mkdtemp() try: # 1️⃣ Clone GitHub repository repo_path = os.path.join(tmp_dir, "github_repo") Repo.clone_from(github_repo_url, repo_path) # 2️⃣ Clone Hugging Face Space space_path = os.path.join(tmp_dir, "hf_space") hf_repo_url = f"https://huggingface.co/spaces/{target_space}" Repo.clone_from( hf_repo_url, space_path, env={"GIT_ASKPASS": "echo", "GIT_USERNAME": "hf"} ) # 3️⃣ Clear existing Space files (except .git) for item in os.listdir(space_path): if item != ".git": item_path = os.path.join(space_path, item) if os.path.isdir(item_path): shutil.rmtree(item_path) else: os.remove(item_path) # 4️⃣ Copy GitHub repo contents into Space for item in os.listdir(repo_path): if item == ".git": continue src = os.path.join(repo_path, item) dst = os.path.join(space_path, item) if os.path.isdir(src): shutil.copytree(src, dst) else: shutil.copy2(src, dst) # 5️⃣ Commit & push repo = Repo(space_path) repo.git.add(A=True) repo.index.commit(commit_message) with repo.git.custom_environment( GIT_USERNAME="hf", GIT_PASSWORD=HF_TOKEN ): repo.remote("origin").push() return "✅ Repository successfully synced to Hugging Face Space!" except Exception as e: return f"❌ Error: {str(e)}" finally: shutil.rmtree(tmp_dir, ignore_errors=True) # 🎛 Gradio UI with gr.Blocks(title="GitHub → Hugging Face Space Sync") as demo: gr.Markdown("## 🚀 GitHub to Hugging Face Space Deployer") github_repo = gr.Textbox( label="GitHub Repository URL", placeholder="https://github.com/username/repo" ) target_space = gr.Textbox( label="Target Hugging Face Space", placeholder="username/space-name" ) commit_msg = gr.Textbox( label="Commit Message", value="Sync from GitHub" ) output = gr.Textbox(label="Status") btn = gr.Button("Clone & Push") btn.click( clone_and_push, inputs=[github_repo, target_space, commit_msg], outputs=output ) demo.launch()