refactor: 统一构建产物输出目录

This commit is contained in:
2026-05-20 10:59:16 +08:00
parent 6e0abac30b
commit fcac708814
13 changed files with 181 additions and 133 deletions
-3
View File
@@ -18,14 +18,11 @@ dist
uploads
CapacityReportData
auth.ini
Configure.json
*.log
*.tmp
*.temp
*.bak
build/temp
build/pyinstaller
target
src-tauri/target
src-tauri/binaries
-2
View File
@@ -35,8 +35,6 @@ dist/
cache/
logs/
uploads/
build/temp/
build/pyinstaller/
src-tauri/target/
src-tauri/binaries/
CapacityReportData/
+16 -8
View File
@@ -37,7 +37,8 @@ CapaReport/
├─ frontend/ # Vue 前端
├─ src-tauri/ # Tauri 桌面壳
├─ scripts/ # 一键构建脚本
├─ build/ # Docker 和 PyInstaller 配置
├─ packaging/ # Docker、Compose、PyInstaller 配置
├─ dist/ # 一键构建后的最终产物
├─ docs/project_context.md # 项目维护记录
├─ Configure.json # 应用配置
├─ ReportScript.sql # SQL 处理脚本
@@ -117,6 +118,8 @@ scripts\build.bat docker -SkipDockerBuild
scripts\build.bat all -SkipDesktopBuild
```
构建完成后只保留 `dist/` 下的最终产物;`dist/.tmp`、`frontend/dist`、`src-tauri/target`、`src-tauri/binaries` 等中间产物会自动清理。
### Server Portable
```bat
@@ -126,8 +129,8 @@ scripts\build.bat server
输出:
```text
dist\packages\CapacityReport-Server-windows-x64\
dist\packages\CapacityReport-Server-windows-x64.zip
dist\server\CapacityReport-Server-windows-x64\
dist\server\CapacityReport-Server-windows-x64.zip
```
便携版内包含后端可执行文件、前端构建产物、`Configure.json`、`ReportScript.sql`、`cache/`、`logs/` 和启动脚本。默认监听端口为 `9081`。
@@ -141,8 +144,8 @@ scripts\build.bat desktop
输出:
```text
src-tauri\target\release\bundle\msi\*.msi
src-tauri\target\release\bundle\nsis\*-setup.exe
dist\desktop\*.msi
dist\desktop\*-setup.exe
```
桌面版使用 Tauri 启动 Python sidecar。sidecar 默认监听 `127.0.0.1:19082`,运行数据写入系统 app data 目录,不写入安装目录。
@@ -159,16 +162,21 @@ cargo install tauri-cli --locked
scripts\build.bat docker
```
输出镜像:
输出:
```text
capacity-report-app:latest
dist\docker\capacity-report-app-latest.tar
dist\docker\docker-compose.yml
dist\docker\Configure.json
dist\docker\ReportScript.sql
```
启动:
```bat
docker compose -f build\docker-compose.yml up -d
docker load -i dist\docker\capacity-report-app-latest.tar
docker compose -f dist\docker\docker-compose.yml up -d
```
访问:
@@ -180,7 +188,7 @@ http://localhost:19081
停止:
```bat
docker compose -f build\docker-compose.yml down
docker compose -f dist\docker\docker-compose.yml down
```
## Linux / macOS 构建
-52
View File
@@ -1,52 +0,0 @@
# Git
.git
.gitignore
# Python cache and virtual environments
__pycache__/
*.py[cod]
.venv/
venv/
ENV/
env/
# Frontend local artifacts
frontend/node_modules/
frontend/dist/
frontend/.vite/
# Runtime and package output
cache/
logs/
dist/
uploads/
CapacityReportData/
error.log
*.log
# Build helper output
build/temp/
# Local-only files
.env
.env.local
auth.ini
# Deployment files copied separately by build.py
docker-compose*.yml
Dockerfile*
.dockerignore
# MySQL data
mysql/
# Temporary and OS files
*.tmp
*.temp
.temp/
.DS_Store
Thumbs.db
# Documentation is not required in the runtime image.
*.md
!README.md
-26
View File
@@ -1,26 +0,0 @@
# Build Notes
Use the root scripts for release builds:
```powershell
scripts\build.bat server
scripts\build.bat docker
scripts\build.bat desktop
```
On Linux or macOS:
```bash
sh scripts/build.sh server
sh scripts/build.sh docker
sh scripts/build.sh desktop
```
## Targets
- `server`: builds a portable server package for the current OS.
- `docker`: builds the Docker image and validates the compose file.
- `desktop`: builds a Tauri desktop package with the Python server sidecar.
- `all`: runs all targets.
Native server and desktop packages must be built on the target OS. Build Windows packages on Windows, Linux packages on Linux, and macOS packages on macOS. Docker images can be built from the Windows development host.
+9 -2
View File
@@ -387,7 +387,7 @@
- `app/config.py` supports `CAPAREPORT_BASE_DIR`; frozen PyInstaller server builds default `BASE_DIR` to the executable directory. The Tauri sidecar sets `CAPAREPORT_BASE_DIR` to the app data directory so runtime files are not written into the install directory.
- Tauri startup creates app-data `cache/` and `logs/`, then copies bundled `Configure.json` and `ReportScript.sql` on first run. Resource lookup supports both normal Tauri resources and the `_up_` directory generated for bundled `../` resources.
- Windows desktop shutdown uses `taskkill /F /T /PID` before killing the shell child, which avoids PyInstaller one-file sidecar process leftovers.
- Docker build now copies only required app files and frontend build output. `.dockerignore` excludes local dependencies, caches, build output, and local config; `build/docker-compose.yml` mounts paths relative to the `build/` directory.
- Docker build now copies only required app files and frontend build output. `.dockerignore` excludes local dependencies, caches, and generated output; deployment compose files are emitted under `dist/docker/`.
- `app/main.py` accepts `--host` and `--port` and exposes `run_server()` so portable launchers, Docker, and the Tauri sidecar share the same backend entry point.
- Windows verification completed: `scripts\build.bat server -NoArchive`, `scripts\build.bat server`, `scripts\build.bat docker`, and `scripts\build.bat desktop`. Server portable `/health`, Docker container `/health`, and desktop sidecar `/health` all returned HTTP 200; desktop first run also copied config and SQL into app data.
- Cleanup verification completed: `.venv\Scripts\python.exe -m compileall app`, `npm run build`, PowerShell AST parse for `scripts/build.ps1`, Docker-hosted `sh -n scripts/build.sh`, and `cargo check --manifest-path src-tauri\Cargo.toml` with a temporary sidecar placeholder all passed. Linux/macOS native server and desktop packages still need native OS verification.
@@ -397,6 +397,13 @@
## 2026-05-20: Tauri desktop console and installer language
- `src-tauri/src/main.rs` uses `#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]` so Windows release builds use the GUI subsystem and do not open an extra console window when launched from Explorer or the installer shortcut.
- `build/capareport-server.spec` keeps Server Portable in console mode, but desktop one-file sidecar builds (`CAPAREPORT_ONEFILE=1`) use PyInstaller `console=False`; PyInstaller should select `runw.exe` for the sidecar so it also stays hidden behind the Tauri window.
- `packaging/capareport-server.spec` keeps Server Portable in console mode, but desktop one-file sidecar builds (`CAPAREPORT_ONEFILE=1`) use PyInstaller `console=False`; PyInstaller should select `runw.exe` for the sidecar so it also stays hidden behind the Tauri window.
- `src-tauri/tauri.conf.json` sets Windows installer localization through `bundle.windows.wix.language = "zh-CN"` and `bundle.windows.nsis.languages = ["SimpChinese"]`. NSIS language keys must use NSIS names such as `SimpChinese`, while WiX/MSI uses locale names such as `zh-CN`.
- Verification on Windows: `cargo check --manifest-path src-tauri\Cargo.toml` passed, `scripts\build.bat desktop` generated the MSI and NSIS bundles, PE subsystem checks reported `Windows GUI` for both `capacity-report-desktop.exe` and `capareport-server.exe`, and the generated NSIS script included `MUI_LANGUAGE "SimpChinese"`.
## 2026-05-20: Unified release output under dist
- The former `build/` packaging source directory was renamed to `packaging/` to avoid confusing source-side packaging recipes with generated output. `packaging/` now holds `Dockerfile`, `docker-compose.yml`, the PyInstaller spec, and MySQL container config.
- `scripts/build.ps1` and `scripts/build.sh` now use `dist/.tmp/` for PyInstaller work output and copy final deliverables to `dist/server/`, `dist/desktop/`, and `dist/docker/`. Successful builds remove `dist/.tmp`, `frontend/dist`, `src-tauri/target`, and `src-tauri/binaries`.
- Docker builds now include `Configure.json` in the image and also create a deployable `dist/docker/` bundle containing `capacity-report-app-latest.tar`, `docker-compose.yml`, `Configure.json`, `ReportScript.sql`, `mysql/`, `cache/`, and `logs/`.
- Server Portable still includes `Configure.json` and `ReportScript.sql` inside `dist/server/CapacityReport-Server-<platform>-x64/`. Tauri desktop still bundles both files through `src-tauri/tauri.conf.json` resources and copies them to app data on first run.
+1 -1
View File
@@ -31,7 +31,7 @@ RUN pip install --no-cache-dir -r requirements.txt
RUN mkdir -p /var/log/supervisor /var/run /app/cache
COPY app ./app
COPY ReportScript.sql start.sh supervisord.conf ./
COPY Configure.json ReportScript.sql start.sh supervisord.conf ./
COPY --from=frontend-build /frontend/dist /app/frontend/dist
RUN chmod +x /app/start.sh 2>/dev/null || true
@@ -6,10 +6,10 @@ services:
ports:
- "19081:9081"
volumes:
- ../cache:/app/cache
- ../Configure.json:/app/Configure.json
- ../ReportScript.sql:/app/ReportScript.sql
- ../logs:/var/log/supervisor
- ./cache:/app/cache
- ./Configure.json:/app/Configure.json
- ./ReportScript.sql:/app/ReportScript.sql
- ./logs:/var/log/supervisor
environment:
- TZ=Asia/Shanghai
- PYTHONUNBUFFERED=1
+86 -20
View File
@@ -17,13 +17,16 @@ $ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$Root = Resolve-Path (Join-Path $ScriptDir "..")
$Root = (Resolve-Path (Join-Path $ScriptDir "..")).Path
$DistDir = Join-Path $Root "dist"
$PackageDir = Join-Path $DistDir "packages"
$PyInstallerDir = Join-Path $Root "build\pyinstaller"
$ServerDistDir = Join-Path $DistDir "server"
$DesktopDistDir = Join-Path $DistDir "desktop"
$DockerDistDir = Join-Path $DistDir "docker"
$TempDir = Join-Path $DistDir ".tmp"
$PyInstallerDir = Join-Path $TempDir "pyinstaller"
$FrontendDir = Join-Path $Root "frontend"
$PackagingDir = Join-Path $Root "packaging"
$ServerName = "capareport-server"
$AppVersion = "2.0.2"
$DesktopApiBase = "http://127.0.0.1:19082"
function Write-Step($Message) {
@@ -46,6 +49,21 @@ function Show-Usage {
Write-Host " -SkipDesktopBuild"
}
function Assert-InWorkspace($Path) {
$resolved = (Resolve-Path -LiteralPath $Path).Path
if (!$resolved.StartsWith($Root, [System.StringComparison]::OrdinalIgnoreCase)) {
throw "Refusing to operate outside workspace: $resolved"
}
return $resolved
}
function Remove-Tree($Path) {
if (Test-Path -LiteralPath $Path) {
$resolved = Assert-InWorkspace $Path
Remove-Item -LiteralPath $resolved -Recurse -Force
}
}
function Invoke-Checked($Command, $WorkingDirectory = $Root) {
Write-Info $Command
Push-Location $WorkingDirectory
@@ -136,9 +154,15 @@ function Build-Frontend($ApiBase) {
function Build-ServerBinary([switch]$OneFile) {
Ensure-PythonEnvironment
Write-Step "Building server binary"
Remove-Item -LiteralPath $PyInstallerDir -Recurse -Force -ErrorAction SilentlyContinue
Remove-Tree $PyInstallerDir
New-Item -ItemType Directory -Force -Path $PyInstallerDir | Out-Null
$python = Join-Path $Root ".venv\Scripts\python.exe"
$workPath = Join-Path $PyInstallerDir "work"
$distPath = Join-Path $PyInstallerDir "dist"
$specPath = Join-Path $PackagingDir "capareport-server.spec"
$previousOneFile = $env:CAPAREPORT_ONEFILE
if ($OneFile) {
$env:CAPAREPORT_ONEFILE = "1"
}
@@ -147,7 +171,7 @@ function Build-ServerBinary([switch]$OneFile) {
}
try {
Invoke-Checked "`"$python`" -m PyInstaller --clean --noconfirm --workpath build\pyinstaller\work --distpath build\pyinstaller\dist build\capareport-server.spec" $Root
Invoke-Checked "`"$python`" -m PyInstaller --clean --noconfirm --workpath `"$workPath`" --distpath `"$distPath`" `"$specPath`"" $Root
}
finally {
if ($null -ne $previousOneFile) {
@@ -159,14 +183,14 @@ function Build-ServerBinary([switch]$OneFile) {
}
if ($OneFile) {
$binaryDir = Join-Path $PyInstallerDir "dist"
$binaryDir = $distPath
$binaryPath = Join-Path $binaryDir (Get-ExecutableName (Get-CurrentPlatform))
if (!(Test-Path $binaryPath)) {
throw "PyInstaller output not found: $binaryPath"
}
}
else {
$binaryDir = Join-Path $PyInstallerDir "dist\$ServerName"
$binaryDir = Join-Path $distPath $ServerName
if (!(Test-Path $binaryDir)) {
throw "PyInstaller output not found: $binaryDir"
}
@@ -237,11 +261,14 @@ function Build-ServerPortable {
$platformName = "windows"
}
$outputDir = Join-Path $ServerDistDir "CapacityReport-Server-$platformName-x64"
$archive = "$outputDir.zip"
Remove-Tree $outputDir
Remove-Item -LiteralPath $archive -Force -ErrorAction SilentlyContinue
Build-Frontend $null
$binaryDir = Build-ServerBinary
$outputDir = Join-Path $PackageDir "CapacityReport-Server-$platformName-x64"
Remove-Item -LiteralPath $outputDir -Recurse -Force -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force -Path $outputDir | Out-Null
Copy-Item -Path (Join-Path $binaryDir "*") -Destination $outputDir -Recurse -Force
@@ -249,8 +276,6 @@ function Build-ServerPortable {
Write-ServerLaunchers $outputDir $platformName
if (!$NoArchive) {
$archive = "$outputDir.zip"
Remove-Item -LiteralPath $archive -Force -ErrorAction SilentlyContinue
Compress-Archive -Path (Join-Path $outputDir "*") -DestinationPath $archive -Force
Write-Info "Archive: $archive"
}
@@ -258,15 +283,36 @@ function Build-ServerPortable {
Write-Info "Server package: $outputDir"
}
function Copy-DockerBundle {
Remove-Tree $DockerDistDir
New-Item -ItemType Directory -Force -Path $DockerDistDir | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $DockerDistDir "cache") | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $DockerDistDir "logs") | Out-Null
Copy-Item -Path (Join-Path $PackagingDir "docker-compose.yml") -Destination (Join-Path $DockerDistDir "docker-compose.yml") -Force
Copy-Item -Path (Join-Path $PackagingDir "mysql") -Destination (Join-Path $DockerDistDir "mysql") -Recurse -Force
Copy-Item -Path (Join-Path $Root "Configure.json") -Destination (Join-Path $DockerDistDir "Configure.json") -Force
Copy-Item -Path (Join-Path $Root "ReportScript.sql") -Destination (Join-Path $DockerDistDir "ReportScript.sql") -Force
}
function Build-DockerImage {
Remove-Tree $DockerDistDir
if ($SkipDockerBuild) {
Write-Host "Docker build skipped."
Write-Host "Docker image build skipped."
Copy-DockerBundle
Invoke-Checked "docker compose -f `"$DockerDistDir\docker-compose.yml`" config" $Root
Write-Info "Docker package: $DockerDistDir"
return
}
Write-Step "Building Docker image"
Invoke-Checked "docker build --progress=plain -f build\Dockerfile -t capacity-report-app:latest ." $Root
Invoke-Checked "docker compose -f build\docker-compose.yml config" $Root
Invoke-Checked "docker build --progress=plain -f `"$PackagingDir\Dockerfile`" -t capacity-report-app:latest ." $Root
Write-Step "Packaging Docker output"
Copy-DockerBundle
Invoke-Checked "docker save -o `"$DockerDistDir\capacity-report-app-latest.tar`" capacity-report-app:latest" $Root
Invoke-Checked "docker compose -f `"$DockerDistDir\docker-compose.yml`" config" $Root
Write-Info "Docker package: $DockerDistDir"
}
function Build-DesktopPackage {
@@ -279,6 +325,8 @@ function Build-DesktopPackage {
throw "Rust is required for the Tauri desktop build"
}
Remove-Tree $DesktopDistDir
Build-Frontend $DesktopApiBase
$binaryDir = Build-ServerBinary -OneFile
$platformName = Get-CurrentPlatform
@@ -294,8 +342,23 @@ function Build-DesktopPackage {
Invoke-Checked "cargo install tauri-cli --locked" $Root
}
Remove-Tree (Join-Path $Root "src-tauri\target\release\bundle")
Write-Step "Building Tauri desktop package"
Invoke-Checked "cargo tauri build" (Join-Path $Root "src-tauri")
New-Item -ItemType Directory -Force -Path $DesktopDistDir | Out-Null
$bundleDir = Join-Path $Root "src-tauri\target\release\bundle"
Get-ChildItem -Path $bundleDir -Recurse -File -Include "*.msi", "*.exe" |
Copy-Item -Destination $DesktopDistDir -Force
Write-Info "Desktop package: $DesktopDistDir"
}
function Clean-Intermediates {
Write-Step "Cleaning intermediate output"
Remove-Tree $TempDir
Remove-Tree (Join-Path $Root "frontend\dist")
Remove-Tree (Join-Path $Root "src-tauri\binaries")
Remove-Tree (Join-Path $Root "src-tauri\target")
}
if ($Help) {
@@ -304,13 +367,14 @@ if ($Help) {
}
if ($Clean) {
Write-Step "Cleaning build output"
Remove-Item -LiteralPath $DistDir -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $PyInstallerDir -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath (Join-Path $Root "src-tauri\binaries") -Recurse -Force -ErrorAction SilentlyContinue
Write-Step "Cleaning dist output"
Remove-Tree $DistDir
Remove-Tree (Join-Path $Root "frontend\dist")
Remove-Tree (Join-Path $Root "src-tauri\binaries")
Remove-Tree (Join-Path $Root "src-tauri\target")
}
New-Item -ItemType Directory -Force -Path $PackageDir | Out-Null
New-Item -ItemType Directory -Force -Path $DistDir | Out-Null
switch ($Target) {
"server" { Build-ServerPortable }
@@ -323,4 +387,6 @@ switch ($Target) {
}
}
Clean-Intermediates
Write-Step "Build finished"
+65 -15
View File
@@ -4,7 +4,15 @@ set -eu
TARGET="${1:-server}"
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)"
DIST_DIR="$ROOT/dist"
SERVER_DIST_DIR="$DIST_DIR/server"
DESKTOP_DIST_DIR="$DIST_DIR/desktop"
DOCKER_DIST_DIR="$DIST_DIR/docker"
TMP_DIR="$DIST_DIR/.tmp"
PYINSTALLER_DIR="$TMP_DIR/pyinstaller"
PACKAGING_DIR="$ROOT/packaging"
DESKTOP_API_BASE="http://127.0.0.1:19082"
SERVER_NAME="capareport-server"
cd "$ROOT"
log() {
@@ -24,6 +32,18 @@ platform_name() {
esac
}
server_exe_name() {
case "$(platform_name)" in
windows) printf '%s.exe' "$SERVER_NAME" ;;
*) printf '%s' "$SERVER_NAME" ;;
esac
}
clean_intermediates() {
log "Cleaning intermediate output"
rm -rf "$TMP_DIR" "$ROOT/frontend/dist" "$ROOT/src-tauri/binaries" "$ROOT/src-tauri/target"
}
ensure_python() {
log "Preparing Python environment"
if [ ! -x ".venv/bin/python" ]; then
@@ -49,20 +69,22 @@ build_server_binary() {
mode="${1:-onedir}"
ensure_python
log "Building server binary"
rm -rf build/pyinstaller
rm -rf "$PYINSTALLER_DIR"
mkdir -p "$PYINSTALLER_DIR"
if [ "$mode" = "onefile" ]; then
CAPAREPORT_ONEFILE=1
export CAPAREPORT_ONEFILE
run .venv/bin/python -m PyInstaller --clean --noconfirm \
--workpath build/pyinstaller/work \
--distpath build/pyinstaller/dist \
build/capareport-server.spec
--workpath "$PYINSTALLER_DIR/work" \
--distpath "$PYINSTALLER_DIR/dist" \
"$PACKAGING_DIR/capareport-server.spec"
unset CAPAREPORT_ONEFILE
else
run .venv/bin/python -m PyInstaller --clean --noconfirm \
--workpath build/pyinstaller/work \
--distpath build/pyinstaller/dist \
build/capareport-server.spec
--workpath "$PYINSTALLER_DIR/work" \
--distpath "$PYINSTALLER_DIR/dist" \
"$PACKAGING_DIR/capareport-server.spec"
fi
}
@@ -85,38 +107,64 @@ EOF
build_server() {
platform="$(platform_name)"
exe_name="$(server_exe_name)"
out_dir="$SERVER_DIST_DIR/CapacityReport-Server-$platform-x64"
rm -rf "$out_dir" "$SERVER_DIST_DIR/$(basename "$out_dir").tar.gz"
build_frontend server
build_server_binary onedir
out_dir="dist/packages/CapacityReport-Server-$platform-x64"
rm -rf "$out_dir"
mkdir -p "$out_dir/cache" "$out_dir/logs" "$out_dir/frontend"
cp -R build/pyinstaller/dist/capareport-server/. "$out_dir/"
cp -R "$PYINSTALLER_DIR/dist/$SERVER_NAME/." "$out_dir/"
cp Configure.json ReportScript.sql "$out_dir/"
cp -R frontend/dist "$out_dir/frontend/"
write_launchers "$out_dir" "capareport-server"
(cd "$out_dir/.." && tar -czf "$(basename "$out_dir").tar.gz" "$(basename "$out_dir")")
write_launchers "$out_dir" "$exe_name"
(cd "$SERVER_DIST_DIR" && tar -czf "$(basename "$out_dir").tar.gz" "$(basename "$out_dir")")
log "Server package: $out_dir"
}
copy_docker_bundle() {
rm -rf "$DOCKER_DIST_DIR"
mkdir -p "$DOCKER_DIST_DIR/cache" "$DOCKER_DIST_DIR/logs"
cp "$PACKAGING_DIR/docker-compose.yml" "$DOCKER_DIST_DIR/docker-compose.yml"
cp Configure.json ReportScript.sql "$DOCKER_DIST_DIR/"
cp -R "$PACKAGING_DIR/mysql" "$DOCKER_DIST_DIR/mysql"
}
build_docker() {
rm -rf "$DOCKER_DIST_DIR"
log "Building Docker image"
run docker build --progress=plain -f build/Dockerfile -t capacity-report-app:latest .
run docker compose -f build/docker-compose.yml config
run docker build --progress=plain -f "$PACKAGING_DIR/Dockerfile" -t capacity-report-app:latest .
log "Packaging Docker output"
copy_docker_bundle
run docker save -o "$DOCKER_DIST_DIR/capacity-report-app-latest.tar" capacity-report-app:latest
run docker compose -f "$DOCKER_DIST_DIR/docker-compose.yml" config
log "Docker package: $DOCKER_DIST_DIR"
}
build_desktop() {
rm -rf "$DESKTOP_DIST_DIR"
build_frontend desktop
build_server_binary onefile
triple="$(rustc -vV | awk '/^host:/ {print $2}')"
mkdir -p src-tauri/binaries
cp build/pyinstaller/dist/capareport-server "src-tauri/binaries/capareport-server-$triple"
cp "$PYINSTALLER_DIR/dist/$(server_exe_name)" "src-tauri/binaries/$SERVER_NAME-$triple"
if ! cargo tauri --version >/dev/null 2>&1; then
run cargo install tauri-cli --locked
fi
rm -rf src-tauri/target/release/bundle
(cd src-tauri && run cargo tauri build)
rm -rf "$DESKTOP_DIST_DIR"
mkdir -p "$DESKTOP_DIST_DIR"
find src-tauri/target/release/bundle -type f \( -name '*.msi' -o -name '*.exe' \) -exec cp {} "$DESKTOP_DIST_DIR/" \;
log "Desktop package: $DESKTOP_DIST_DIR"
}
mkdir -p "$DIST_DIR"
case "$TARGET" in
server) build_server ;;
docker) build_docker ;;
@@ -125,4 +173,6 @@ case "$TARGET" in
*) echo "Usage: scripts/build.sh [server|docker|desktop|all]" >&2; exit 1 ;;
esac
clean_intermediates
log "Build finished"