Skip to content

Commit 6823f97

Browse files
authored
Merge pull request #2124 from Websoft9/feature/appstore-publish-migration
fix
2 parents 4183285 + 43f56a4 commit 6823f97

3 files changed

Lines changed: 51 additions & 41 deletions

File tree

-115 Bytes
Binary file not shown.

build/library_publish.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ def format_dataset_version(dt: datetime) -> str:
8080
def resolve_from_version(from_ref: str | None) -> str:
8181
if not from_ref:
8282
return "initial"
83-
timestamp = run_git("show", "-s", "--format=%cI", from_ref)
84-
return format_dataset_version(datetime.fromisoformat(timestamp.replace("Z", "+00:00")))
83+
return run_git("rev-parse", "--short=16", from_ref)
8584

8685

8786
def load_library_json(library_version: str | None) -> dict:
@@ -309,11 +308,12 @@ def build_library_manifest(
309308
}
310309

311310

312-
def build_catalog_manifest(dataset_version: str, checksum_names: dict, generated_at: str) -> dict:
311+
def build_catalog_manifest(dataset_version: str, checksum_names: dict, generated_at: str, full_package_name: str) -> dict:
313312
return {
314313
"schemaVersion": "1",
315314
"datasetVersion": dataset_version,
316315
"source": "contentful",
316+
"fullPackage": full_package_name,
317317
"files": {
318318
"catalogEn": "catalog_en.json",
319319
"catalogZh": "catalog_zh.json",
@@ -405,6 +405,9 @@ def validate_catalog_artifacts(output_dir: Path, manifest: dict) -> None:
405405
raise SystemExit(f"missing catalog checksum: {checksum_name}")
406406
if not (output_dir / "manifest.json").exists():
407407
raise SystemExit("missing catalog manifest.json")
408+
full_pkg = manifest.get("fullPackage")
409+
if full_pkg and not (output_dir / full_pkg).exists():
410+
raise SystemExit(f"missing catalog full package: {full_pkg}")
408411

409412

410413
def validate_library_artifacts(output_dir: Path, manifest: dict, changed_app_names: set[str] | None = None) -> None:
@@ -554,7 +557,17 @@ def build_v2_appstore_artifacts(
554557
catalog_checksum_values = ",".join(f"{k}={v}" for k, v in sorted(catalog_checksums.items()))
555558
catalog_dsv = _hash_content(catalog_checksum_values)
556559

557-
catalog_manifest = build_catalog_manifest(catalog_dsv, catalog_checksums, generated_at)
560+
# ── catalog full package ─────────────────────────────────
561+
catalog_zip_name = f"catalog-{catalog_dsv}.zip"
562+
with tempfile.TemporaryDirectory() as tmp_dir_name:
563+
tmp_dir = Path(tmp_dir_name)
564+
for file_name in CATALOG_FILE_NAMES:
565+
shutil.copy2(catalog_dir / file_name, tmp_dir / file_name)
566+
create_zip_from_directory(tmp_dir, catalog_dir / catalog_zip_name)
567+
catalog_zip_checksum = write_checksum_file(catalog_dir / catalog_zip_name)
568+
catalog_checksums["fullPackage"] = catalog_zip_checksum
569+
570+
catalog_manifest = build_catalog_manifest(catalog_dsv, catalog_checksums, generated_at, catalog_zip_name)
558571
write_json(catalog_dir / "manifest.json", catalog_manifest)
559572
write_checksum_file(catalog_dir / "manifest.json")
560573
validate_catalog_artifacts(catalog_dir, catalog_manifest)

docs/appstore-release-spec.md

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ else:
105105
artifact/websoft9/v2/<channel>/appstore/
106106
├── catalog/
107107
│ ├── manifest.json # catalog 清单
108+
│ ├── catalog-<datasetVersion>.zip # 全量包(4 个 JSON)
108109
│ ├── catalog_en.json
109110
│ ├── catalog_zh.json
110111
│ ├── product_en.json
@@ -168,6 +169,7 @@ artifact/websoft9/v2/<channel>/appstore/
168169
"schemaVersion": "1",
169170
"datasetVersion": "7ee7a10b7da49f38",
170171
"source": "contentful",
172+
"fullPackage": "catalog-7ee7a10b7da49f38.zip",
171173
"files": {
172174
"catalogEn": "catalog_en.json",
173175
"catalogZh": "catalog_zh.json",
@@ -178,7 +180,8 @@ artifact/websoft9/v2/<channel>/appstore/
178180
"catalogEn": "catalog_en.json.sha256",
179181
"catalogZh": "catalog_zh.json.sha256",
180182
"productEn": "product_en.json.sha256",
181-
"productZh": "product_zh.json.sha256"
183+
"productZh": "product_zh.json.sha256",
184+
"fullPackage": "catalog-7ee7a10b7da49f38.zip.sha256"
182185
},
183186
"generatedAt": "2026-06-09T12:00:00Z"
184187
}
@@ -318,51 +321,44 @@ artifact/websoft9/v2/<channel>/appstore/
318321

319322
## 11. 消费者指南
320323

321-
消费者在本地维护两个版本锚点,分别对应 `appstore-manifest.json` 中暴露的 `catalog.datasetVersion``library.datasetVersion`
322-
323-
```json
324-
{
325-
"schemaVersion": "1",
326-
"lastCatalogDsv": "7ee7a10b7da49f38",
327-
"lastLibraryDsv": "85f687824c03ef93"
328-
}
329-
```
330-
331-
> **为什么存两个而不是一个?** 根 manifest 中已经分别给出了 `catalog.datasetVersion``library.datasetVersion`。消费者下载根 manifest 后,可以**直接**判断哪部分变了、哪部分没变——catalog 没变就跳过 catalog 更新,library 没变就跳过 library 更新。如果只存一个组合版本,只能知道"有变化"但不知道"谁变了",必须两个子 manifest 都下载。**
324+
消费者无需维护额外的状态文件——**上一次下载成功的 `appstore-manifest.json` 本身就是完整的状态记录**。更新时将新下载的 manifest 与本地缓存的旧 manifest 对比即可。
332325

333326
### 11.1 首次安装(冷启动)
334327

335328
```
336329
1. 下载 appstore-manifest.json
337330
2. 检查 schemaVersion 兼容性 → 不兼容则中止
338-
3. 下载 full/library-<channel>.zip(全量包)
339-
4. 校验 full/library-<channel>.zip.sha256
340-
5. 解压到本地 apps/ 目录
341-
6. 将 catalog.datasetVersion 和 library.datasetVersion 保存到本地
331+
332+
3. 下载 catalog 全量数据:
333+
→ 下载 catalog/manifest.json
334+
→ 下载 catalog-<datasetVersion>.zip(全量包,1 次请求 1 次校验)
335+
→ 校验 catalog-<datasetVersion>.zip.sha256
336+
→ 解压到本地
337+
338+
4. 下载 library 全量数据:
339+
→ 下载 full/library-<channel>.zip(全量包,含所有 app 模板)
340+
→ 校验 full/library-<channel>.zip.sha256
341+
→ 解压到本地 apps/ 目录
342+
343+
5. 保存本次下载的 appstore-manifest.json 到本地作为状态锚点
342344
```
343345

344346
### 11.2 增量更新
345347

346348
```
347-
1. 下载 appstore-manifest.json(~200B)
348-
349-
2. if catalog.datasetVersion ≠ 本地 lastCatalogDsv:
350-
→ 下载 catalog/manifest.json
351-
→ 逐个对比 checksum,只下载实际变更的 JSON 文件
352-
→ 更新 lastCatalogDsv
353-
354-
3. if library.datasetVersion ≠ 本地 lastLibraryDsv:
355-
→ 下载 library/manifest.json
356-
→ if supportsPartialUpdate == true:
357-
下载 apps-delta-{lastLibraryDsv}-to-{新libraryDsv}.json
358-
addedApps / changedApps → 下载对应的 latest.zip
359-
removedApps → 本地删除
360-
→ else:
361-
下载 full/library-<channel>.zip 全量替换
362-
→ 更新 lastLibraryDsv
363-
364-
4. 更新本地 schemaVersion(如有变化)
365-
```
349+
1. 下载最新的 appstore-manifest.json
350+
351+
2. 对比新 manifest 与本地缓存的旧 manifest:
352+
→ 如果 catalog.datasetVersion 不同:
353+
下载 catalog/manifest.json → 逐个对比 checksum → 下载变更的 JSON
354+
→ 如果 library.datasetVersion 不同:
355+
if supportsPartialUpdate:
356+
下载 apps-delta → 下载 changed/added app 的 latest.zip
357+
else:
358+
下载全量包
359+
→ 如果都相同:什么都不做,结束
360+
361+
3. 更新成功后,用新 manifest 替换本地缓存
366362
```
367363

368364
**典型场景开销**
@@ -378,10 +374,11 @@ artifact/websoft9/v2/<channel>/appstore/
378374
```
379375
增量更新中任一文件下载或校验失败:
380376
→ 回退策略:下载 full/library-<channel>.zip 全量覆盖本地 apps/
381-
更新 lastLibraryDsv 到全量包的版本
377+
用本次下载的 manifest 替换本地缓存
382378
383379
schemaVersion 不在本地支持列表中:
384-
→ 不更新任何数据,保持当前状态
380+
→ 不更新任何数据,保持本地缓存的旧 manifest
381+
→ 提示用户升级客户端
385382
→ 提示用户升级客户端
386383
```
387384

0 commit comments

Comments
 (0)