mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-07-21 20:31:28 +00:00
Adds a self-update engine for the Linux AppImage build. There's no Velopack pipeline for Linux (Windows/macOS use it, Linux doesn't), so this is a small, purpose-built GitHub-releases checker instead: - On the nightly channel, compares the commit baked into the running build (dist/main/build-info.json, written at build time) against the published nightly's target_commitish. A mismatch means the running build is behind, so it's offered as an update — this sidesteps the fact that the AppImage's filename and app.getVersion() never change between nightly builds, so semver comparison can't detect a new one. - The check returns immediately and the ~1.5GB download runs in the background with live progress (a new update:progress IPC event), so the UI never blocks or freezes waiting on it. - The download streams straight to disk (no buffering the whole file in memory) and is swapped in with an atomic rename next to the running AppImage. The stale-generation check (a channel switch or new check invalidating an in-flight download) runs before that swap, and a failed or superseded download always cleans up its temp file. - Applying the update spawns the (already-swapped-in) AppImage as a detached process and waits for a real 'spawn' confirmation before quitting this one, rather than assuming success — child_process.spawn can fail asynchronously, and quitting on an unconfirmed relaunch could leave the user with nothing running. - The pure idle/staged/download decision is split into linux-update-decision.ts with a small truth-table test, and every main-process decision point (and the equivalent renderer-side actions, in the companion feedBack PR) is traced through a new update:diag IPC event that lands in the app's existing "Export Diagnostics" console-capture bundle — this is how the handful of real bugs below were actually root-caused, from real device captures rather than guesswork. Also removes a forgotten, dead second implementation of the update-channel UI (src/renderer/screen.js's setupUpdateChannelControls() + its markup in settings.html), left over from before this work discovered the real, visible System-tab update UI lives in the feedBack repo. It was still wired up in the audio_engine plugin's own settings panel and silently called setChannel() with a stale channel value every time that panel rendered — invisibly corrupting the real UI's state. This was the actual root cause of several rounds of flaky, hard-to-reproduce on-device behavior (a stuck "unsupported" warning, downloads starting without an explicit check, etc.) chased down via the diagnostic tracing above; once found, no other logic needed to change. Dev tooling only, not used by CI: forces --platform linux/amd64 in the local Docker build wrapper (the Linux target is x86_64-only end to end — needed on Apple Silicon, where Rosetta chokes on a foreign-arch binary inside an otherwise-native container) and adds a SLOPSMITH_REPO override so a contributor without push access to the core repo can bundle a fork branch for a local test build. Verified end-to-end on a Steam Deck across many build/deploy rounds: fresh launch, channel selection, check, background download with live progress, atomic swap, and relaunch onto the new build — confirmed via a real Export Diagnostics capture showing a clean, fully-accounted-for trace with zero orphaned state transitions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
117 lines
3.6 KiB
Bash
Executable File
117 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# Docker-based Linux build wrapper
|
|
# Runs build-linux-ubuntu.sh inside a reproducible container
|
|
#
|
|
# --platform linux/amd64 is forced on both build and run: the Linux target is
|
|
# x86_64-only end to end (bundle-python.sh's python-build-standalone pin,
|
|
# vgmstream, onnxruntime, etc. have no arm64 Linux build, and Steam Deck
|
|
# itself is x86_64). On an Apple Silicon host, omitting --platform makes
|
|
# `docker build` produce a native arm64 image, so bundle-python.sh's hardcoded
|
|
# x86_64 download becomes a foreign-arch binary inside an otherwise-native
|
|
# container — Rosetta chokes trying to exec it directly instead of via full
|
|
# amd64 emulation. Forcing amd64 for the whole container sidesteps that.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
DEVCONTAINER_DIR="$PROJECT_DIR/.devcontainer"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
echo "=== Slopsmith Desktop Docker Build ==="
|
|
echo ""
|
|
echo "This script provides reproducible Linux builds by running"
|
|
echo "build-linux-ubuntu.sh inside a Docker container."
|
|
echo ""
|
|
|
|
# Check prerequisites
|
|
echo -e "${BLUE}Checking prerequisites...${NC}"
|
|
|
|
if ! command -v docker &>/dev/null; then
|
|
echo -e "${RED}Error: Docker is not installed${NC}" >&2
|
|
echo "Install: https://docs.docker.com/get-docker/" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! docker info &>/dev/null; then
|
|
echo -e "${RED}Error: Docker daemon is not running${NC}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}✓${NC} Docker available"
|
|
echo ""
|
|
|
|
# Build container image
|
|
echo -e "${BLUE}Building container image...${NC}"
|
|
echo " (This will take a few minutes on first run)"
|
|
echo ""
|
|
|
|
docker build \
|
|
--platform linux/amd64 \
|
|
-f "$DEVCONTAINER_DIR/Dockerfile" \
|
|
-t slopsmith-ubuntu-builder \
|
|
"$PROJECT_DIR"
|
|
# `set -e` at the top of this script already aborts on a failed
|
|
# `docker build` — no manual `$?` check needed (and the check that
|
|
# was here would in practice be unreachable).
|
|
|
|
echo -e "${GREEN}✓${NC} Container image built"
|
|
echo ""
|
|
|
|
# Clear stale CMake build cache. CMakeCache.txt bakes in the build path;
|
|
# when the project is mounted at a different path inside the container the
|
|
# paths don't match and cmake aborts. A clean build/ guarantees consistency.
|
|
if [[ -d "$PROJECT_DIR/build" ]]; then
|
|
echo -e "${BLUE}Clearing stale CMake cache...${NC}"
|
|
rm -rf "$PROJECT_DIR/build"
|
|
fi
|
|
|
|
# Generate unique container name
|
|
CONTAINER_NAME="slopsmith-build-$(date +%s)-$$-$RANDOM"
|
|
|
|
echo -e "${BLUE}Running build in container...${NC}"
|
|
echo -e "${BLUE}Container name:${NC} $CONTAINER_NAME"
|
|
echo ""
|
|
echo "The container will be preserved after the build to allow debugging."
|
|
echo "Clean up when done:"
|
|
echo " docker stop $CONTAINER_NAME && docker rm $CONTAINER_NAME"
|
|
echo ""
|
|
|
|
set +e
|
|
docker run \
|
|
--platform linux/amd64 \
|
|
--name "$CONTAINER_NAME" \
|
|
-v "$PROJECT_DIR:/workspace" \
|
|
-w /workspace \
|
|
-e ELECTRON_CACHE=/home/vscode/.cache/electron \
|
|
-e ELECTRON_BUILDER_CACHE=/home/vscode/.cache/electron-builder \
|
|
-e GIT_TERMINAL_PROMPT=0 \
|
|
-e "GH_CLONE_TOKEN=${GH_CLONE_TOKEN:-}" \
|
|
-e "SLOPSMITH_REF=${SLOPSMITH_REF:-main}" \
|
|
-e "SLOPSMITH_REPO=${SLOPSMITH_REPO:-got-feedback/feedback}" \
|
|
-t \
|
|
slopsmith-ubuntu-builder \
|
|
bash -c './scripts/build-linux-ubuntu.sh'
|
|
BUILD_EXIT_CODE=$?
|
|
set -e
|
|
|
|
echo ""
|
|
if [[ $BUILD_EXIT_CODE -eq 0 ]]; then
|
|
echo -e "${GREEN}✓${NC} Build completed successfully!"
|
|
else
|
|
echo -e "${RED}✗${NC} Build failed (exit code: $BUILD_EXIT_CODE)"
|
|
echo ""
|
|
echo "To debug:"
|
|
echo " docker exec -it $CONTAINER_NAME /bin/bash"
|
|
echo " docker logs $CONTAINER_NAME"
|
|
echo ""
|
|
fi
|
|
|
|
exit $BUILD_EXIT_CODE
|