Files
comfyui_o1key/utils/updater.py
T
Jony ba920f2b66 Publish current ComfyUI O1Key code baseline
Replace the prior release tree with the current plugin, frontend, tests, and documentation. Document retired node IDs and the public Gitea update source.
2026-09-24 19:56:48 +08:00

104 lines
4.0 KiB
Python

"""Fast-forward a clean Git installation from the public O1Key release repo."""
import os
import subprocess
from pathlib import Path
PLUGIN_DIR = Path(__file__).resolve().parent.parent
RELEASE_REPOSITORY_URL = "https://git.o1key.com/publisher/comfyui_o1key.git"
class UpdateError(Exception):
def __init__(self, code, message, suggestion, status=409):
super().__init__(message)
self.code = code
self.suggestion = suggestion
self.status = status
def as_dict(self):
return {
"code": self.code,
"error": str(self),
"suggestion": self.suggestion,
}
def _git(*args, timeout=60, check=True):
env = os.environ.copy()
env["GIT_TERMINAL_PROMPT"] = "0"
env["GCM_INTERACTIVE"] = "Never"
try:
result = subprocess.run(
["git", *args], cwd=PLUGIN_DIR, env=env,
capture_output=True, text=True, encoding="utf-8",
errors="replace", timeout=timeout,
)
except FileNotFoundError as exc:
raise UpdateError(
"git_missing", "未找到 Git。", "安装 Git 后重启 ComfyUI,再重新检查更新。", 503,
) from exc
except subprocess.TimeoutExpired as exc:
raise UpdateError(
"timeout", "连接发布仓库超时。", "检查网络连接,稍后再试。", 504,
) from exc
if check and result.returncode:
raise UpdateError(
"git_failed", "Git 操作未完成。", "检查插件目录的 Git 状态后重试。",
)
return result
def update_package():
"""Fetch the release main branch and fast-forward only a clean local main."""
if not (PLUGIN_DIR / ".git").exists():
raise UpdateError(
"not_git", "当前插件不是 Git 安装。",
"请从发布仓库重新以 Git 安装;现有配置文件先单独备份。",
)
branch = _git("symbolic-ref", "--quiet", "--short", "HEAD", check=False)
if branch.returncode or branch.stdout.strip() != "main":
raise UpdateError(
"wrong_branch", "当前不在 main 分支。",
"请先检查并切换分支;本地分支上的修改不会自动合并。",
)
if _git("status", "--porcelain", "--untracked-files=no").stdout.strip():
raise UpdateError(
"local_changes", "插件目录有未提交的代码修改。",
"请先保存、提交或暂存修改;更新不会覆盖这些文件。",
)
old_commit = _git("rev-parse", "HEAD").stdout.strip()
old_requirements = _git("show", "HEAD:requirements.txt", check=False).stdout
fetched = _git("fetch", "--no-tags", RELEASE_REPOSITORY_URL, "main", timeout=90, check=False)
if fetched.returncode:
raise UpdateError(
"fetch_failed", "无法获取发布仓库的 main 分支。",
"检查 git.o1key.com 的网络连接与仓库读取权限,稍后重试。", 503,
)
new_commit = _git("rev-parse", "FETCH_HEAD").stdout.strip()
if old_commit == new_commit:
return {"updated": False, "version": old_commit[:7], "requirements_changed": False}
if _git("merge-base", "--is-ancestor", "HEAD", "FETCH_HEAD", check=False).returncode:
raise UpdateError(
"diverged", "本地提交与发布仓库已分叉,无法自动快进。",
"请手动比较两个分支并合并,不要强制重置本地文件。",
)
new_requirements = _git("show", "FETCH_HEAD:requirements.txt", check=False).stdout
merged = _git("merge", "--ff-only", "FETCH_HEAD", check=False)
if merged.returncode:
raise UpdateError(
"merge_blocked", "更新被本地文件阻止。",
"检查是否有与新版本重名的未跟踪文件,保留文件后手动处理。",
)
requirements_changed = old_requirements != new_requirements
return {
"updated": True,
"version": new_commit[:7],
"requirements_changed": requirements_changed,
}