#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 组装 DLPilot 发布包: exe + 附属资产 → 一个文件夹 + 一个 zip(解压即用) ================================================================ 先把 assets/ 的图案复制进 release/(与 exe 平铺), 使 release/ 本身就是 可直接使用的完整文件夹; 再原样压成 zip —— 两者内容始终一致。 zip 解压后根目录为 DLPilot/, 与 exe 运行目录结构一致: DLPilot.exe 主程序(先运行 build_exe.py 打包) pattern_slots.json 预置自定义栏位(指向前 3 张 bw 图案) bw_*.png 640x360 黑白测试图 ×5(自定义栏位用) solid_*.png 800x600 纯色测试图 ×10(RGB 位交换测试用) README.md 使用说明 用法: python package_release.py 版本号自动取最近 git tag(DLPilot-v*) python package_release.py 0.1.0 手动指定版本号 产物: release/DLPilot-v<版本>-win64.zip(zip 不入库, 上传到 Gitea Release) """ import os import re import shutil import subprocess import sys import zipfile SRC = os.path.dirname(os.path.abspath(__file__)) BASE = os.path.dirname(SRC) RELEASE = os.path.join(BASE, 'release') ASSETS = os.path.join(BASE, 'assets') PATTERN_GLOBS = ('bw_*.png', 'solid_*.png') def detect_version(): """从最近的 DLPilot-v* tag 推断版本号, 无 tag 则报错提示手动指定""" try: out = subprocess.check_output( ['git', 'describe', '--tags', '--abbrev=0', '--match', 'DLPilot-v*'], cwd=BASE, stderr=subprocess.DEVNULL) return out.decode().strip().removeprefix('DLPilot-v') except Exception: sys.exit('未能从 git tag 推断版本号, 请手动指定: python package_release.py <版本号>') def main(): version = (sys.argv[1] if len(sys.argv) > 1 else detect_version()).lstrip('v') exe = os.path.join(RELEASE, 'DLPilot.exe') slots = os.path.join(RELEASE, 'pattern_slots.json') readme = os.path.join(BASE, 'README.md') if not os.path.exists(exe): sys.exit('缺少 release/DLPilot.exe, 先运行: python build_exe.py') for must in (slots, readme): if not os.path.exists(must): sys.exit(f'缺少 {must}') # 依 pattern_slots.json 校验栏位引用的图片都在 assets/ 里 slot_files = re.findall(r'"file":\s*"([^"]+)"', open(slots, encoding='utf-8').read()) patterns = sorted(p for g in PATTERN_GLOBS for p in os.listdir(ASSETS) if re.fullmatch(g.replace('*', '.*'), p)) for f in slot_files: if f not in patterns: sys.exit(f'pattern_slots.json 引用的 {f} 不在 assets/ 中') # 图案复制进 release/, 与 exe 平铺 -> release/ 即完整可用的发布文件夹 for p in patterns: shutil.copy2(os.path.join(ASSETS, p), os.path.join(RELEASE, p)) shutil.copy2(readme, os.path.join(RELEASE, 'README.md')) zip_name = f'DLPilot-v{version}-win64.zip' zip_path = os.path.join(RELEASE, zip_name) with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as z: for p in ['DLPilot.exe', 'pattern_slots.json', 'README.md'] + patterns: z.write(os.path.join(RELEASE, p), f'DLPilot/{p}') print(f'发布文件夹: {RELEASE} (exe+配置+说明+{len(patterns)} 张图案, 平铺即用)') print(f'发布包: {zip_path} ({os.path.getsize(zip_path) / 1024 / 1024:.1f} MB)') print('下一步上传: python publish_gitea.py', zip_name) if __name__ == '__main__': main()