chore(observability): add CSS mirror sync helper
All checks were successful
CD Pipeline / deploy (push) Successful in 1m33s

This commit is contained in:
OoO
2026-05-05 22:16:41 +08:00
parent 15f7c8660d
commit 346e9672a6
4 changed files with 73 additions and 3 deletions

View File

@@ -50,7 +50,13 @@ scripts/check_observability_suite.sh
python3 scripts/check_observability_ui.py
```
或透過既有 quick review 選單執行第 8 項完整 QA 套件、第 6 項靜態 UI guard
如果修改了 `static/css/observability-system.css`,先同步 Flask 實際服務用的 mirror
```bash
python3 scripts/sync_observability_css.py
```
或透過既有 quick review 選單執行第 8 項完整 QA 套件、第 6 項靜態 UI guard、第 9 項 CSS mirror sync
```bash
./scripts/quick_review.sh

View File

@@ -202,7 +202,7 @@ def scan_css() -> list[str]:
web_text = web_path.read_text(encoding="utf-8")
if web_text != text:
findings.append(
f"{WEB_CSS_PATH}: must match {CSS_PATH} so production /static CSS is in sync"
f"{WEB_CSS_PATH}: must match {CSS_PATH} so production /static CSS is in sync; run `python3 scripts/sync_observability_css.py`"
)
return findings

View File

@@ -18,6 +18,7 @@ CODE_REVIEW_SCRIPT="$PROJECT_ROOT/scripts/code_review.py"
OBSERVABILITY_UI_GUARD="$PROJECT_ROOT/scripts/check_observability_ui.py"
OBSERVABILITY_PAGE_SMOKE="$PROJECT_ROOT/scripts/check_observability_pages.py"
OBSERVABILITY_QA_SUITE="$PROJECT_ROOT/scripts/check_observability_suite.sh"
OBSERVABILITY_CSS_SYNC="$PROJECT_ROOT/scripts/sync_observability_css.py"
# 顯示標題
echo -e "${BLUE}========================================${NC}"
@@ -75,6 +76,16 @@ run_observability_qa_suite() {
bash "$OBSERVABILITY_QA_SUITE"
}
run_observability_css_sync() {
if [ ! -f "$OBSERVABILITY_CSS_SYNC" ]; then
echo -e "${RED}❌ AI觀測台 CSS 同步腳本不存在: $OBSERVABILITY_CSS_SYNC${NC}"
exit 1
fi
echo -e "${GREEN}🎨 同步 AI觀測台 CSS 到 Flask static path...${NC}"
python3 "$OBSERVABILITY_CSS_SYNC"
}
# 顯示選單
if [ $# -eq 0 ]; then
echo -e "${YELLOW}請選擇操作:${NC}"
@@ -86,8 +97,9 @@ if [ $# -eq 0 ]; then
echo "6) AI觀測台 UI/UX 防回歸檢查"
echo "7) AI觀測台 10頁線上巡檢"
echo "8) AI觀測台完整 QA 套件"
echo "9) 同步 AI觀測台 CSS static mirror"
echo ""
read -p "請輸入選項 (1-8): " choice
read -p "請輸入選項 (1-9): " choice
case $choice in
1)
@@ -126,6 +138,9 @@ if [ $# -eq 0 ]; then
8)
run_observability_qa_suite
;;
9)
run_observability_css_sync
;;
*)
echo -e "${RED}❌ 無效選項${NC}"
exit 1

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env python3
"""Sync the canonical observability CSS to the Flask-served static path.
The project keeps the design-system source at:
static/css/observability-system.css
Production Flask static serving currently exposes:
web/static/css/observability-system.css
This helper keeps the two files byte-identical so deploys do not regress into
"HTML links the CSS but /static/css/observability-system.css is 404/stale".
"""
from __future__ import annotations
import shutil
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SOURCE = ROOT / "static/css/observability-system.css"
TARGET = ROOT / "web/static/css/observability-system.css"
def main() -> int:
if not SOURCE.exists():
print(f"ERROR: missing source CSS: {SOURCE.relative_to(ROOT)}")
return 1
TARGET.parent.mkdir(parents=True, exist_ok=True)
source_bytes = SOURCE.read_bytes()
target_bytes = TARGET.read_bytes() if TARGET.exists() else b""
if source_bytes == target_bytes:
print("Observability CSS sync: already in sync")
print(f"- source: {SOURCE.relative_to(ROOT)}")
print(f"- target: {TARGET.relative_to(ROOT)}")
return 0
shutil.copyfile(SOURCE, TARGET)
print("Observability CSS sync: synced")
print(f"- source: {SOURCE.relative_to(ROOT)}")
print(f"- target: {TARGET.relative_to(ROOT)}")
print(f"- bytes: {len(source_bytes)}")
return 0
if __name__ == "__main__":
raise SystemExit(main())