refactor: flatten docs/ — move V2 docs from docs/v2/ to docs/
- git mv docs/v2/*.md docs/ (11 planning documents) - Remove empty docs/v2/ directory - Update all references: AGENTS.md, CHANGELOG.md, README.md, ARCHITECTURE.md - Fix outdated repo tree in ARCHITECTURE.md to match actual structure
This commit is contained in:
@@ -0,0 +1,564 @@
|
||||
# Hostkeeper V2 — Build System
|
||||
|
||||
> **Status**: V2 Planning Complete
|
||||
> **Last Updated**: 2026-06-29
|
||||
|
||||
---
|
||||
|
||||
## 1. Build Overview
|
||||
|
||||
Hostkeeper V2 produces **4 platform outputs** from a single codebase:
|
||||
|
||||
| Platform | Output | Wrapper | Backend |
|
||||
|----------|--------|---------|---------|
|
||||
| macOS (ARM64) | `.dmg` | Electron | Go binary (embedded) |
|
||||
| macOS (x64) | `.dmg` | Electron | Go binary (embedded) |
|
||||
| Windows (x64) | `.exe` installer | Electron | Go binary (embedded) |
|
||||
| Linux (x64) | `.AppImage` | Electron | Go binary (embedded) |
|
||||
| Android (ARM64) | `.aab` / `.apk` | WebView | Go library (.aar) |
|
||||
| iOS (ARM64) | `.ipa` | WKWebView | Go framework (.xcframework) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Build Pipeline
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ Go Build │ │ Frontend │ │ Electron │ │ Platform │
|
||||
│ (backend) │ → │ Build │ → │ Package │ → │ Sign │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
||||
```
|
||||
|
||||
### Step 1: Go Backend Cross-Compile
|
||||
|
||||
```bash
|
||||
# macOS ARM64
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 \
|
||||
go build -ldflags="-s -w" -o dist/hostkeeper-server .
|
||||
|
||||
# macOS x64
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 \
|
||||
go build -ldflags="-s -w" -o dist/hostkeeper-server .
|
||||
|
||||
# Windows x64
|
||||
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 \
|
||||
go build -ldflags="-s -w" -o dist/hostkeeper-server.exe .
|
||||
|
||||
# Linux x64
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
||||
go build -ldflags="-s -w" -o dist/hostkeeper-server .
|
||||
|
||||
# Linux ARM64
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 \
|
||||
go build -ldflags="-s -w" -o dist/hostkeeper-server .
|
||||
```
|
||||
|
||||
**Notes**:
|
||||
- `CGO_ENABLED=0` — pure Go, no C dependencies
|
||||
- `-ldflags="-s -w"` — strip debug info, reduce binary size
|
||||
- Go binary size: ~15-20 MB (compressed)
|
||||
|
||||
### Step 2: Frontend Build
|
||||
|
||||
```bash
|
||||
cd app/frontend
|
||||
npm ci
|
||||
npm run build
|
||||
# Output: app/frontend/dist/
|
||||
```
|
||||
|
||||
**Vite config** (`app/frontend/vite.config.ts`):
|
||||
```typescript
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
sourcemap: false,
|
||||
minify: 'terser',
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
xterm: ['@xterm/xterm', '@xterm/addon-fit'],
|
||||
react: ['react', 'react-dom'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': 'http://localhost:8080',
|
||||
'/ws': {
|
||||
target: 'ws://localhost:8080',
|
||||
ws: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Step 3: Electron Package
|
||||
|
||||
```yaml
|
||||
# app/electron/electron-builder.yml
|
||||
appId: com.hostkeeper.app
|
||||
productName: Hostkeeper
|
||||
copyright: Copyright © 2026
|
||||
|
||||
directories:
|
||||
output: ../../dist
|
||||
|
||||
files:
|
||||
- "**/*"
|
||||
- "!**/node_modules/*/{CHANGELOG.md,README.md,readme.md,LICENSE}"
|
||||
|
||||
extraResources:
|
||||
- from: "../backend/hostkeeper-server"
|
||||
to: "hostkeeper-server"
|
||||
- from: "../frontend/dist"
|
||||
to: "frontend"
|
||||
|
||||
mac:
|
||||
category: public.app-category.developer-tools
|
||||
icon: assets/icon.icns
|
||||
target:
|
||||
- dmg
|
||||
- zip
|
||||
hardenedRuntime: true
|
||||
notarize: true
|
||||
|
||||
win:
|
||||
icon: assets/icon.ico
|
||||
target:
|
||||
- nsis
|
||||
certificateFile: env.WIN_CERTIFICATE_FILE
|
||||
|
||||
linux:
|
||||
icon: assets/icon.png
|
||||
target:
|
||||
- AppImage
|
||||
- deb
|
||||
category: Development
|
||||
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Mobile Build
|
||||
|
||||
### Android
|
||||
|
||||
```bash
|
||||
# Prerequisites:
|
||||
# - Android SDK installed
|
||||
# - Go 1.26+ with gomobile
|
||||
# - Java 17+
|
||||
|
||||
# Install gomobile
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
gomobile init
|
||||
|
||||
# Build Go library
|
||||
cd mobile/gomobile
|
||||
gomobile bind -target=android -o=../android/app/libs/hostkeeper.aar \
|
||||
./go/
|
||||
|
||||
# Build Android app
|
||||
cd ../android
|
||||
./gradlew assembleRelease
|
||||
# Output: mobile/android/app/build/outputs/apk/release/app-release.apk
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
```bash
|
||||
# Prerequisites:
|
||||
# - Xcode 15+
|
||||
# - Go 1.26+ with gomobile
|
||||
|
||||
# Build Go framework
|
||||
cd mobile/gomobile
|
||||
gomobile bind -target=ios -o=../ios/Hostkeeper/Hostkeeper.xcframework \
|
||||
./go/
|
||||
|
||||
# Build iOS app
|
||||
cd ../ios
|
||||
xcodebuild -project Hostkeeper.xcodeproj \
|
||||
-scheme Hostkeeper \
|
||||
-sdk iphoneos \
|
||||
-configuration Release
|
||||
# Output: mobile/ios/build/Release-iphoneos/Hostkeeper.app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Build Scripts
|
||||
|
||||
### `scripts/build.sh` (Full Build)
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
VERSION=${1:-"dev"}
|
||||
PLATFORM=${2:-"all"}
|
||||
|
||||
echo "=== Building Hostkeeper V2 v${VERSION} ==="
|
||||
|
||||
# Step 1: Build Go backend
|
||||
echo "Step 1: Building Go backend..."
|
||||
cd app/backend
|
||||
|
||||
case $PLATFORM in
|
||||
macos|all)
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w -X main.version=${VERSION}" -o ../electron/hostkeeper-server .
|
||||
;;
|
||||
windows|all)
|
||||
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w -X main.version=${VERSION}" -o ../electron/hostkeeper-server.exe .
|
||||
;;
|
||||
linux|all)
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X main.version=${VERSION}" -o ../electron/hostkeeper-server .
|
||||
;;
|
||||
esac
|
||||
|
||||
cd ../..
|
||||
|
||||
# Step 2: Build frontend
|
||||
echo "Step 2: Building frontend..."
|
||||
cd app/frontend
|
||||
npm ci
|
||||
npm run build
|
||||
cd ../..
|
||||
|
||||
# Step 3: Package Electron
|
||||
echo "Step 3: Packaging Electron..."
|
||||
cd app/electron
|
||||
|
||||
case $PLATFORM in
|
||||
macos)
|
||||
npx electron-builder --mac --arm64
|
||||
;;
|
||||
windows)
|
||||
npx electron-builder --win --x64
|
||||
;;
|
||||
linux)
|
||||
npx electron-builder --linux --x64
|
||||
;;
|
||||
all)
|
||||
npx electron-builder --mac --win --linux
|
||||
;;
|
||||
esac
|
||||
|
||||
cd ../..
|
||||
|
||||
# Step 4: Generate checksums
|
||||
echo "Step 4: Generating checksums..."
|
||||
cd dist
|
||||
shasum -a 256 *.dmg *.exe *.AppImage 2>/dev/null > checksums.txt
|
||||
|
||||
echo "=== Build complete ==="
|
||||
echo "Output: dist/"
|
||||
ls -la dist/
|
||||
```
|
||||
|
||||
### `scripts/build-mobile.sh`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
PLATFORM=${1:-"android"}
|
||||
|
||||
echo "=== Building Hostkeeper Mobile (${PLATFORM}) ==="
|
||||
|
||||
case $PLATFORM in
|
||||
android)
|
||||
cd mobile/gomobile
|
||||
gomobile bind -target=android -o=../android/app/libs/hostkeeper.aar ./go/
|
||||
cd ../android
|
||||
./gradlew assembleRelease
|
||||
echo "APK: mobile/android/app/build/outputs/apk/release/"
|
||||
;;
|
||||
ios)
|
||||
cd mobile/gomobile
|
||||
gomobile bind -target=ios -o=../ios/Hostkeeper/Hostkeeper.xcframework ./go/
|
||||
cd ../ios
|
||||
xcodebuild -project Hostkeeper.xcodeproj -scheme Hostkeeper -sdk iphoneos -configuration Release
|
||||
echo "IPA: mobile/ios/build/Release-iphoneos/"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "=== Mobile build complete ==="
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Development Workflow
|
||||
|
||||
### Quick Start
|
||||
|
||||
```bash
|
||||
# Terminal 1: Go backend
|
||||
cd app/backend
|
||||
go run .
|
||||
|
||||
# Terminal 2: Frontend (with hot reload)
|
||||
cd app/frontend
|
||||
npm run dev
|
||||
|
||||
# Open browser: http://localhost:5173
|
||||
```
|
||||
|
||||
### With Electron
|
||||
|
||||
```bash
|
||||
# Terminal 1: Go backend
|
||||
cd app/backend
|
||||
go run .
|
||||
|
||||
# Terminal 2: Frontend
|
||||
cd app/frontend
|
||||
npm run dev
|
||||
|
||||
# Terminal 3: Electron
|
||||
cd app/electron
|
||||
npm run dev
|
||||
# Electron opens with hot reload
|
||||
```
|
||||
|
||||
### VS Code Launch Config
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Go Backend",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/app/backend",
|
||||
"cwd": "${workspaceFolder}/app/backend"
|
||||
},
|
||||
{
|
||||
"name": "Electron",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/app/electron/node_modules/.bin/electron",
|
||||
"args": ["."],
|
||||
"cwd": "${workspaceFolder}/app/electron"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. CI/CD (GitHub Actions)
|
||||
|
||||
```yaml
|
||||
# .github/workflows/build.yml
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ['v*']
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.26'
|
||||
- run: go test -race ./app/backend/...
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
- run: cd app/frontend && npm ci && npm test
|
||||
|
||||
build-macos:
|
||||
needs: test
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.26'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
- run: ./scripts/build.sh ${{ github.ref_name }} macos
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: hostkeeper-macos
|
||||
path: dist/*.dmg
|
||||
|
||||
build-windows:
|
||||
needs: test
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.26'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
- run: ./scripts/build.sh ${{ github.ref_name }} windows
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: hostkeeper-windows
|
||||
path: dist/*.exe
|
||||
|
||||
build-linux:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.26'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
- run: ./scripts/build.sh ${{ github.ref_name }} linux
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: hostkeeper-linux
|
||||
path: dist/*.AppImage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Binary Size Optimization
|
||||
|
||||
| Technique | Impact |
|
||||
|-----------|--------|
|
||||
| `-ldflags="-s -w"` | -20% Go binary size |
|
||||
| UPX compression (optional) | -60% Go binary size |
|
||||
| Vite tree shaking | -40% JS bundle size |
|
||||
| Code splitting (lazy load) | -30% initial load |
|
||||
| Image optimization | -50% icon sizes |
|
||||
| Terser minification | -30% JS size |
|
||||
| CSS purging (Tailwind) | -80% CSS size |
|
||||
|
||||
**Target sizes**:
|
||||
- Go backend binary: ~15 MB (5 MB compressed)
|
||||
- Frontend dist: ~2 MB (500 KB compressed)
|
||||
- Electron package: ~200 MB total
|
||||
- Mobile APK: ~50 MB
|
||||
- Mobile IPA: ~60 MB
|
||||
|
||||
---
|
||||
|
||||
## 8. Version Management
|
||||
|
||||
### Version Format
|
||||
|
||||
```
|
||||
vMAJOR.MINOR.PATCH
|
||||
```
|
||||
|
||||
- **MAJOR**: Breaking changes (data format, API)
|
||||
- **MINOR**: New features
|
||||
- **PATCH**: Bug fixes
|
||||
|
||||
### Version Injection
|
||||
|
||||
```go
|
||||
// In main.go
|
||||
var version = "dev"
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Hostkeeper v%s\n", version)
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Build with version
|
||||
go build -ldflags="-X main.version=v2.0.0" -o hostkeeper-server .
|
||||
```
|
||||
|
||||
### Changelog Format
|
||||
|
||||
```markdown
|
||||
## [v2.1.0] - 2026-07-15
|
||||
|
||||
### Added
|
||||
- Port forwarding support (local, remote, dynamic)
|
||||
- Import from ~/.ssh/config
|
||||
|
||||
### Changed
|
||||
- Improved terminal performance with WebGL renderer
|
||||
|
||||
### Fixed
|
||||
- Fixed SFTP upload progress not updating
|
||||
- Fixed vault auto-lock not triggering on sleep
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Code Signing
|
||||
|
||||
### macOS
|
||||
|
||||
```bash
|
||||
# Requires Apple Developer account + certificates
|
||||
export CSC_LINK="path/to/certificate.p12"
|
||||
export CSC_KEY_PASSWORD="certificate-password"
|
||||
|
||||
# electron-builder handles signing + notarization
|
||||
npx electron-builder --mac --publish always
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
```bash
|
||||
# Requires code signing certificate
|
||||
export WIN_CERTIFICATE_FILE="path/to/certificate.pfx"
|
||||
export WIN_CERTIFICATE_PASSWORD="certificate-password"
|
||||
|
||||
npx electron-builder --win --publish always
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
No code signing required. AppImage is self-contained.
|
||||
|
||||
---
|
||||
|
||||
## 10. Release Workflow
|
||||
|
||||
```bash
|
||||
# 1. Update version
|
||||
npm version minor # or major, patch
|
||||
|
||||
# 2. Update CHANGELOG.md
|
||||
|
||||
# 3. Commit
|
||||
git add .
|
||||
git commit -m "chore: release v2.1.0"
|
||||
|
||||
# 4. Tag
|
||||
git tag -a v2.1.0 -m "Release v2.1.0"
|
||||
|
||||
# 5. Push
|
||||
git push origin main --tags
|
||||
|
||||
# 6. GitHub Actions builds + publishes artifacts
|
||||
|
||||
# 7. Create GitHub Release
|
||||
gh release create v2.1.0 \
|
||||
--title "Hostkeeper v2.1.0" \
|
||||
--notes-file CHANGELOG.md \
|
||||
dist/*.dmg dist/*.exe dist/*.AppImage
|
||||
```
|
||||
Reference in New Issue
Block a user