Files
Jyotisha/scripts/deployment_preflight.py
T
2026-07-15 22:23:17 +08:00

102 lines
4.2 KiB
Python

#!/usr/bin/env python3
"""Check ordinary-user delivery paths before publishing a Jyotish build."""
from __future__ import annotations
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
APP = ROOT / "jyotish-app"
def read(path: Path) -> str:
return path.read_text(encoding="utf-8")
def require(condition: bool, label: str, failures: list[str]) -> None:
if not condition:
failures.append(label)
def delivery_matrix() -> list[dict]:
return [
{
"id": "local-dev",
"label": "Local dev",
"user_url": "http://127.0.0.1:5173",
"commands": [
".venv/bin/python scripts/jyotish_api_server.py --host 127.0.0.1 --port 5200",
"cd jyotish-app && npm run dev -- --host 127.0.0.1 --port 5173",
],
"api_required": True,
"scope": "Full web/app user experience with local API.",
},
{
"id": "docker-compose",
"label": "Docker Compose",
"user_url": "http://localhost:5300",
"commands": ["docker compose up -d"],
"api_required": True,
"scope": "Bundled API + web shell for local ordinary-user trials.",
},
{
"id": "static-demo-pwa",
"label": "Static demo / PWA",
"user_url": "https://<static-host>/",
"commands": ["cd jyotish-app && npm run build"],
"api_required": False,
"scope": "public demo shell; full advanced techniques require a local API service.",
},
{
"id": "desktop-shell",
"label": "Desktop shell",
"user_url": "pwa://installed-app or pake://local-url",
"commands": [
"cd jyotish-app && npm run build && npm run preview -- --host 127.0.0.1 --port 4173",
"python3 scripts/desktop_packaging_preflight.py",
],
"api_required": True,
"scope": "PWA/Pake now; Tauri sidecar only after API lifecycle and signing are fixed.",
},
]
def main() -> int:
failures: list[str] = []
readme = read(ROOT / "README.md")
dockerfile = read(ROOT / "Dockerfile")
compose = read(ROOT / "docker-compose.yml")
package = json.loads(read(APP / "package.json"))
manifest = json.loads(read(APP / "public" / "manifest.webmanifest"))
sw = read(APP / "public" / "sw.js")
index_html = read(APP / "index.html")
main_js = read(APP / "main.js")
require("普通用户交付形态" in readme, "README missing ordinary-user delivery matrix", failures)
require("python3 scripts/deployment_preflight.py" in readme, "README missing deployment preflight command", failures)
require("static_demo_boundary_visible" in readme, "README missing static demo boundary marker", failures)
require('id="static-demo-boundary"' in index_html, "static demo capability boundary must be visible on first screen", failures)
require("renderStaticDemoBoundary" in main_js, "Trust Center must render static demo capability boundary", failures)
require("http://localhost:5300" in compose, "docker-compose missing ordinary web URL note", failures)
require("python3 scripts/deployment_preflight.py" in dockerfile, "Dockerfile must run deployment preflight", failures)
require("build" in package.get("scripts", {}), "jyotish-app missing build script", failures)
require("preview" in package.get("scripts", {}), "jyotish-app missing preview script", failures)
require(manifest.get("display") == "standalone", "PWA manifest must remain standalone", failures)
require("url.pathname.startsWith('/api/')" in sw, "service worker must bypass API requests", failures)
result = {
"valid": not failures,
"failures": failures,
"delivery_matrix": delivery_matrix(),
"static_demo_boundary_visible": "static shell is labeled; local API-only capabilities are listed for ordinary users.",
"ordinary_user_note": "公开演示环境只能完整展示静态壳;完整高级技法需要本地 API 服务。",
}
print(json.dumps(result, ensure_ascii=False, indent=2))
return 0 if not failures else 1
if __name__ == "__main__":
raise SystemExit(main())