CoolFace
Apppublic

LZ-SG/embedded-dev-tutorials

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
push_to_github.py120 linesDownload Raw Back to root
1#!/usr/bin/env python32"""通过GitHub Contents API批量推送文件到远程仓库"""3import os, base64, json, urllib.request, urllib.error, time4 5TOKEN = "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"6REPO = "SG06231219-boop/embedded-dev-tutorials"7BRANCH = "main"8API_BASE = f"https://api.github.com/repos/{REPO}/contents"9 10# 需要推送的文件列表(相对于项目根目录)11FILES_TO_PUSH = [12    "static/tutorials/esp32.html",13    "static/tutorials/flash-debug.html",14    "static/tutorials/freertos.html",15    "static/tutorials/main.html",16    "static/tutorials/protocols.html",17    "static/tutorials/proj-led-button.html",18    "static/tutorials/proj-uart-hello.html",19    "static/tutorials/proj-oled-display.html",20    "static/tutorials/proj-dht11-monitor.html",21    "static/tutorials/proj-pwm-motor.html",22    "static/tutorials/proj-servo-control.html",23    "static/tutorials/proj-ir-remote.html",24    "static/tutorials/proj-ultrasonic.html",25    "static/tutorials/proj-stepper-motor.html",26    "static/tutorials/proj-freertos-station.html",27    "static/tutorials/proj-smart-car.html",28    "static/tutorials/proj-can-bus.html",29    "static/tutorials/proj-sd-logger.html",30    "static/tutorials/proj-esp32-iot.html",31    "static/tutorials/proj-low-power.html",32    "static/tutorials/proj-bootloader-iap.html",33    "static/tutorials/proj-dma-adc.html",34    "static/tutorials/proj-usb-hid.html",35    "static/tutorials/proj-s32k144-auto.html",36    "static/tutorials/proj-oscilloscope-debug.html",37]38 39BASE_DIR = os.path.dirname(os.path.abspath(__file__))40 41def get_remote_sha(path):42    """获取远程文件的SHA"""43    url = f"{API_BASE}/{path}?ref={BRANCH}"44    req = urllib.request.Request(url, headers={45        "Authorization": f"token {TOKEN}",46        "Accept": "application/vnd.github.v3+json",47        "User-Agent": "push-script"48    })49    try:50        with urllib.request.urlopen(req, timeout=15) as resp:51            data = json.loads(resp.read())52            return data.get("sha")53    except urllib.error.HTTPError as e:54        if e.code == 404:55            return None56        raise57 58def push_file(path, message):59    """推送单个文件到GitHub"""60    local_path = os.path.join(BASE_DIR, path.replace("/", os.sep))61    if not os.path.exists(local_path):62        print(f"  SKIP {path} (not found locally)")63        return False64    65    with open(local_path, "rb") as f:66        content = base64.b64encode(f.read()).decode("utf-8")67    68    sha = get_remote_sha(path)69    70    payload = {71        "message": message,72        "content": content,73        "branch": BRANCH,74    }75    if sha:76        payload["sha"] = sha77    78    url = f"{API_BASE}/{path}"79    data = json.dumps(payload).encode("utf-8")80    req = urllib.request.Request(url, data=data, headers={81        "Authorization": f"token {TOKEN}",82        "Accept": "application/vnd.github.v3+json",83        "User-Agent": "push-script",84        "Content-Type": "application/json"85    }, method="PUT")86    87    try:88        with urllib.request.urlopen(req, timeout=30) as resp:89            result = json.loads(resp.read())90            commit_sha = result.get("commit", {}).get("sha", "?")[:7]91            print(f"  OK {path} (commit {commit_sha})")92            return True93    except urllib.error.HTTPError as e:94        body = e.read().decode("utf-8", errors="replace")95        print(f"  FAIL {path}: {e.code} {body[:200]}")96        return False97 98def main():99    total = len(FILES_TO_PUSH)100    ok = 0101    fail = 0102    103    print(f"Pushing {total} files to {REPO}:{BRANCH}...")104    105    for i, fpath in enumerate(FILES_TO_PUSH, 1):106        print(f"[{i}/{total}] {fpath}")107        msg = f"feat: v1.5.0 - FAQ+cross-refs for {os.path.basename(fpath)}"108        if push_file(fpath, msg):109            ok += 1110        else:111            fail += 1112        # Rate limit: 逐文件推送间隔1秒113        if i < total:114            time.sleep(1)115    116    print(f"\nDone: {ok} OK, {fail} FAIL out of {total}")117 118if __name__ == "__main__":119    main()120