jim800121chen c54f16fca0 Initial commit: visionA monorepo with local-tool subproject
local-tool/: visionA-local desktop app
- M1: Wails shell + Go server + Next.js UI + Mock mode (macOS dmg ready)
- M2: i18n (zh-TW/en) + Settings 4-tab refactor
- M3: Embedded Python 3.12 runtime (python-build-standalone) + KneronPLUS wheels
- M4: Windows Inno Setup script (build on Windows runner)
- M5: Linux AppImage script + udev rule (build on Linux runner)
- M6: ffmpeg (GPL, pending legal review) + yt-dlp bundled
- Lifecycle: watchServer health check, fatal native dialog,
            Wails IPC raise endpoint, stale process cleanup

.autoflow/: full PRD / Design Spec / Architecture / Testing docs
            (4 rounds tri-party discussion + cross review)
.github/workflows/: macOS / Windows / Linux build CI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:10:38 +08:00

310 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Packaging — visionA-local
> macOS .dmg、Windows Inno Setup .exe、Linux AppImage 的具體打包流程。
> **無任何程式碼簽章**(使用者決策 Q2 = C
---
## 1. 總覽:三平台產出物
| 平台 | 格式 | 簽章 | 大小(預估) |
|------|------|------|------------|
| macOS 14/15 x86_64 | `visiona-local-v{ver}-macos-x64.dmg` 內含 `.app` | ad-hoc`codesign -s -` | ~195MB |
| Windows 10/11 x64 | `visiona-local-v{ver}-windows-x64.exe`Inno Setup installer | **無** | ~205MB |
| Ubuntu 22.04/24.04 x64 | `visiona-local-v{ver}-linux-x64.AppImage` | 無 | ~210MB |
## 2. macOS.app + .dmg
### 2.1 建置流程
```bash
# 1. 準備 payload
make payload-macos # 把 python + wheels + ffmpeg + models 塞到 visiona-local/payload/
# 2. Wails 編譯
cd visiona-local && wails build -platform darwin/amd64 -clean
# 3. ad-hoc sign
codesign --force --deep --sign - build/bin/visiona-local.app
# 4. 驗證簽章
codesign -dv --verbose=4 build/bin/visiona-local.app
# 5. 打包成 dmg
dmgbuild -s dmg-config.py "visionA-local" dist/visiona-local-v${VERSION}-macos-x64.dmg # 顯示標題沿用產品名 visionA-local
```
### 2.2 `wails.json` 關鍵設定
```json
{
"name": "visiona-local",
"outputfilename": "visiona-local",
"frontend:install": "echo skip",
"frontend:build": "echo skip",
"info": {
"companyName": "Innovedus",
"productName": "visionA-local",
"productVersion": "1.0.0",
"copyright": "© 2026 Innovedus",
"comments": "Kneron KL520/KL720 本地開發工具"
},
"nsisType": "multiple",
"appid": "com.innovedus.visiona-local"
}
```
### 2.3 Info.plist 關鍵項
- `CFBundleIdentifier = com.innovedus.visiona-local`
- `CFBundleExecutable = visiona-local`binary 全小寫;`CFBundleName` / `CFBundleDisplayName` 仍為 `visionA-local` 作為顯示名)
- `NSHighResolutionCapable = true`
- `LSMinimumSystemVersion = 14.0`
- `NSCameraUsageDescription = visionA-local 需要存取攝影機以執行 AI 推論展示`
- `NSAppleEventsUsageDescription = visionA-local 需要使用 AppleScript 開啟瀏覽器`
- **不需要** `NSAppTransportSecurity` 因為只用 localhost
### 2.4 dmgbuild 設定檔(`dmg-config.py`
```python
# dmg-config.py
format = 'UDBZ' # bzip2 壓縮,壓縮率好
size = '400M'
files = ['build/bin/visiona-local.app']
symlinks = {'Applications': '/Applications'}
badge_icon = 'build/icon.icns'
icon_locations = {
'visiona-local.app': (150, 200),
'Applications': (450, 200),
}
window_rect = ((200, 200), (600, 400))
background = 'build/dmg-background.png'
```
### 2.5 首次啟動Gatekeeper workaround
**因為沒有 notarization使用者第一次打開 .app 會跳警告:**
> "visionA-local" can't be opened because it is from an unidentified developer.
**解法(必須寫進 README 與首次啟動說明頁):**
1. 在 Finder 中對 `visiona-local.app` **按右鍵 → 開啟**
2. 在警告對話框按「開啟」
3. 之後可以正常雙擊開啟
或命令列:`xattr -d com.apple.quarantine /Applications/visiona-local.app`
## 3. WindowsInno Setup .exe
### 3.1 為何選 Inno Setup 而不是 NSIS / MSI
- **UI 現代化**Inno Setup 6 的預設樣式比 NSIS 好看
- **腳本簡單**Pascal-like DSL比 NSIS 的 MakeNSIS 好維護
- **安裝 driver 方便**:內建 `DriverInstall` 流程支援 pnputil
- **不用 MSI**MSI 需要 WiX 工具鏈與 signing 才順我們不簽章Inno Setup 更簡單
### 3.2 建置流程
```bash
# 1. 準備 payload
make payload-windows
# 2. Wails 編譯
cd visiona-local && wails build -platform windows/amd64 -clean
# 3. 執行 Inno Setup Compiler
iscc visiona-local-installer.iss
# 產物dist/visiona-local-v{ver}-windows-x64.exe
```
### 3.3 `visiona-local-installer.iss` 骨架
```pascal
[Setup]
AppId={{A7F3E891-4B2C-4D5E-9F1A-8B3C2D1E0F9A}
AppName=visionA-local
AppVersion=1.0.0
AppPublisher=Innovedus
AppPublisherURL=https://innovedus.com
DefaultDirName={autopf}\visiona-local
DefaultGroupName=visiona-local
OutputDir=..\dist
OutputBaseFilename=visiona-local-v1.0.0-windows-x64
SetupIconFile=assets\icon.ico
Compression=lzma2/ultra64
SolidCompression=yes
WizardStyle=modern
PrivilegesRequired=admin
ArchitecturesInstallIn64BitMode=x64
MinVersion=10.0.17763
[Files]
Source: "visiona-local\build\bin\visiona-local.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "visiona-local\payload\*"; DestDir: "{app}\payload"; Flags: ignoreversion recursesubdirs
[Icons]
Name: "{group}\visionA-local"; Filename: "{app}\visiona-local.exe"
Name: "{autodesktop}\visionA-local"; Filename: "{app}\visiona-local.exe"; Tasks: desktopicon
[Tasks]
Name: "desktopicon"; Description: "建立桌面捷徑"; GroupDescription: "附加選項:"
[Run]
; 安裝 WinUSB driver
Filename: "{sys}\pnputil.exe"; \
Parameters: "/add-driver ""{app}\payload\drivers\kneron_winusb.inf"" /install"; \
StatusMsg: "正在安裝 Kneron USB driver..."; \
Flags: runhidden waituntilterminated
; 啟動 app
Filename: "{app}\visiona-local.exe"; \
Description: "啟動 visionA-local"; \
Flags: postinstall nowait skipifsilent
[UninstallDelete]
Type: filesandordirs; Name: "{localappdata}\visiona-local"
```
### 3.4 SmartScreen 警告處理
**沒有 Authenticode 簽章Windows SmartScreen 會擋:**
> Windows protected your PC — Microsoft Defender SmartScreen prevented an unrecognized app from starting.
**解法(寫進安裝說明):**
1. 點「更多資訊」
2. 點「仍要執行」
使用者第一次下載後會遇到這個警告,執行過一次之後 Windows 會記住。這是可接受的摩擦成本(使用者決策)。
## 4. LinuxAppImage
### 4.1 為何選 AppImage 而不是 .deb / snap / flatpak
- **單檔可攜**:一個 `.AppImage` 檔案,雙擊即跑,不需安裝
- **跨發行版**:只要 glibc >= 2.28Ubuntu 18.04+)就能跑
- **不需 sudo**(正常情境下)
- **符合「像一般 app」的體驗**
`.deb` 需要 apt install + sudosnap / flatpak 需要發到 store 或有 runtime 依賴,不適合內部工具分發。
### 4.2 建置流程
```bash
# 1. 準備 payload
make payload-linux
# 2. Wails 編譯
cd visiona-local && wails build -platform linux/amd64 -clean
# 3. 建立 AppDir
rm -rf AppDir && mkdir -p AppDir/usr/bin AppDir/usr/lib
cp build/bin/visiona-local AppDir/usr/bin/
cp -r payload AppDir/usr/bin/payload
# 4. 複製 libusb 到 AppDir避免依賴系統 libusb
cp /usr/lib/x86_64-linux-gnu/libusb-1.0.so.0 AppDir/usr/lib/
# 5. 寫入 .desktop 與 AppRun
cat > AppDir/visiona-local.desktop <<EOF
[Desktop Entry]
Type=Application
Name=visionA-local
Exec=visiona-local
Icon=visiona-local
Categories=Development;
EOF
cat > AppDir/AppRun <<'EOF'
#!/bin/bash
HERE="$(dirname "$(readlink -f "$0")")"
export LD_LIBRARY_PATH="$HERE/usr/lib:${LD_LIBRARY_PATH}"
exec "$HERE/usr/bin/visiona-local" "$@"
EOF
chmod +x AppDir/AppRun
cp assets/icon.png AppDir/visiona-local.png
# 6. 用 appimagetool 打包
ARCH=x86_64 appimagetool AppDir dist/visiona-local-v${VERSION}-linux-x64.AppImage
```
### 4.3 首次執行需要的權限
因為要寫入 `/etc/udev/rules.d/99-kneron.rules` 讓非 root 使用者存取 USB
**首次執行時跳 pkexec 提權對話框GNOME 預設可用),執行:**
```bash
pkexec cp ~/.local/share/visiona-local/scripts/99-kneron.rules /etc/udev/rules.d/
pkexec udevadm control --reload-rules
pkexec udevadm trigger
```
使用者拒絕或系統沒有 pkexec例如 minimal server 安裝):顯示錯誤訊息提示手動執行 `sudo ./install-udev.sh`,內附的 script 由我們提供。
### 4.4 AppImage 的已知限制
- **沒有 .desktop integration**:使用者要自己放到 `~/Applications/` 或用 `appimaged`
- **第一次解壓慢**AppImage 是 squashfs第一次啟動會把內容 mount 到 `/tmp/.mount_*/`
## 5. 圖示與品牌資產
### 5.1 檔案清單
| 平台 | 檔案 | 尺寸 |
|------|------|------|
| macOS | `visiona-local.icns` | 512×512 @1x + @2x |
| Windows | `visiona-local.ico` | 16, 32, 48, 64, 128, 256 |
| Linux | `visiona-local.png` | 256×256 |
> Tray 圖示已移除(第三輪使用者決策 Q-A=A3砍 tray
### 5.2 來源
使用者決策 Q14**先沿用 edge-ai-platform 既有視覺(字母 E**,品牌換名但圖示暫時不動。
`edge-ai-platform/installer/frontend/src-tauri/icons/` 直接複製(`server/tray/assets/` 不再使用)。
## 6. 首次啟動警告匯總(使用者要看到的文件)
必須在以下位置寫清楚:
1. `README.md`GitHub / Gitea 發布頁)
2. 下載頁Gitea Release 描述)
3. 首次啟動歡迎頁(如果有的話,可跳過)
**內容模板:**
```markdown
## 首次啟動提示
visionA-local 是內部工具,**沒有 Apple / Microsoft 的程式碼簽章**。
首次執行時作業系統可能會顯示警告,這是正常的。
### macOS
在 Finder 中找到 `visiona-local.app`**按右鍵 → 開啟**,在彈出對話框中選「開啟」。
之後可以正常雙擊開啟。
### Windows
執行安裝檔時若看到 "Windows 已保護您的電腦" 警告:
點「更多資訊」→「仍要執行」。
### Linux
AppImage 預設沒有執行權限:
```
chmod +x visiona-local-v1.0.0-linux-x64.AppImage
./visiona-local-v1.0.0-linux-x64.AppImage
```
```
## 7. 發布流程
| 步驟 | 負責 | 工具 |
|------|------|------|
| 1. Tag release | 開發者 | `git tag v1.0.0 && git push --tags` |
| 2. CI build macOS | GitHub Actions / local | `make installer-macos` |
| 3. CI build Windows | GitHub Actions / local | `make installer-windows` |
| 4. CI build Linux | GitHub Actions / Docker | `make installer-linux` |
| 5. 上傳到 Gitea Release | 開發者 | `gh release create` 或手動 |
| 6. 更新 `latest.json`(如果未來做 auto-update | - | 目前不做 |
**不建置 universal / multi-arch**,只有 x64。