12 KiB
打包与分发
T-524 目标:先把当前 Windows 桌面工具打成免安装 onedir
.exe,方便第一版交付使用。暂不做自动更新器、安装器、增量补丁或在线升级。
一、打包前提
- 在 Windows 环境执行。
- Python 环境已能运行源码版
python main.py。 - 打包脚本固定使用 Windows Python Launcher 的
py -3.10,不使用当前 PATH 中的python;正式出包前先确认py -3.10 --version可用。 - 安装运行依赖和打包依赖:
py -3.10 -m pip install -r requirements-build.txt
requirements-build.txt 会先安装 requirements.txt 的运行依赖,再安装 PyInstaller。依赖必须安装到 Python 3.10 环境里,避免 PATH 上的 Python 3.7/3.12/3.14 打出不可比对的包。
二、打包命令
powershell -ExecutionPolicy Bypass -File scripts\build_exe.ps1
脚本会执行:
py -3.10 -m PyInstaller --noconfirm --clean cmshopee.spec
成功后输出:
dist\cmshopee\
cmshopee.exe
_internal\
<PyInstaller 依赖文件和依赖目录>
正式分发入口是 release\cmshopee-<APP_VERSION>-portable.zip。dist\cmshopee\ 只是 PyInstaller 构建中间产物,不直接作为正式发包名称。
当前 requirements-build.txt 锁定 PyInstaller 6.11.1,onedir 产物必须是 cmshopee.exe + _internal\ 集中依赖布局。scripts\build_exe.ps1 会校验 _internal\ 存在;缺失时直接失败,避免把不一致的打包环境误发给用户。
发布包只包含程序文件和依赖文件:
cmshopee\
cmshopee.exe
_internal\
<PyInstaller 依赖文件和依赖目录>
首次运行后才会在同级生成 data\,用于保存用户本地数据。
三、版本号与发布目录
参考 D:\chengma\cmbot 的打包方式,版本控制采用“单一版本源 + 发布目录带版本号”的轻量方案,暂不引入启动器、自动更新或 manifest。
3.1 单一版本源
新增 app/version.py,作为软件名称和版本号的唯一来源:
APP_NAME = "蝦皮圈優化助手"
APP_CODE_NAME = "cmshopee"
APP_VERSION = "0.1.0"
APP_UPDATE_CHECK_URL = "https://cm.833729.com/api/v1/client/releases/latest?platform=windows"
规则:
- 修改版本号只改
app/version.py的APP_VERSION。 - 线上版本检查接口只改
app/version.py的APP_UPDATE_CHECK_URL;当前正式接口为https://cm.833729.com/api/v1/client/releases/latest?platform=windows。如需本地开发临时跳过启动检查,可把该值置空。 - GUI 窗口标题读取同一版本源,显示为
蝦皮圈優化助手 v0.1.0。 - 打包脚本读取同一版本源生成发布目录、压缩包和
version.txt。 - 禁止在 GUI、构建脚本或文档示例之外重复硬编码不同版本号。
3.2 发布目录结构
scripts\build_exe.ps1 仍先产出 PyInstaller 原始目录 dist\cmshopee\,再组装面向用户分发的 release\ 目录:
release\
cmshopee-0.1.0\
cmshopee.exe
_internal\
<PyInstaller 依赖文件和依赖目录>
version.txt
README.txt
cmshopee-0.1.0-portable.zip
说明:
dist\cmshopee\是构建中间产物,不直接作为正式发包名称。release\cmshopee-<APP_VERSION>\是人工验收和分发目录。release\cmshopee-<APP_VERSION>-portable.zip是交付给用户的便携压缩包。version.txt使用 ASCII/UTF-8 无 BOM 写入APP_VERSION,用于人工排查和未来更新机制读取。README.txt用中文写明启动方式、不要放入Program Files、保留data\、升级时覆盖程序文件但不覆盖data\。
当前 PyInstaller 6.11.1 的 onedir 为集中依赖结构,所以 release\cmshopee-<APP_VERSION>\ 必须包含 cmshopee.exe 和 _internal\,不得只复制单个 exe。
3.3 正式出包流程
- 修改
app/version.py中的APP_VERSION。 - 运行语法检查和单元测试。
- 运行
powershell -ExecutionPolicy Bypass -File scripts\build_exe.ps1。 - 检查
release\cmshopee-<APP_VERSION>\version.txt、GUI 标题栏版本、压缩包文件名三者一致。 - 在无 Python 环境的 Windows 10/11 机器上解压
cmshopee-<APP_VERSION>-portable.zip并启动验证。
正式发布构建固定使用 Python 3.10。源码在 Python 3.7.9 上曾验证可运行,但发布包不再以 3.7.9 作为打包基线;脚本会直接调用 py -3.10 并校验返回版本必须是 3.10.x,避免同一个 APP_VERSION 在不同 Python 版本下打出不可比对的包。CI 仍可继续使用 Python 3.11 做自动测试。
3.4 启动版本检查(T-544 第一版)
T-544 第一版目标是启动时检查是否必须升级,但仍不做自动覆盖升级。
客户端启动流程:
appconfig.prepare_data_dir()成功后、创建MainWindow前,请求app/version.py中APP_UPDATE_CHECK_URL指向的服务器版本接口。- 当前版本从
app/version.py的APP_VERSION读取;APP_UPDATE_CHECK_URL为空时跳过检查并允许进入软件,用于本地开发或尚未配置线上接口的构建。 - 如果服务器明确返回“当前版本必须升级”,弹中文阻断框,不进入主界面。
- 弹窗只提供「下载新版」和「退出程序」。点击「下载新版」用系统浏览器打开下载地址;用户下载后按第六节手动覆盖程序文件。
- 网络失败、接口超时、JSON 非法或字段缺失时,第一版允许进入软件;只记录本地诊断日志或给低打扰提示,避免服务器故障导致所有用户不可用。
建议版本接口返回结构:
{
"latest_version": "0.1.1",
"min_supported_version": "0.1.1",
"force_update": true,
"download_url": "https://example.com/cmshopee-0.1.1-portable.zip",
"sha256": "optional-release-zip-sha256",
"message": "发现必须升级的新版本,请下载后覆盖当前程序文件,保留 data 目录。"
}
客户端同时兼容当前线上接口返回结构:
{
"platform": "windows",
"release": {
"version": "0.1.0",
"download_url": "https://example.com/cmshopee-0.1.0-portable.zip",
"sha256": "",
"release_notes": "发布说明"
}
}
映射规则:release.version 作为 latest_version,release.download_url 作为下载地址,release.sha256 作为校验值,release.release_notes 作为弹窗说明。若该结构未返回 min_supported_version 或 force_update=true,客户端只记录可用新版本信息,不会阻断启动。
客户端判定规则:
APP_VERSION < min_supported_version:必须升级。force_update=true且APP_VERSION < latest_version:必须升级。- 只比较语义化数字段,不能用字符串字典序比较版本号。
download_url为空时不能进入自动下载;弹窗提示联系管理员或查看发布地址。
第一版明确不做:
- 不自动下载并覆盖正在运行的
cmshopee.exe。 - 不自动覆盖
_internal\。 - 不删除、不覆盖、不合并
data\。 - 不做 Launcher、后台替换、增量补丁、签名校验或失败回滚。
原因:Windows 下运行中的 cmshopee.exe 和 PyInstaller onedir 依赖目录很容易出现文件占用、半覆盖失败、权限不足或杀毒拦截。第一版只做“强制提示 + 下载新版 + 用户手动覆盖”,和当前便携包更新方式一致。
3.5 暂不引入自动覆盖升级
本阶段不迁移 cmbot 的 Launcher.exe、manifest.json、SHA-256 下载校验、自动替换程序目录或增量补丁。原因:
- 当前用户已验证“拷贝发布目录到无 Python 环境运行”的第一版交付路径。
cmshopee刚完成data\数据隔离,先把手动发版和版本号一致性做稳。- 自动更新需要安装根可写、下载暂存、目录切换、回滚和安全校验,属于独立后续任务,不能混入当前打包版本号控制。
后续如果要做真正自动覆盖升级,再另起任务,参考 cmbot 的 Launcher.exe + app\ + manifest.json + sha256 + version.txt 设计。
四、绝不打包的本地数据
发布包里不能包含以下本地数据、密钥、业务数据或登录态:
config.jsonconfig/ai_models.jsoncmshopee.db、cmshopee.db-wal、cmshopee.db-shmdb.sqlitechrome_user_data_dir/images/logs/prompts/title_prompt.txtdata/- 运营填写后的 Excel 文件
cmshopee.spec 不声明任何 datas;scripts/build_exe.ps1 会在打包后检查 dist\cmshopee\,如果发现上述路径会直接失败。
五、首次运行与本地数据位置
T-538 后,打包版不再把全进程工作目录切到 cmshopee.exe 所在目录;路径由 app/appconfig.py 按显式数据根解析。
首次运行时,程序会在 exe 同级创建单独的 data\ 子目录,并把所有用户本地数据放进去:
cmshopee\
cmshopee.exe
_internal\
<PyInstaller 依赖文件和依赖目录>
data\
config.json
config\
ai_models.json
cmhub.json
cmshopee.db
chrome_user_data_dir\
images\
logs\
prompts\
title_prompt.txt
源码运行时同理使用项目根目录下的 data\。config.json 内的 user_data_root、image_dir、db_path 默认仍保存为 chrome_user_data_dir、images、cmshopee.db 等相对值,运行时再解析到 data\ 下,保持便携。
这些文件属于用户本地数据,不随新版本程序包覆盖。
旧布局迁移
如果用户从 T-524 旧包升级,新版首次启动会检查 exe 顶层是否存在旧布局数据,例如 config.json、config\、cmshopee.db、chrome_user_data_dir\、images\、logs\、prompts\、title_prompt.txt。若 data\ 中没有同名目标,程序会自动移动到 data\ 下。
如果旧布局和 data\ 中同时存在同名数据,程序不会覆盖,会以“数据迁移冲突”提示用户先手动合并或备份,避免误丢账号、任务、图片或登录态。此类冲突不是目录不可写,不应直接归类为“数据目录不可写”。
启动时会检测 data\ 是否可写;如果程序放在 Program Files 等只读目录导致写入失败,才会以“数据目录不可写”提示“请把程序放到可写目录,勿放 Program Files”并退出。
六、用户后续更新方式
第一版不做自动覆盖升级。给用户发新版本时,或 T-544 启动检查弹出“必须升级”时:
- 让用户先关闭 cmshopee。
- 建议用户备份当前整个程序文件夹。
- 解压新版
release\cmshopee-<APP_VERSION>-portable.zip。 - 覆盖新版程序文件和依赖文件。当前 PyInstaller 6.11.1 是
cmshopee.exe+_internal\onedir,不能只覆盖cmshopee.exe;应把新版cmshopee.exe、_internal\、version.txt、README.txt等程序文件整体覆盖到旧程序目录。 - 保留旧目录里的
data\,不要删除、覆盖或合并它。
如果用户把整个旧目录删除再放新版,data\ 里的账号、任务记录、图片和登录态也会一起丢失,只能从备份恢复。
七、验证清单
打包前后至少执行:
py -3.10 -m compileall app main.py
py -3.10 -m unittest discover -s tests
powershell -ExecutionPolicy Bypass -File scripts\build_exe.ps1
打包成功后确认:
dist\cmshopee\cmshopee.exe存在。- 当前 PyInstaller 6.11.1 下
dist\cmshopee\_internal\必须存在。 dist\cmshopee\中没有第四节列出的本地数据,尤其不能含data\。release\cmshopee-<APP_VERSION>\version.txt、GUI 标题栏版本、压缩包文件名三者一致。- 在干净目录首次启动时能生成
data\config.json并进入 GUI。 - 在目标 Windows 10/11 机器或虚拟机上启动 release exe 后,主窗口标题栏完整可见,左边缘不出屏,用户能用标题栏拖动窗口;小分辨率环境不得出现窗口卡在左上角且标题栏不可拖动的问题(见 T-541)。
涉及 Shopee/CDP 的真实更新能力,仍按任务文档要求用测试商品做人工回归;打包任务本身不新增自动绕过登录、验证码或风控的能力。