mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-08-11 03:09:56 +00:00
187 lines
7.5 KiB
Markdown
187 lines
7.5 KiB
Markdown
# Build Scripts
|
|
|
|
Unified build system for Slopsmith Desktop supporting Linux (via Docker), macOS, and Windows.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
./scripts/build-release.sh
|
|
```
|
|
|
|
## Call Hierarchy
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ GitHub Actions │
|
|
│ build.yml │
|
|
└────────┬────────┘
|
|
│
|
|
│ (calls the same script everywhere)
|
|
│
|
|
▼
|
|
┌──────────────────┐
|
|
│ build-release.sh │ Platform dispatcher
|
|
└────────┬─────────┘
|
|
│
|
|
│ Detects host OS:
|
|
│ - Linux → build-linux-docker.sh
|
|
│ - macOS → build-macos.sh
|
|
│ - Windows → build-windows.sh
|
|
│
|
|
▼
|
|
┌──────────────────────────────────────┐
|
|
│ For Linux: Docker wrapper │
|
|
│ build-linux-docker.sh → │
|
|
│ Docker container: │
|
|
│ ./build-linux-ubuntu.sh │
|
|
└──────────────────────────────────────┘
|
|
│
|
|
│ Sources:
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ build-common.sh │ Shared build logic (~250 lines)
|
|
└─────────────────┘
|
|
▲ ▲ ▲
|
|
│ │ │
|
|
│ │ ├─── Platform-specific implementations:
|
|
│ │ install_system_deps()
|
|
│ │ bundle_python_impl()
|
|
│ │ bundle_binaries_impl()
|
|
│ │
|
|
│ └─ build-macos.sh
|
|
│ build-windows.sh
|
|
│ build-linux-ubuntu.sh
|
|
│
|
|
└─ platform: mac / win / linux
|
|
```
|
|
|
|
## How It Works
|
|
|
|
1. **build-release.sh** - Platform dispatcher. Detects OS and routes to the right build script.
|
|
|
|
2. **Linux builds** - Always Docker-based for reproducibility:
|
|
- `build-linux-docker.sh` → Docker container → `build-linux-ubuntu.sh` → packages
|
|
|
|
3. **Native builds** - macOS and Windows run directly on host:
|
|
- `build-macos.sh` - Uses Homebrew dependencies
|
|
- `build-windows.sh` - Uses Git Bash, downloads binaries
|
|
|
|
4. **build-common.sh** - Shared logic sourced by platform scripts:
|
|
- Validates environment (Node.js, Python, .NET)
|
|
- Runs npm install, builds C++ engine, bundles resources
|
|
- Calls platform-specific functions for: dependency installation, Python bundling, binary bundling
|
|
|
|
## Platform-Specific Scripts
|
|
|
|
### Files
|
|
|
|
| Script | Purpose | Requirements | Output |
|
|
|--------|---------|--------------|--------|
|
|
| `build-linux-docker.sh` | Reproducible Docker build | Docker, adjacent slopsmith repo | `.AppImage`, `.deb` |
|
|
| `build-linux-ubuntu.sh` | Native Ubuntu build | Ubuntu/Debian + apt | `.AppImage`, `.deb` |
|
|
| `build-macos.sh` | Native macOS build | Homebrew, Xcode CLI | `.dmg`, `.zip` |
|
|
| `build-windows.sh` | Native Windows build | Git Bash, Node.js, Python, .NET | `.exe` installer |
|
|
|
|
### Two-Layer Ubuntu Builds
|
|
|
|
Most Linux distributions don't have identical package versions. Using Docker ensures the build is reproducible:
|
|
|
|
- **Direct use**: `./scripts/build-linux-docker.sh`
|
|
- **Inside container**: Runs `./scripts/build-linux-ubuntu.sh`
|
|
- **Why**: Guarantees identical builds across different Linux distros
|
|
|
|
### Platform-Specific Functions
|
|
|
|
Each platform script implements four functions that `build-common.sh` calls:
|
|
|
|
```bash
|
|
install_system_deps() {
|
|
# Platform-specific: apt install, brew install, choco install, or downloads
|
|
}
|
|
|
|
bundle_python_impl() {
|
|
# Linux: copy system Python
|
|
# macOS: download python-build-standalone
|
|
# Windows: download embeddable Python zip
|
|
}
|
|
|
|
bundle_binaries_impl() {
|
|
# Linux: copy existing + patchelf
|
|
# macOS: copy existing + dylibbundler + sign
|
|
# Windows: download binaries (ffmpeg, vgmstream, fluidsynth)
|
|
}
|
|
|
|
get_expected_artifacts() {
|
|
# Globs verify_artifacts checks at the end of the build, e.g.
|
|
# printf "%s\n" "$PROJECT_DIR/release/*.dmg" "$PROJECT_DIR/release/*.zip"
|
|
}
|
|
```
|
|
|
|
## Requirements
|
|
|
|
| Platform | Requirements |
|
|
|----------|--------------|
|
|
| **Linux (Docker)** | Docker, adjacent slopsmith repo |
|
|
| **Linux (native)** | Ubuntu/Debian, sudo, Node.js 22+, Python 3.12+, .NET 10+, apt dependencies |
|
|
| **macOS** | macOS 11+, Homebrew, Xcode CLI, Node.js 22+, Python 3.12+, .NET 10+ |
|
|
| **Windows** | Windows 10/11, Git for Windows + Bash, Node.js 22+, Python 3.12+, .NET 10+ |
|
|
|
|
**Windows Note:** These scripts must run in Git Bash (MSYS), not `cmd.exe` or PowerShell. They rely on MSYS-style paths such as `/tmp`, which work fine inside Git Bash but won't resolve correctly from a native Windows shell — so for local development outside GitHub Actions, run the scripts from a Git Bash terminal.
|
|
|
|
## GitHub Actions
|
|
|
|
The CI workflow is extremely simple - just calls the same script:
|
|
|
|
```yaml
|
|
# .github/workflows/build.yml
|
|
steps:
|
|
# Install platform-specific dependencies (apt, brew, or choco)
|
|
- name: Install dependencies
|
|
run: ...
|
|
|
|
# Build using the same script developers use locally
|
|
- name: Build
|
|
shell: bash
|
|
run: ./scripts/build-release.sh
|
|
```
|
|
|
|
Result:
|
|
- Local builds and CI use identical code paths
|
|
- Build failures can be reproduced and debugged locally
|
|
- Workflow is "dumb" - all logic lives in versioned scripts
|
|
|
|
## macOS Code Signing & Notarization
|
|
|
|
The macOS build signs every bundled native binary (fluidsynth, ffmpeg, vgmstream-cli, embedded Python interpreter + dylibs + extension `.so`s) with a Developer ID Application certificate, then electron-builder signs the `.app` and submits it to Apple's notary service. With signing in place, users get no Gatekeeper "app is damaged" warning on first launch.
|
|
|
|
### Required GitHub secrets
|
|
|
|
| Secret | Purpose |
|
|
|---|---|
|
|
| `APPLE_CERTIFICATE_P12_BASE64` | Developer ID Application cert exported as `.p12`, then `base64 -i cert.p12` |
|
|
| `APPLE_CERTIFICATE_PASSWORD` | The `.p12` export password |
|
|
| `APPLE_SIGNING_IDENTITY` | Full identity, e.g. `Developer ID Application: Your Name (TEAMID)` |
|
|
| `APPLE_ID` | Apple ID email |
|
|
| `APPLE_APP_SPECIFIC_PASSWORD` | App-specific password from appleid.apple.com (not the regular Apple ID password) |
|
|
| `APPLE_TEAM_ID` | 10-char team ID from developer.apple.com → Membership |
|
|
| `KEYCHAIN_PASSWORD` | Any random string — used for the temporary CI keychain |
|
|
|
|
When `APPLE_CERTIFICATE_P12_BASE64` is unset (forks, contributor PRs without secret access), the certificate-import step is skipped and `sign-macos-binaries.sh` exits early. The build still completes — it just produces an unsigned `.app` that will trigger Gatekeeper on macOS.
|
|
|
|
### Local macOS builds
|
|
|
|
Local builds without `APPLE_SIGNING_IDENTITY` set produce an unsigned `.app` (same as before signing was added). To produce a signed local build for testing, ensure your Developer ID Application certificate is in your login keychain and run:
|
|
|
|
```bash
|
|
APPLE_SIGNING_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
|
|
./scripts/build-release.sh
|
|
```
|
|
|
|
This signs the bundled binaries but does **not** notarize — notarization requires `APPLE_ID` + `APPLE_APP_SPECIFIC_PASSWORD` + `APPLE_TEAM_ID` env vars and is run by electron-builder when those are present.
|
|
|
|
### Local cmake-js cache
|
|
|
|
`build-windows.sh` only force-clears `$HOME/.cmake-js` when `$CI` is set (or `CLEAN_CMAKE_JS=1` is exported). Local Windows builds reuse the cache by default; set `CLEAN_CMAKE_JS=1` if you need a fully fresh build to mirror CI behaviour.
|
|
|