feat: 构建超时控制、日志持久化、任务删除、pod install 及多项 UI 优化

- 新增 BUILD_TIMEOUT_HOURS 配置,超时自动标记失败
- 日志保存到独立 backend/logs/ 目录,不随构建目录删除
- 新增任务删除 API 及前端删除按钮
- 构建流程增加 pod install 步骤
- 通过文件传递配置避免命令行参数截断
- Provisioning Profile 支持按名称搜索
- dSYM 下载支持目录打包为 zip
- 前端端口可配置、历史页增加下载列和耗时显示
- 日志弹窗支持展开/收起详细日志
- 自动生成 upload_key 标识
This commit is contained in:
shen
2026-06-08 18:56:43 +08:00
parent 75363ee276
commit f5919a8229
11 changed files with 535 additions and 212 deletions
+19
View File
@@ -64,6 +64,17 @@ DEFAULT_SERVERS = {
}
def _ensure_upload_keys(config: dict) -> bool:
"""为没有 upload_key 的 app 自动生成,返回是否有变更"""
import uuid
changed = False
for app_id, app in config.get("apps", {}).items():
if not app.get("upload_key"):
app["upload_key"] = uuid.uuid4().hex[:8]
changed = True
return changed
def load_config() -> dict:
"""读取 config.json"""
if not CONFIG_JSON_PATH.exists():
@@ -77,6 +88,9 @@ def load_config() -> dict:
config["branches"] = ["main"]
if "upload" not in config:
config["upload"] = DEFAULT_UPLOAD
# 自动为缺少 upload_key 的 app 生成唯一标识
if _ensure_upload_keys(config):
save_config(config)
return config
@@ -119,6 +133,7 @@ async def get_apps():
@router.post("/apps")
async def create_app(app: dict):
"""新增 app"""
import uuid
async with _config_lock:
config = load_config()
apps = config.get("apps", {})
@@ -127,6 +142,10 @@ async def create_app(app: dict):
numeric_keys = [int(k) for k in apps.keys() if k.isdigit()]
new_id = str(max(numeric_keys) + 1) if numeric_keys else "1"
# 自动生成 upload_key
if not app.get("upload_key"):
app["upload_key"] = uuid.uuid4().hex[:8]
apps[new_id] = app
config["apps"] = apps
save_config(config)