# Release SOP: 先打包後部署 **Version**: v1.0.0 **Date**: 2026-04-30 **Status**: Active --- ## 流程概覽 ``` 1. 預檢 (Pre-flight) → 2. 打包 (Package) → 3. Schema 同步 → 4. 部署 (Deploy) → 5. 驗證 (Verify) ``` --- ## Phase 1: 預檢 (Pre-flight Checks) ### 1.1 服務檢查 ```bash bash scripts/release_preflight_check.sh ``` **檢查項目**: - PostgreSQL, Redis, MongoDB, Qdrant - Ollama (nomic-embed-text), llama-server (gemma4_e4b_q5) - ffmpeg, ffprobe, Python 3.11 - SFTPGo - Disk space < 90% ### 1.2 程式碼檢查 ```bash cargo clippy --lib && cargo test --lib && cargo fmt -- --check ``` ### 1.3 Schema 版本檢查 ```bash # 檢查 public schema 是否有遺漏欄位 psql -U accusys -d momentry -c " SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'videos' AND column_name = 'parent_uuid'; " ``` --- ## Phase 2: 打包 (Packaging) | 步驟 | 輸出 | 位置 | |------|------|------| | 2.1 建立 Release Tag | Git tag | `git tag -a v1.0.0` | | 2.2 備份 DB Schema | `public_schema_v1.0.0.sql` | `release/` | | 2.3 備份 DB Data | `dev_data_v1.0.0.sql` | `release/` | | 2.4 備份 API 文件 | `API_DOCUMENTATION.md` | `docs_v1.0/` | | 2.5 建立 Release 目錄 | 完整 release 結構 | `release/` | | 2.6 打包原始碼 | `momentry_core_v1.0.0_source.zip` | `release/` | | 2.7 打包 Dev Output | `output_json_v1.0.0.zip` | `release/` | | 2.8 打包架構文件 | `docs_v1.0_v1.0.0.zip` | `release/` | | 2.9 建立 Release Manifest | `RELEASE_INFO.txt` | `release/` | | 2.10 建立 Migration 腳本 | `migrate_public_schema_v4.sql` | `release/` | --- ## Phase 3: Schema 同步 (Schema Synchronization) **⚠️ 這是最容易被忽略的步驟!** ### 3.1 檢查 Schema 差異 ```bash # 比較 public vs dev schema diff <(psql -U accusys -d momentry -c "\dt public.*" -t) \ <(psql -U accusys -d momentry -c "\dt dev.*" -t) ``` ### 3.2 執行 Migration ```bash # 備份當前 public schema pg_dump -U accusys -d momentry --schema=public > release/public_schema_backup_$(date +%Y%m%d_%H%M%S).sql # 執行 migration psql -U accusys -d momentry -f release/migrate_public_schema_v4.sql ``` ### 3.3 驗證 Migration ```bash # 檢查關鍵欄位 psql -U accusys -d momentry -c " SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = 'public' AND column_name IN ('parent_uuid', 'summary_text', 'file_uuid', 'bbox') ORDER BY table_name, column_name; " ``` --- ## Phase 4: 部署 (Deployment) ### 4.1 停止現有服務 ```bash sudo launchctl stop com.momentry.api sleep 2 lsof -i :3002 # 確認 port 已釋放 ``` ### 4.2 備份現有 Binary ```bash cp target/release/momentry release/momentry_v$(prev_version)_backup ``` ### 4.3 建立新 Binary ```bash cargo build --release --bin momentry cp target/release/momentry release/momentry_v$(version) ``` ### 4.4 啟動服務 ```bash sudo launchctl start com.momentry.api sleep 3 curl -s http://localhost:3002/health | jq . ``` --- ## Phase 5: 驗證 (Post-deployment Verification) ### 5.1 健康檢查 ```bash curl -s http://localhost:3002/health | jq . curl -s http://localhost:3002/health/detailed | jq . curl -s http://localhost:3002/api/v1/stats/inference | jq . ``` ### 5.2 API 測試 ```bash # 影片列表 curl -s "http://localhost:3002/api/v1/videos?page=1&page_size=5" -H "X-API-Key: $API_KEY" | jq .count # 搜索功能 curl -s -X POST http://localhost:3002/api/v1/search \ -H "Content-Type: application/json" -H "X-API-Key: $API_KEY" \ -d '{"query":"test","limit":5}' | jq .results | length # 身份列表 curl -s "http://localhost:3002/api/v1/identities?page=1" -H "X-API-Key: $API_KEY" | jq .count ``` ### 5.3 關鍵 Endpoint 檢查清單 | Endpoint | 預期 | 實際 | |----------|------|------| | `GET /health` | 200 OK | | | `GET /health/detailed` | 200 OK, 4 services ok | | | `GET /api/v1/videos` | 200 OK, count > 0 | | | `GET /api/v1/identities` | 200 OK | | | `POST /api/v1/search` | 200 OK, results | | | `GET /api/v1/stats/ingest` | 200 OK | | | `GET /api/v1/videos/:uuid/details` | 200 OK | | | `GET /api/v1/faces/candidates` | 200 OK | | --- ## Phase 6: 清理 (Cleanup) ### 6.1 更新 RELEASE_INFO.txt ```bash # 記錄 git commit, binary hash, deployment time echo "Deployed: $(date)" >> release/RELEASE_INFO.txt echo "Commit: $(git rev-parse HEAD)" >> release/RELEASE_INFO.txt ``` ### 6.2 建立 Release Tag ```bash git tag -a v1.0.0 -m "Release v1.0.0 - V4.0 Architecture" git push origin v1.0.0 ``` ### 6.3 存檔 Release Package ```bash mkdir -p ~/.momentry_snapshots/v1.0.0 cp release/* ~/.momentry_snapshots/v1.0.0/ ``` --- ## 常見問題 ### Q: Schema migration 失敗怎麼辦? A: 執行 rollback: ```bash psql -U accusys -d momentry < release/public_schema_backup_YYYYMMDD_HHMMSS.sql ``` ### Q: 服務啟動後 port 3002 仍被佔用? A: 使用 `sudo launchctl bootout gui/$(id -u)/com.momentry.api` 強制停止。 ### Q: API 回應 500 錯誤? A: 依序檢查: 1. Schema 版本:`psql -U accusys -d momentry -c "\d public.videos" | grep parent_uuid` 2. SQL 查詢欄位是否與 struct 匹配 3. 檢查 server logs --- ## 經驗教訓 (Lessons Learned) ### v1.0.0 Release 發現的問題 1. **Schema 同步機制缺失** - 問題:開發期間 public schema 沒有同步更新 - 影響:release binary 無法正常運行 - 修正:建立 migration 腳本,納入 SOP Phase 3 2. **SQL 查詢欄位不完整** - 問題:`search_videos` 的 `columns` 字串缺少 `parent_uuid` - 影響:sqlx 映射失敗,所有 videos 相關 API 500 錯誤 - 修正:添加缺少的欄位,未來新增欄位時需同步更新 queries 3. **Pre-flight 檢查不足** - 問題:只檢查服務狀態,沒有檢查 schema 版本 - 修正:添加 schema 驗證步驟 --- ## Release Checklist - [ ] Phase 1: 預檢通過 (services, code, schema) - [ ] Phase 2: 打包完成 (source, data, docs, binary) - [ ] Phase 3: Schema 同步完成且驗證通過 - [ ] Phase 4: 部署完成,服務啟動正常 - [ ] Phase 5: API 測試通過 (所有關鍵 endpoint) - [ ] Phase 6: 清理完成 (tag, archive, manifest) - [ ] Release report 已建立 (`release/RELEASE_TEST_REPORT.md`)