Spaces:
Runtime error
Runtime error
File size: 6,791 Bytes
f691896 | 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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | """Publish the Space + sync the public GitHub mirror in one command.
Run from `chief-engineer/`:
make publish
or
uv run python -m scripts.publish
What it does:
1. Runs `scripts.deploy_preflight --push` to update the HF Space and reboot.
2. Syncs the Space-facing file subset to the public mirror repo
`kylebrodeur/microfactory-node` and pushes `main`.
Environment:
- HF_TOKEN or `hf auth login` must be active for the Space push.
- `gh auth login` or SSH key must be active for the GitHub push.
"""
from __future__ import annotations
import argparse
import os
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
MIRROR_REPO = "git@github.com:kylebrodeur/microfactory-node.git"
MIRROR_NAME = "microfactory-node"
# Same rules as deploy_preflight.SPACE_IGNORE, plus a .gitignore for the mirror itself.
MIRROR_IGNORE = [
"docs/**",
"!docs/reference/DEPLOYMENT.md",
"!docs/reference/SIMULATION.md",
"spike/**", "field_logs/**", "deliberation_logs/**", ".venv/**", "node_modules/**",
"recordings/**", "**/__pycache__/**", "**/*.pyc", ".git/**", ".gitignore", ".env", ".agents/**",
".codeboarding/**", ".codeboardingignore", "data/policy.json", "data/_generated.glb",
"data/_vprint.gif", "uv.lock", ".pytest_cache/**", "*.cap/**",
"learn/finetune/REPORT.md",
"learn/finetune/REPORT_v1.md",
]
def match_ignore(rel_path: str) -> bool:
import fnmatch
# (pattern, is_negative)
patterns: list[tuple[str, bool]] = []
for pat in MIRROR_IGNORE:
is_neg = pat.startswith("!")
real_pat = pat[1:] if is_neg else pat
patterns.append((real_pat, is_neg))
# Inclusions override exclusions.
for pat, is_neg in patterns:
if is_neg and _matches(rel_path, pat):
return False
for pat, is_neg in patterns:
if not is_neg and _matches(rel_path, pat):
return True
return False
def _matches(rel_path: str, pat: str) -> bool:
import fnmatch
if pat.endswith("/**"):
prefix = pat[:-3]
return rel_path.startswith(prefix + "/") or rel_path == prefix
if pat.startswith("**/"):
suffix = pat[3:]
return rel_path.endswith(suffix) or ("/" + suffix) in rel_path
if pat.startswith("*"):
return fnmatch.fnmatch(rel_path, pat) or fnmatch.fnmatch(Path(rel_path).name, pat)
return rel_path == pat or rel_path.startswith(pat + "/")
def run(cmd: list[str], cwd: Path | None = None, check: bool = True, capture_output: bool = False) -> subprocess.CompletedProcess:
print(f" $ {' '.join(cmd)}")
kwargs = {"cwd": cwd, "check": check, "text": True}
if capture_output:
kwargs["capture_output"] = True
return subprocess.run(cmd, **kwargs)
def publish_space(*, no_reboot: bool = False, dry_run: bool = False) -> bool:
print("\n⏫ Step 1 — update the HF Space")
cmd = ["uv", "run", "python", "-m", "scripts.deploy_preflight"]
if not dry_run:
cmd.append("--push")
if no_reboot:
cmd.append("--no-reboot")
r = subprocess.run(cmd, cwd=ROOT, text=True)
return r.returncode == 0
def sync_mirror(*, dry_run: bool = False) -> bool:
print("\n🪞 Step 2 — sync public GitHub mirror")
mirror_dir = Path(tempfile.gettempdir()) / f"{MIRROR_NAME}-sync"
if mirror_dir.exists():
shutil.rmtree(mirror_dir)
mirror_dir.mkdir(parents=True)
print(f" Mirroring Space-facing subset → {mirror_dir}")
files_copied = 0
for src in sorted(ROOT.rglob("*")):
if not src.is_file():
continue
rel = src.relative_to(ROOT).as_posix()
if match_ignore(rel):
continue
dst = mirror_dir / rel
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src, dst)
files_copied += 1
# Drop transient pycache/pi that may have slipped through
for d in list(mirror_dir.rglob("__pycache__")):
shutil.rmtree(d)
pi_dir = mirror_dir / ".pi"
if pi_dir.exists():
shutil.rmtree(pi_dir)
print(f" Copied {files_copied} files")
run(["git", "init", "-b", "main"], cwd=mirror_dir, check=False)
run(["git", "remote", "add", "origin", MIRROR_REPO], cwd=mirror_dir, check=False)
run(["git", "fetch", "origin", "main"], cwd=mirror_dir, check=False)
run(["git", "reset", "--hard", "origin/main"], cwd=mirror_dir, check=False)
# Clean working tree but keep .git
for item in mirror_dir.iterdir():
if item.name == ".git":
continue
if item.is_dir():
shutil.rmtree(item)
else:
item.unlink()
# Re-copy after reset
for src in sorted(ROOT.rglob("*")):
if not src.is_file():
continue
rel = src.relative_to(ROOT).as_posix()
if match_ignore(rel):
continue
dst = mirror_dir / rel
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src, dst)
for d in list(mirror_dir.rglob("__pycache__")):
shutil.rmtree(d)
if (mirror_dir / ".pi").exists():
shutil.rmtree(mirror_dir / ".pi")
run(["git", "add", "-A"], cwd=mirror_dir)
status = run(["git", "status", "--short"], cwd=mirror_dir, check=True, capture_output=True)
if not status.stdout.strip():
print(" Mirror already up to date.")
return True
print(f" Changes:\n{status.stdout}")
if dry_run:
print(" (dry-run: not committing or pushing)")
return True
run(["git", "commit", "-m", "Re-sync from private microfactory-lab"], cwd=mirror_dir)
run(["git", "push", "origin", "main"], cwd=mirror_dir)
print(f" ✅ Mirror pushed: https://github.com/kylebrodeur/{MIRROR_NAME}")
return True
def main() -> int:
ap = argparse.ArgumentParser(description="Publish the HF Space + sync the public GitHub mirror.")
ap.add_argument("--no-reboot", action="store_true", help="push to Space but skip factory reboot")
ap.add_argument("--mirror-only", action="store_true", help="skip the HF Space push; only sync the mirror")
ap.add_argument("--dry-run", action="store_true", help="show what would happen; do not push")
args = ap.parse_args()
print("Publish Microfactory Node: HF Space + public GitHub mirror")
print("=" * 60)
if not args.mirror_only:
if not publish_space(no_reboot=args.no_reboot, dry_run=args.dry_run):
print("\n🔴 Space push failed — mirror sync skipped.")
return 1
if not sync_mirror(dry_run=args.dry_run):
print("\n🔴 Mirror sync failed.")
return 1
print("\n🟢 Published: Space updated, mirror synced.")
return 0
if __name__ == "__main__":
sys.exit(main())
|