feat: 上架版本号按分支拆分,master / develop 各自独立
原来 master 与 develop 共用一条 release 轨,版本号和构建号绑在一起。 现改为每个上架分支各有一条轨道(轨道名即分支名),自测分支仍共用 feature 轨。 - 轨道记录新增 kind(release/feature),branch_track 存轨道名 - 旧的共用 release 轨及更早的单轨结构,加载时自动按上架分支拆开, 已用构建号原样复制,拆分后各分支从原来的号继续递增 - 构建号递增时跨上架轨取同一 App_Ver 的最大值 +1:App Store 的构建号 唯一性按 MARKETING_VERSION 全局判定,避免两分支同版本号时重号被拒 - 分支管理页轨道选择改为「上架(本分支独立版本号)/ 自测(共用)」, 打包设置页按上架分支分块填写版本号 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BJaZ913U5GVdTkYHiRpvDU
This commit is contained in:
+208
-75
@@ -93,74 +93,128 @@ DEFAULT_SERVERS = {
|
||||
|
||||
DEFAULT_APP_VER = "2.180.0"
|
||||
|
||||
# 版本轨道:上架分支(master/develop)共用 release,自测分支(feature/*)用 feature。
|
||||
# 两条轨道的 App_Ver 各自独立填写,互不影响。
|
||||
TRACK_RELEASE = "release"
|
||||
TRACK_FEATURE = "feature"
|
||||
TRACKS = (TRACK_RELEASE, TRACK_FEATURE)
|
||||
# 版本轨道:每个上架分支(master / develop / release-* 等)各有一条独立轨道,
|
||||
# 轨道名即分支名,App_Store 打包时构建号自增;所有自测分支共用一条 feature 轨,
|
||||
# 构建号永不自增。各轨道的 App_Ver 互不影响。
|
||||
KIND_RELEASE = "release"
|
||||
KIND_FEATURE = "feature"
|
||||
TRACK_FEATURE = "feature" # 自测轨的固定轨道名
|
||||
LEGACY_RELEASE_TRACK = "release" # 旧版 master/develop 共用的上架轨,迁移时按分支拆开
|
||||
|
||||
# 按名字推断轨道的默认规则;config["branch_track"] 中的显式配置优先。
|
||||
RELEASE_BRANCH_NAMES = {"master", "main", "develop", "dev"}
|
||||
RELEASE_BRANCH_PREFIXES = ("release/", "release-", "hotfix/", "hotfix-")
|
||||
|
||||
|
||||
def _default_track_for_branch(branch: str) -> str:
|
||||
"""按分支名推断所属版本轨道。"""
|
||||
def _is_release_branch(branch: str) -> bool:
|
||||
"""按分支名推断是否为上架分支。"""
|
||||
name = (branch or "").strip().lower()
|
||||
if name in RELEASE_BRANCH_NAMES or name.startswith(RELEASE_BRANCH_PREFIXES):
|
||||
return TRACK_RELEASE
|
||||
return TRACK_FEATURE
|
||||
return name in RELEASE_BRANCH_NAMES or name.startswith(RELEASE_BRANCH_PREFIXES)
|
||||
|
||||
|
||||
def _new_track(app_ver: str = DEFAULT_APP_VER) -> dict:
|
||||
def _release_track_name(branch: str) -> str:
|
||||
"""上架轨道名即分支名;与固定的自测轨重名时加前缀避让。"""
|
||||
return f"release:{branch}" if branch == TRACK_FEATURE else branch
|
||||
|
||||
|
||||
def _default_track_for_branch(branch: str) -> str:
|
||||
"""按分支名推断所属版本轨道名。"""
|
||||
return _release_track_name(branch) if _is_release_branch(branch) else TRACK_FEATURE
|
||||
|
||||
|
||||
def _new_track(app_ver: str = DEFAULT_APP_VER, kind: str = KIND_RELEASE) -> dict:
|
||||
# 每个版本号(App_Ver)独立记录已用到的最大构建号第四位。
|
||||
# App Store 的构建号唯一性按 MARKETING_VERSION(即完整 App_Ver) 分别计算,
|
||||
# 因此必须按版本号分别记录,回退到旧版本号时才能从它自己的最大值继续递增。
|
||||
return {"app_ver": app_ver, "build_map": {}}
|
||||
return {"kind": kind, "app_ver": app_ver, "build_map": {}}
|
||||
|
||||
|
||||
def _seed_release_track(tracks: dict, legacy: dict = None) -> dict:
|
||||
"""新建上架轨的初值:优先沿用旧共用轨(含已用构建号),否则沿用任一上架轨的 App_Ver。"""
|
||||
if legacy:
|
||||
return {"kind": KIND_RELEASE, "app_ver": legacy["app_ver"], "build_map": dict(legacy["build_map"])}
|
||||
for track in tracks.values():
|
||||
if track.get("kind") == KIND_RELEASE:
|
||||
return _new_track(track.get("app_ver") or DEFAULT_APP_VER)
|
||||
return _new_track()
|
||||
|
||||
|
||||
def _ensure_track(config: dict, track_name: str) -> dict:
|
||||
"""确保轨道存在;新建的上架轨沿用已有上架轨的 App_Ver,构建号从 .0 起。"""
|
||||
tracks = config.setdefault("versions", {}).setdefault("tracks", {})
|
||||
track = tracks.get(track_name)
|
||||
if not isinstance(track, dict):
|
||||
track = tracks[track_name] = (
|
||||
_new_track(kind=KIND_FEATURE) if track_name == TRACK_FEATURE
|
||||
else _seed_release_track(tracks)
|
||||
)
|
||||
return track
|
||||
|
||||
|
||||
def _legacy_single_track(versions: dict) -> dict:
|
||||
"""把最旧的单轨结构读成 {app_ver, build_map}。"""
|
||||
app_ver = versions.get("app_ver") or DEFAULT_APP_VER
|
||||
build_map = versions.get("build_map")
|
||||
if not isinstance(build_map, dict):
|
||||
build_map = {}
|
||||
# 更旧的单值形式 "2.195.0.3" → {"2.195.0": 3}
|
||||
old = versions.get("build_ver")
|
||||
if isinstance(old, str):
|
||||
parts = old.split(".")
|
||||
if len(parts) >= 4 and parts[3].isdigit():
|
||||
build_map[".".join(parts[:3])] = int(parts[3])
|
||||
versions.pop("app_ver", None)
|
||||
versions.pop("build_map", None)
|
||||
versions.pop("build_ver", None)
|
||||
return {"app_ver": app_ver, "build_map": build_map}
|
||||
|
||||
|
||||
def _ensure_versions(config: dict) -> bool:
|
||||
"""确保 versions 为双轨结构,并迁移旧式单轨/单值 build_ver 配置。
|
||||
"""确保 versions 为「每个上架分支一条轨 + 一条 feature 轨」结构,并迁移旧配置。
|
||||
|
||||
旧式 ``{"app_ver": ..., "build_map": ...}`` 整体迁入 release 轨;
|
||||
feature 轨用同一个 App_Ver 初始化,构建号从 .0 起且永不自增。
|
||||
旧式单轨 ``{"app_ver": ..., "build_map": ...}`` 和旧的 master/develop 共用
|
||||
``release`` 轨,都会按上架分支拆成各自独立的轨道,并复制已用构建号,
|
||||
使拆分后每个分支都从原来的构建号继续递增。
|
||||
"""
|
||||
versions = config.get("versions")
|
||||
changed = False
|
||||
|
||||
if not isinstance(versions, dict):
|
||||
config["versions"] = {"tracks": {TRACK_RELEASE: _new_track(), TRACK_FEATURE: _new_track()}}
|
||||
return True
|
||||
|
||||
tracks = versions.get("tracks")
|
||||
if not isinstance(tracks, dict):
|
||||
# 旧式单轨结构 → release 轨
|
||||
legacy_app_ver = versions.get("app_ver") or DEFAULT_APP_VER
|
||||
legacy_build_map = versions.get("build_map")
|
||||
if not isinstance(legacy_build_map, dict):
|
||||
legacy_build_map = {}
|
||||
# 更旧的单值形式 "2.195.0.3" → {"2.195.0": 3}
|
||||
old = versions.get("build_ver")
|
||||
if isinstance(old, str):
|
||||
parts = old.split(".")
|
||||
if len(parts) >= 4 and parts[3].isdigit():
|
||||
legacy_build_map[".".join(parts[:3])] = int(parts[3])
|
||||
versions.pop("app_ver", None)
|
||||
versions.pop("build_map", None)
|
||||
versions.pop("build_ver", None)
|
||||
tracks = {
|
||||
TRACK_RELEASE: {"app_ver": legacy_app_ver, "build_map": legacy_build_map},
|
||||
TRACK_FEATURE: _new_track(legacy_app_ver),
|
||||
}
|
||||
versions["tracks"] = tracks
|
||||
versions = {}
|
||||
config["versions"] = versions
|
||||
changed = True
|
||||
|
||||
for name in TRACKS:
|
||||
track = tracks.get(name)
|
||||
legacy = None # 需要拆分到各上架分支的旧共用轨
|
||||
tracks = versions.get("tracks")
|
||||
if not isinstance(tracks, dict):
|
||||
legacy = _legacy_single_track(versions)
|
||||
tracks = {}
|
||||
versions["tracks"] = tracks
|
||||
changed = True
|
||||
else:
|
||||
# 迁移后的轨道都带 kind;没有 kind 的 release 轨即旧的共用上架轨
|
||||
old = tracks.get(LEGACY_RELEASE_TRACK)
|
||||
if isinstance(old, dict) and "kind" not in old:
|
||||
build_map = old.get("build_map")
|
||||
legacy = {
|
||||
"app_ver": old.get("app_ver") or DEFAULT_APP_VER,
|
||||
"build_map": build_map if isinstance(build_map, dict) else {},
|
||||
}
|
||||
tracks.pop(LEGACY_RELEASE_TRACK)
|
||||
changed = True
|
||||
|
||||
feature = tracks.get(TRACK_FEATURE)
|
||||
if not isinstance(feature, dict):
|
||||
tracks[TRACK_FEATURE] = _new_track((legacy or {}).get("app_ver") or DEFAULT_APP_VER, KIND_FEATURE)
|
||||
changed = True
|
||||
|
||||
for name, track in tracks.items():
|
||||
if not isinstance(track, dict):
|
||||
tracks[name] = _new_track()
|
||||
track = tracks[name] = _new_track()
|
||||
changed = True
|
||||
kind = KIND_FEATURE if name == TRACK_FEATURE else KIND_RELEASE
|
||||
if track.get("kind") != kind:
|
||||
track["kind"] = kind
|
||||
changed = True
|
||||
continue
|
||||
if not track.get("app_ver"):
|
||||
track["app_ver"] = DEFAULT_APP_VER
|
||||
changed = True
|
||||
@@ -168,33 +222,101 @@ def _ensure_versions(config: dict) -> bool:
|
||||
track["build_map"] = {}
|
||||
changed = True
|
||||
|
||||
# 分支归属:只存显式配置,缺省按名字规则推断
|
||||
# 分支归属:值为轨道名,缺省按分支名规则推断
|
||||
branch_track = config.get("branch_track")
|
||||
if not isinstance(branch_track, dict):
|
||||
branch_track = {}
|
||||
config["branch_track"] = branch_track
|
||||
changed = True
|
||||
for branch in config.get("branches", []) or []:
|
||||
if branch_track.get(branch) not in TRACKS:
|
||||
branch_track[branch] = _default_track_for_branch(branch)
|
||||
name = branch_track.get(branch)
|
||||
if name == LEGACY_RELEASE_TRACK and LEGACY_RELEASE_TRACK not in tracks:
|
||||
# 旧的共用上架轨 → 该分支自己的轨
|
||||
name = _release_track_name(branch)
|
||||
if not isinstance(name, str) or not name:
|
||||
name = _default_track_for_branch(branch)
|
||||
if branch_track.get(branch) != name:
|
||||
branch_track[branch] = name
|
||||
changed = True
|
||||
if name not in tracks:
|
||||
tracks[name] = _seed_release_track(tracks, legacy)
|
||||
changed = True
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
def _primary_track_name(config: dict) -> str:
|
||||
"""主上架轨:第一个上架分支所属的轨道;没有上架分支时退回 feature 轨。
|
||||
|
||||
仅用于顶层 app_ver/build_ver 的兼容字段和未指定轨道时的缺省值。
|
||||
"""
|
||||
for branch in config.get("branches", []) or []:
|
||||
name = get_track_name(config, branch)
|
||||
if name != TRACK_FEATURE:
|
||||
return name
|
||||
return TRACK_FEATURE
|
||||
|
||||
|
||||
def get_track_name(config: dict, branch: str) -> str:
|
||||
"""取分支所属的版本轨道名。"""
|
||||
track = (config.get("branch_track") or {}).get(branch)
|
||||
return track if track in TRACKS else _default_track_for_branch(branch)
|
||||
name = (config.get("branch_track") or {}).get(branch)
|
||||
tracks = (config.get("versions") or {}).get("tracks") or {}
|
||||
if isinstance(name, str) and name in tracks:
|
||||
return name
|
||||
if name == LEGACY_RELEASE_TRACK: # 尚未迁移的旧配置
|
||||
return _release_track_name(branch)
|
||||
return _default_track_for_branch(branch)
|
||||
|
||||
|
||||
def get_track(config: dict, track_name: str) -> dict:
|
||||
"""取某条轨道的版本记录(不存在时返回默认值,不写回配置)。"""
|
||||
"""取某条轨道的版本记录副本(不存在时返回默认值;只读,不写回配置)。
|
||||
|
||||
未迁移的旧记录没有 kind,按轨道名补上:只有固定的 feature 轨是自测轨。
|
||||
"""
|
||||
tracks = (config.get("versions") or {}).get("tracks") or {}
|
||||
kind = KIND_FEATURE if track_name == TRACK_FEATURE else KIND_RELEASE
|
||||
track = tracks.get(track_name)
|
||||
if not isinstance(track, dict):
|
||||
return _new_track()
|
||||
return track
|
||||
return _new_track(kind=kind)
|
||||
return {**track, "kind": track.get("kind") or kind}
|
||||
|
||||
|
||||
def is_release_track(track: dict) -> bool:
|
||||
"""该轨道是否为上架轨(App_Store 打包时构建号自增)。"""
|
||||
return track.get("kind", KIND_RELEASE) == KIND_RELEASE
|
||||
|
||||
|
||||
def next_build_no(tracks: dict, app_ver: str) -> int:
|
||||
"""该 App_Ver 下一个可用的构建号。
|
||||
|
||||
构建号唯一性由 App Store 按 MARKETING_VERSION 全局判定,与分支无关,
|
||||
因此取所有上架轨在这个版本号上已用到的最大值再 +1,避免两个上架分支
|
||||
临时使用同一 App_Ver 时产生重复构建号被拒。
|
||||
"""
|
||||
used = [
|
||||
int((track.get("build_map") or {}).get(app_ver, 0))
|
||||
for track in tracks.values()
|
||||
if isinstance(track, dict) and is_release_track(track)
|
||||
]
|
||||
return max(used, default=0) + 1
|
||||
|
||||
|
||||
def resolve_track(config: dict, branch: str, track: str) -> str:
|
||||
"""把用户传入的轨道值解析为轨道名。
|
||||
|
||||
兼容按类型指定:``release`` 表示该分支自己的上架轨,``feature`` 表示共用自测轨;
|
||||
也可直接传已存在的轨道名(多个分支共用同一条版本线)。
|
||||
"""
|
||||
value = (track or "").strip()
|
||||
if not value:
|
||||
return _default_track_for_branch(branch)
|
||||
if value == KIND_FEATURE:
|
||||
return TRACK_FEATURE
|
||||
if value == KIND_RELEASE:
|
||||
return _release_track_name(branch)
|
||||
if value in ((config.get("versions") or {}).get("tracks") or {}):
|
||||
return value
|
||||
raise HTTPException(status_code=400, detail=f"未知的版本轨道: {track}")
|
||||
|
||||
|
||||
def track_build_ver(track: dict) -> str:
|
||||
@@ -203,6 +325,7 @@ def track_build_ver(track: dict) -> str:
|
||||
build_map = track.get("build_map") or {}
|
||||
return f"{app_ver}.{int(build_map.get(app_ver, 0))}"
|
||||
|
||||
|
||||
# 为已有环境迁移的固定前缀;后续环境从配置中的 next_app_id_prefix 自动分配。
|
||||
LEGACY_SERVER_PREFIXES = {
|
||||
"测试环境": 1,
|
||||
@@ -652,43 +775,47 @@ async def get_branches():
|
||||
|
||||
@router.post("/branches")
|
||||
async def add_branch(data: dict):
|
||||
"""新增分支,可指定所属版本轨道(缺省按分支名推断)"""
|
||||
"""新增分支,可指定所属版本轨道(缺省按分支名推断)。
|
||||
|
||||
track 传 release 表示这个分支用自己独立的上架版本号,feature 表示共用自测版本号;
|
||||
也可直接传已有轨道名,让该分支与另一个分支共用同一条版本线。
|
||||
"""
|
||||
name = data.get("name", "").strip()
|
||||
if not name:
|
||||
raise HTTPException(status_code=400, detail="分支名称不能为空")
|
||||
|
||||
track = (data.get("track") or "").strip() or _default_track_for_branch(name)
|
||||
if track not in TRACKS:
|
||||
raise HTTPException(status_code=400, detail=f"未知的版本轨道: {track}")
|
||||
|
||||
async with _config_lock:
|
||||
config = load_config()
|
||||
branches = config.get("branches", ["main"])
|
||||
if name in branches:
|
||||
raise HTTPException(status_code=400, detail="分支已存在")
|
||||
track = resolve_track(config, name, data.get("track"))
|
||||
branches.append(name)
|
||||
config["branches"] = branches
|
||||
config.setdefault("branch_track", {})[name] = track
|
||||
_ensure_track(config, track)
|
||||
save_config(config)
|
||||
return {"message": "分支已添加", "track": track}
|
||||
|
||||
|
||||
@router.put("/branches/track")
|
||||
async def update_branch_track(data: dict):
|
||||
"""修改分支所属的版本轨道(release=上架,feature=自测)。
|
||||
"""修改分支所属的版本轨道(release=该分支独立的上架版本号,feature=共用自测版本号)。
|
||||
|
||||
分支名可能含 /(如 feature/login),因此走请求体而非路径参数。
|
||||
改成 release 时会为这个分支建一条以分支名命名的轨道(初值沿用已有上架轨的 App_Ver),
|
||||
此后它的版本号与其它分支互不影响。分支名可能含 /(如 feature/login),因此走请求体而非路径参数。
|
||||
"""
|
||||
branch = (data.get("branch") or "").strip()
|
||||
track = (data.get("track") or "").strip()
|
||||
if track not in TRACKS:
|
||||
raise HTTPException(status_code=400, detail=f"未知的版本轨道: {track}")
|
||||
if not (data.get("track") or "").strip():
|
||||
raise HTTPException(status_code=400, detail="未指定版本轨道")
|
||||
|
||||
async with _config_lock:
|
||||
config = load_config()
|
||||
if branch not in config.get("branches", []):
|
||||
raise HTTPException(status_code=404, detail="分支不存在")
|
||||
track = resolve_track(config, branch, data.get("track"))
|
||||
config.setdefault("branch_track", {})[branch] = track
|
||||
_ensure_track(config, track)
|
||||
save_config(config)
|
||||
return {"message": "分支版本轨道已更新", "branch": branch, "track": track}
|
||||
|
||||
@@ -755,24 +882,29 @@ async def update_build_settings(settings: BuildConfigUpdate, db: Session = Depen
|
||||
# 版本号配置 API
|
||||
@router.get("/versions")
|
||||
async def get_versions():
|
||||
"""获取两条版本轨道各自的 App_Ver 及其当前构建号。
|
||||
"""获取各条版本轨道的 App_Ver 及其当前构建号。
|
||||
|
||||
每个上架分支(master / develop 等)一条独立轨道,轨道名即分支名;自测分支共用 feature 轨。
|
||||
build_ver 为该轨道当前 App_Ver 已用到的最大构建号(形如 2.195.0.5,尚未打包则 .0),
|
||||
仅供展示;实际递增只发生在 release 轨的 App_Store 打包时,feature 轨永不自增。
|
||||
顶层 app_ver / build_ver 为 release 轨的镜像,保留给旧客户端。
|
||||
仅供展示;实际递增只发生在上架轨的 App_Store 打包时,feature 轨永不自增。
|
||||
顶层 app_ver / build_ver 为主上架轨的镜像,保留给旧客户端。
|
||||
"""
|
||||
config = load_config()
|
||||
tracks = {}
|
||||
for name in TRACKS:
|
||||
track = get_track(config, name)
|
||||
tracks[name] = {
|
||||
tracks = {
|
||||
name: {
|
||||
"kind": KIND_FEATURE if name == TRACK_FEATURE else KIND_RELEASE,
|
||||
"app_ver": track.get("app_ver") or DEFAULT_APP_VER,
|
||||
"build_ver": track_build_ver(track),
|
||||
"build_map": track.get("build_map") or {},
|
||||
}
|
||||
for name, track in ((config.get("versions") or {}).get("tracks") or {}).items()
|
||||
if isinstance(track, dict)
|
||||
}
|
||||
primary = _primary_track_name(config)
|
||||
return {
|
||||
**tracks[TRACK_RELEASE],
|
||||
**{k: v for k, v in tracks.get(primary, {}).items() if k != "kind"},
|
||||
"tracks": tracks,
|
||||
"primary_track": primary,
|
||||
"branch_track": {
|
||||
branch: get_track_name(config, branch)
|
||||
for branch in config.get("branches", []) or []
|
||||
@@ -787,14 +919,12 @@ async def update_versions(data: dict):
|
||||
每个 App_Ver 的构建号在所属轨道内独立保存于 build_map 各自递增,因此来回切换
|
||||
版本号(包括回退到打过包的旧版本号)都不会重复,不会被 App Store 拒绝。
|
||||
|
||||
- track:release(master/develop,上架用)或 feature(自测用),缺省 release。
|
||||
- track:轨道名,上架分支为分支名(如 master、develop),自测为 feature;缺省为主上架轨。
|
||||
- 不传 build_ver:保留该版本号已记录的构建号,仅更新该轨道的当前 App_Ver。
|
||||
- 传 build_ver:形如 2.196.0.3,前三位须与 app_ver 一致,第四位为构建号;
|
||||
直接写入该版本号的记录(可用于手动对齐 App Store Connect 上的已传构建号)。
|
||||
"""
|
||||
track_name = (data.get("track") or TRACK_RELEASE).strip()
|
||||
if track_name not in TRACKS:
|
||||
raise HTTPException(status_code=400, detail=f"未知的版本轨道: {track_name}")
|
||||
track_name = (data.get("track") or "").strip()
|
||||
|
||||
app_ver = data.get("app_ver", "").strip()
|
||||
if not re.fullmatch(r"\d+\.\d+\.\d+", app_ver):
|
||||
@@ -814,7 +944,10 @@ async def update_versions(data: dict):
|
||||
async with _config_lock:
|
||||
config = load_config()
|
||||
tracks = config.setdefault("versions", {}).setdefault("tracks", {})
|
||||
track = tracks.setdefault(track_name, _new_track())
|
||||
track_name = track_name or _primary_track_name(config)
|
||||
if track_name not in tracks:
|
||||
raise HTTPException(status_code=400, detail=f"未知的版本轨道: {track_name}")
|
||||
track = tracks[track_name]
|
||||
track["app_ver"] = app_ver
|
||||
build_map = track.setdefault("build_map", {})
|
||||
if build_no is not None:
|
||||
|
||||
@@ -610,7 +610,7 @@ async def generate_config(task_id: str, task, build_dir: Path) -> dict:
|
||||
|
||||
from ..routers.config import (
|
||||
load_config, _config_lock, get_track, get_track_name, track_build_ver,
|
||||
TRACK_RELEASE, _new_track,
|
||||
is_release_track, next_build_no, _ensure_track,
|
||||
)
|
||||
|
||||
config = load_config()
|
||||
@@ -621,29 +621,29 @@ async def generate_config(task_id: str, task, build_dir: Path) -> dict:
|
||||
scheme = schemes.get(task.scheme_id, {})
|
||||
|
||||
# 版本号由当前服务配置统一管理,不读取分支源码中的手动打包脚本。
|
||||
# 按分支所属轨道取版本号:master/develop 走 release 轨(上架用),feature 走 feature 轨(自测用),
|
||||
# 两条轨道的 App_Ver 各自独立。
|
||||
# 按分支所属轨道取版本号:每个上架分支(master、develop 等)一条独立轨道,
|
||||
# 自测分支共用 feature 轨,各轨道的 App_Ver 互不影响。
|
||||
track_name = get_track_name(config, task.branch)
|
||||
track = get_track(config, track_name)
|
||||
app_ver = track.get("app_ver") or "2.180.0"
|
||||
|
||||
# 构建号按版本号独立记录:build_map[app_ver] 为该版本号已用到的最大第四位。
|
||||
build_ver = track_build_ver(track)
|
||||
is_release = is_release_track(track)
|
||||
await log_streamer.emit(
|
||||
task_id,
|
||||
f"版本轨道: {track_name}({'上架,App_Store 打包自增' if track_name == TRACK_RELEASE else '自测,构建号不自增'})",
|
||||
f"版本轨道: {track_name}({'上架,App_Store 打包自增' if is_release else '自测,构建号不自增'})",
|
||||
)
|
||||
|
||||
# release 轨的 App_Store 打包,在该版本号自己的构建号上 +1
|
||||
# (回退到旧版本号也从它自己的最大值继续);feature 轨始终使用手动设定的构建号。
|
||||
if track_name == TRACK_RELEASE and task.build_type == "App_Store":
|
||||
# 上架轨的 App_Store 打包,在该版本号的构建号上 +1(回退到旧版本号也从它自己的最大值继续);
|
||||
# feature 轨始终使用手动设定的构建号。
|
||||
if is_release and task.build_type == "App_Store":
|
||||
async with _config_lock:
|
||||
config = load_config()
|
||||
tracks = config.setdefault("versions", {}).setdefault("tracks", {})
|
||||
track = tracks.setdefault(track_name, _new_track(app_ver))
|
||||
build_map = track.setdefault("build_map", {})
|
||||
n = int(build_map.get(app_ver, 0)) + 1
|
||||
build_map[app_ver] = n
|
||||
track = _ensure_track(config, track_name)
|
||||
track.setdefault("app_ver", app_ver)
|
||||
n = next_build_no(config["versions"]["tracks"], app_ver)
|
||||
track.setdefault("build_map", {})[app_ver] = n
|
||||
build_ver = f"{app_ver}.{n}"
|
||||
|
||||
from ..routers.config import save_config
|
||||
|
||||
Reference in New Issue
Block a user