mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-19 09:30:44 +00:00
1.6.1:常规发布
- 版本号 1.6.1 -> 1.6.1 - 重建三端并打包 - 关键测试全过
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
r"""一条命令完成发布。
|
||||
|
||||
用法:
|
||||
python _build/release.py 1.7.0 # 升版本 + 构建 + 打包 + 推送 + 建发行版
|
||||
python _build/release.py 1.7.0 --no-readme # 明说这版没改 README
|
||||
|
||||
它干这些事:
|
||||
1. 升版本号(三端 + 文档 + 测试断言)
|
||||
2. 重建 EXE 和 APK
|
||||
3. 打三个成品
|
||||
4. 跑一遍关键测试
|
||||
5. git 提交 + 推送
|
||||
6. 在 Gitee 建发行版,把三个文件传上去
|
||||
7. 覆盖仓库简介(只在第一次需要,重复设成一样也无害)
|
||||
|
||||
令牌从 _build/.gitee_token 读(那个文件在 .gitignore 里,不会进仓库)。
|
||||
第一次用:把令牌写进去就行。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
|
||||
TOKEN_FILE = ROOT / "_build" / ".gitee_token"
|
||||
GIT = r"C:\Program Files\Git\bin\git.exe"
|
||||
GIT_SSH = r"C:\Program Files\Git\usr\bin\ssh.exe"
|
||||
|
||||
|
||||
def sh(args, cwd=ROOT, check=False, timeout=1800, env=None):
|
||||
merged = dict(os.environ)
|
||||
if env:
|
||||
merged.update(env)
|
||||
proc = subprocess.run(args, cwd=cwd, capture_output=True, text=True,
|
||||
encoding="utf-8", errors="replace", timeout=timeout,
|
||||
env=merged)
|
||||
if check and proc.returncode != 0:
|
||||
raise RuntimeError(f"{args[0]} 失败:{proc.stdout}\n{proc.stderr}")
|
||||
return proc
|
||||
|
||||
|
||||
def step(n, title):
|
||||
print()
|
||||
print(f" {'=' * 56}")
|
||||
print(f" {n}. {title}")
|
||||
print(f" {'=' * 56}")
|
||||
|
||||
|
||||
def read_current_version() -> str:
|
||||
text = (ROOT / "_build" / "package_remote.py").read_text(encoding="utf-8")
|
||||
for line in text.splitlines():
|
||||
if line.startswith("VERSION = "):
|
||||
return line.split('"')[1]
|
||||
return "0.0.0"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) < 2:
|
||||
print(" 用法: python _build/release.py <新版本号>")
|
||||
print(f" 当前版本: {read_current_version()}")
|
||||
return 1
|
||||
|
||||
new_version = sys.argv[1]
|
||||
old_version = read_current_version()
|
||||
note_readme = "--no-readme" in sys.argv
|
||||
|
||||
if not TOKEN_FILE.is_file():
|
||||
print(f" [失败] 找不到令牌文件 {TOKEN_FILE}")
|
||||
print(" 把 Gitee 令牌写进那个文件(一行,别加引号)")
|
||||
return 1
|
||||
token = TOKEN_FILE.read_text(encoding="utf-8").strip()
|
||||
if len(token) < 20:
|
||||
print(f" [失败] 令牌看起来不对(长度 {len(token)})")
|
||||
return 1
|
||||
|
||||
print(f" 发布 {old_version} -> {new_version}")
|
||||
print(f" README: {'这次改了' if note_readme else '没改'}")
|
||||
|
||||
# ---- 1. 升版本 ----
|
||||
step(1, "升版本号")
|
||||
proc = sh([sys.executable, "_build/bump_version_generic.py",
|
||||
old_version, new_version])
|
||||
print(proc.stdout[-1200:])
|
||||
if proc.returncode != 0:
|
||||
print(proc.stderr[-500:])
|
||||
return 1
|
||||
|
||||
# ---- 2. 重建 ----
|
||||
step(2, "重建 EXE 和 APK")
|
||||
sh([GIT, "--version"]) # 探活,无关紧要
|
||||
for args in (["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass",
|
||||
"-File", "android\\build_apk.ps1"],
|
||||
["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass",
|
||||
"-File", "windows\\build_exe.ps1"]):
|
||||
proc = sh(args, timeout=2400)
|
||||
tail = (proc.stdout or "").strip().splitlines()[-2:]
|
||||
for line in tail:
|
||||
print(f" {line}")
|
||||
if proc.returncode != 0:
|
||||
print(f" [失败] {args[-1]}")
|
||||
print((proc.stderr or "")[-600:])
|
||||
return 1
|
||||
|
||||
# ---- 3. 打包 ----
|
||||
step(3, "打三个成品")
|
||||
proc = sh([sys.executable, "_build/package_remote.py"])
|
||||
print(proc.stdout[-1400:])
|
||||
if proc.returncode != 0:
|
||||
return 1
|
||||
|
||||
# ---- 4. 关键测试 ----
|
||||
step(4, "跑关键测试")
|
||||
for test in ("audit_encoding.py", "test_net_tune.py", "test_chunked_body.py",
|
||||
"test_admin_js.py"):
|
||||
proc = sh([sys.executable, "-u", f"_tests/{test}"], timeout=900)
|
||||
# 用退出码判断 —— 各测试的输出格式不一样
|
||||
# (有的打"失败 0 项",有的打"结论:JS 合法",字符串匹配会误判)
|
||||
bad = proc.returncode != 0
|
||||
print(f" {test:28} {'✗' if bad else '✓'}")
|
||||
if bad:
|
||||
print((proc.stdout or "")[-800:])
|
||||
print((proc.stderr or "")[-400:])
|
||||
return 1
|
||||
proc = sh([sys.executable, "-u", "_tests/test_package_remote.py"],
|
||||
timeout=1800)
|
||||
out = proc.stdout or ""
|
||||
last = [ln for ln in out.splitlines() if "通过" in ln or "失败" in ln]
|
||||
print(f" {'test_package_remote.py':28} "
|
||||
f"{'✓' if proc.returncode == 0 else '✗'} {last[-1] if last else ''}")
|
||||
if proc.returncode != 0:
|
||||
return 1
|
||||
|
||||
# ---- 5. 提交推送 ----
|
||||
step(5, "提交并推送")
|
||||
env = {"GIT_SSH_COMMAND": f'"{GIT_SSH}"'}
|
||||
sh([GIT, "add", "-A"])
|
||||
msg = (f"{new_version}:{'README 与' if note_readme else ''}常规发布\n\n"
|
||||
f"- 版本号 {old_version} -> {new_version}\n"
|
||||
f"- 重建三端并打包\n"
|
||||
f"- 关键测试全过\n")
|
||||
sh([GIT, "commit", "-q", "-m", msg])
|
||||
proc = sh([GIT, "push", "origin", "main"], env=env, timeout=1800)
|
||||
print(f" {proc.stdout.strip()[-300:]}")
|
||||
if proc.returncode != 0:
|
||||
print(proc.stderr[-600:])
|
||||
return 1
|
||||
|
||||
# ---- 6. 发行版 ----
|
||||
step(6, "建 Gitee 发行版")
|
||||
proc = sh([sys.executable, "_build/gitee_release.py", token, new_version],
|
||||
timeout=2400)
|
||||
print(proc.stdout[-1200:])
|
||||
if proc.returncode != 0:
|
||||
print(proc.stderr[-600:])
|
||||
return 1
|
||||
|
||||
print()
|
||||
print(f" ✓ {new_version} 发布完成")
|
||||
print(f" https://gitee.com/xmz7891/ykxmz/releases/tag/v{new_version}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user