feat: 根据应用版本自动重置构建版本

This commit is contained in:
shenlei 2026-07-20 16:03:59 +09:00
parent 89fb633b00
commit 8747792a4b
5 changed files with 32 additions and 20 deletions

View File

@ -2,6 +2,7 @@
import asyncio
import json
import os
import re
import shutil
import zipfile
from datetime import datetime
@ -501,19 +502,18 @@ async def get_versions():
@router.put("/versions")
async def update_versions(data: dict):
"""更新 App_Ver 和 Build_Ver"""
"""更新 App_Ver,并将 Build_Ver 重置为对应的 .0。"""
app_ver = data.get("app_ver", "").strip()
build_ver = data.get("build_ver", "").strip()
if not app_ver or not build_ver:
raise HTTPException(status_code=400, detail="版本号不能为空")
if not re.fullmatch(r"\d+\.\d+\.\d+", app_ver):
raise HTTPException(status_code=400, detail="App_Ver 必须为主版本.次版本.修订号,例如 2.196.0")
build_ver = f"{app_ver}.0"
async with _config_lock:
config = load_config()
config["versions"] = {
"app_ver": app_ver,
"build_ver": build_ver,
}
async with _config_lock:
save_config(config)
return {"message": "版本号已更新", "app_ver": app_ver, "build_ver": build_ver}

View File

@ -181,6 +181,6 @@ describe('ConfigView.vue', () => {
expect(wrapper.text()).toContain('应用版本号')
expect(wrapper.text()).not.toContain('打包参数')
expect(wrapper.findAll('input').length).toBe(2)
expect(wrapper.findAll('input').length).toBe(1)
})
})

View File

@ -273,11 +273,7 @@
<input type="text" v-model="versions.app_ver" placeholder="2.180.0">
<div style="font-size: 12px; color: #999; margin-top: 4px;">格式主版本.次版本.修订号</div>
</div>
<div class="form-group">
<label>Build_Ver构建版本</label>
<input type="text" v-model="versions.build_ver" placeholder="2.180.0.0">
<div style="font-size: 12px; color: #999; margin-top: 4px;">格式主版本.次版本.修订号.构建号App_Store 打包时构建号自动 +1</div>
</div>
<div style="font-size: 12px; color: #999; margin: -8px 0 16px;">保存后 Build_Ver 将自动重置为 App_Ver.0App Store 打包时构建号自动 +1</div>
<button class="btn btn-primary" style="width: auto; padding: 10px 32px; margin-bottom: 24px;" @click="saveVersions">保存版本号</button>
<template v-if="isAdmin">
@ -1037,7 +1033,7 @@ const saveVersions = async () => {
const res = await authFetch('/api/config/versions', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(versions.value),
body: JSON.stringify({ app_ver: versions.value.app_ver }),
})
if (res.ok) {
const data = await res.json()

View File

@ -144,3 +144,19 @@ def test_update_build_settings(client, tmp_config):
resp = client.put("/api/config/build", json={"max_concurrent_builds": 4})
assert resp.status_code == 200
assert client.get("/api/config/build").json()["max_concurrent_builds"] == 4
# ---- Versions ----
def test_update_versions_resets_build_number(client, tmp_config):
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"
assert resp.json()["build_ver"] == "2.196.0.0"
assert client.get("/api/config/versions").json()["build_ver"] == "2.196.0.0"
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
assert "App_Ver" in resp.json()["detail"]

View File

@ -56,9 +56,9 @@ def test_config_routes_limit_regular_users_to_apps_and_versions(client, tmp_conf
assert client.get("/api/config/apps", headers=headers).status_code == 200
assert client.post("/api/config/apps", json={"name": "普通用户 App"}, headers=headers).status_code == 200
assert client.get("/api/config/versions", headers=headers).status_code == 200
assert client.put("/api/config/versions", json={
"app_ver": "2.196.0", "build_ver": "2.196.0.0",
}, headers=headers).status_code == 200
versions = client.put("/api/config/versions", json={"app_ver": "2.196.0"}, headers=headers)
assert versions.status_code == 200
assert versions.json()["build_ver"] == "2.196.0.0"
assert client.get("/api/config", headers=headers).status_code == 403
assert client.get("/api/config/servers", headers=headers).status_code == 403
assert client.put("/api/config/build", json={"max_concurrent_builds": 1}, headers=headers).status_code == 403