feat: 构建号按版本号(App_Ver)独立记录,避免回退旧版本号被 App Store 拒
将 versions.build_ver 单值改为 build_map(每个 App_Ver 独立记录已用到的最大 构建号)。App Store 的构建号唯一性按 MARKETING_VERSION 分别计算,改为单一全局 计数器时回退到打过包的旧版本号会重复(如 2.195.0 已到 .5,切 2.196.0 后再回退, 重置/沿用全局计数都会 < .5 而被拒)。 - config.py: 新增 _ensure_versions 迁移旧 build_ver → build_map;PUT /versions 不再重置构建号,改版本号仅切换当前 App_Ver,并支持可选手动设置 build_ver; GET /versions 返回 build_map 及当前版本号对应的 build_ver - build_service.py: App_Store 打包时在 build_map[app_ver] 自身上 +1 并回写 - ConfigView.vue: 打包设置页显示可编辑的 Build_Ver,修改 App_Ver 时自动切换为 该版本号已记录的构建号 - 迁移 config.json;更新前后端相关测试 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b6e56f5f9a
commit
91e9b027e8
@@ -172,7 +172,8 @@ def test_update_build_settings(client, tmp_config):
|
||||
|
||||
# ---- Versions ----
|
||||
|
||||
def test_update_versions_resets_build_number(client, tmp_config):
|
||||
def test_update_versions_keeps_per_version_build_number(client, tmp_config):
|
||||
# 首次设置某版本号,构建号从 .0 起(尚未打包)
|
||||
resp = client.put("/api/config/versions", json={"app_ver": "2.196.0"})
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["app_ver"] == "2.196.0"
|
||||
@@ -180,6 +181,22 @@ def test_update_versions_resets_build_number(client, tmp_config):
|
||||
assert client.get("/api/config/versions").json()["build_ver"] == "2.196.0.0"
|
||||
|
||||
|
||||
def test_update_versions_does_not_reset_used_build_number(client, tmp_config):
|
||||
# 模拟 2.195.0 已打到 .5、并切到 2.196.0 后,再回退到 2.195.0
|
||||
import json
|
||||
with open(tmp_config, "r", encoding="utf-8") as f:
|
||||
cfg = json.load(f)
|
||||
cfg["versions"] = {"app_ver": "2.196.0", "build_map": {"2.195.0": 5, "2.196.0": 3}}
|
||||
with open(tmp_config, "w", encoding="utf-8") as f:
|
||||
json.dump(cfg, f)
|
||||
|
||||
resp = client.put("/api/config/versions", json={"app_ver": "2.195.0"})
|
||||
assert resp.status_code == 200
|
||||
# 回退到旧版本号时,构建号保留其自身已用到的最大值,不被重置
|
||||
assert resp.json()["build_ver"] == "2.195.0.5"
|
||||
assert client.get("/api/config/versions").json()["build_ver"] == "2.195.0.5"
|
||||
|
||||
|
||||
def test_update_versions_rejects_invalid_app_version(client, tmp_config):
|
||||
resp = client.put("/api/config/versions", json={"app_ver": "2.196"})
|
||||
assert resp.status_code == 400
|
||||
|
||||
@@ -339,6 +339,31 @@ async def test_generate_config_uses_saved_version(tmp_path, log_streamer):
|
||||
assert result["BUILD_VERSION"] == "3.0.1.0"
|
||||
|
||||
|
||||
async def test_generate_config_appstore_increments_per_version(tmp_path, log_streamer):
|
||||
"""App_Store 打包时,按版本号在其自身已用构建号上 +1(回退旧版本号亦从自身最大值继续)"""
|
||||
build_dir = tmp_path / "build"
|
||||
build_dir.mkdir()
|
||||
|
||||
task = MagicMock(app_id="1", scheme_id="1", build_type="App_Store", obfuscation=False)
|
||||
|
||||
# 2.195.0 已打到 .5,切到 2.196.0 后又回退到 2.195.0
|
||||
mock_config = {
|
||||
"apps": {"1": {"name": "App", "certificates": {}}},
|
||||
"schemes": {"1": {"name": "sch", "ossFloder": "f"}},
|
||||
"versions": {"app_ver": "2.195.0", "build_map": {"2.195.0": 5, "2.196.0": 3}},
|
||||
}
|
||||
|
||||
with patch("backend.routers.config.load_config", return_value=mock_config), \
|
||||
patch("backend.routers.config.save_config") as save_mock:
|
||||
result = await generate_config("t1", task, build_dir)
|
||||
|
||||
# 从 2.195.0 自身的 5 继续到 6,不受 2.196.0 影响,也不撞已传的 .5
|
||||
assert result["BUILD_VERSION"] == "2.195.0.6"
|
||||
assert mock_config["versions"]["build_map"]["2.195.0"] == 6
|
||||
assert mock_config["versions"]["build_map"]["2.196.0"] == 3
|
||||
save_mock.assert_called()
|
||||
|
||||
|
||||
async def test_generate_config_uses_server_theme_not_source_autopacking(tmp_path, log_streamer):
|
||||
"""Web 打包不读取分支源码中的 AutoPacking 目录。"""
|
||||
build_dir = tmp_path / "build"
|
||||
|
||||
Reference in New Issue
Block a user