Debian trixie-based build-compile-deploy workflow

This commit is contained in:
Mikkeli Matlock
2026-01-24 23:18:37 +09:00
parent 90ed757976
commit aabca4915c
8 changed files with 311 additions and 36 deletions

View File

@@ -11,16 +11,62 @@ UI_DIR="$PROJECT_ROOT/pi/ui"
echo "=== Smart Serow Build ==="
echo "Project: $UI_DIR"
# Check for flutter-elinux
if ! command -v flutter-elinux &> /dev/null; then
echo "ERROR: flutter-elinux not found in PATH"
echo "Install it or check your PATH"
echo ""
echo "Current PATH: $PATH"
which flutter 2>/dev/null && echo "Found flutter at: $(which flutter)"
exit 1
fi
echo "Using: $(which flutter-elinux)"
# Cross-compilation toolchain for ARM64
export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export AR=aarch64-linux-gnu-ar
export LD=aarch64-linux-gnu-ld
# CMake-specific vars
export CMAKE_C_COMPILER=aarch64-linux-gnu-gcc
export CMAKE_CXX_COMPILER=aarch64-linux-gnu-g++
echo "Cross-compiler: $CXX"
cd "$UI_DIR"
# Clean previous build (optional, comment out for faster incremental builds)
# flutter-elinux clean
# Initialize elinux project if not already configured
if [ ! -d "elinux" ]; then
echo "Initializing elinux project structure..."
flutter-elinux create . --project-name smartserow_ui --org com.smartserow
fi
# Clean CMake cache on --clean flag
# (CMake caches compiler choice, so stale cache = wrong linker)
if [ "${1:-}" = "--clean" ]; then
echo "Cleaning CMake cache..."
rm -rf build/elinux/arm64
fi
echo "Fetching dependencies..."
flutter-elinux pub get
echo "Building for ARM64 (elinux)..."
flutter-elinux build elinux --target-arch=arm64 --release
echo "Building for ARM64 (elinux) with DRM-GBM backend..."
# Use Pi sysroot if available (for proper cross-linking)
SYSROOT_FLAG=""
if [ -d "$PROJECT_ROOT/pi_sysroot" ]; then
echo "Using Pi sysroot: $PROJECT_ROOT/pi_sysroot"
SYSROOT_FLAG="--target-sysroot=$PROJECT_ROOT/pi_sysroot"
fi
flutter-elinux build elinux \
--target-arch=arm64 \
--target-backend-type=gbm \
--target-compiler-triple=aarch64-linux-gnu \
$SYSROOT_FLAG \
--release
BUILD_OUTPUT="$UI_DIR/build/elinux/arm64/release/bundle"

View File

@@ -14,14 +14,21 @@ if [ ! -f "$CONFIG_FILE" ]; then
exit 1
fi
HOST=$(jq -r '.host' "$CONFIG_FILE")
REMOTE_PATH=$(jq -r '.remote_path' "$CONFIG_FILE")
SERVICE_NAME=$(jq -r '.service_name' "$CONFIG_FILE")
# Parse JSON with Python (more universal than jq)
read_json() {
python3 -c "import json; print(json.load(open('$CONFIG_FILE'))['$1'])"
}
PI_USER=$(read_json user)
PI_HOST=$(read_json host)
REMOTE_PATH=$(read_json remote_path)
SERVICE_NAME=$(read_json service_name)
SSH_TARGET="$PI_USER@$PI_HOST"
BUILD_DIR="$PROJECT_ROOT/pi/ui/build/elinux/arm64/release/bundle"
echo "=== Smart Serow Deploy ==="
echo "Target: $HOST:$REMOTE_PATH"
echo "Target: $SSH_TARGET:$REMOTE_PATH"
echo "Source: $BUILD_DIR"
if [ ! -d "$BUILD_DIR" ]; then
@@ -34,20 +41,20 @@ echo ""
echo "Syncing files..."
rsync -avz --delete \
"$BUILD_DIR/" \
"$HOST:$REMOTE_PATH/bundle/"
"$SSH_TARGET:$REMOTE_PATH/bundle/"
# Restart service if requested
RESTART="${1:-}"
if [ "$RESTART" = "--restart" ] || [ "$RESTART" = "-r" ]; then
echo ""
echo "Restarting service: $SERVICE_NAME"
ssh "$HOST" "sudo systemctl restart $SERVICE_NAME"
ssh "$SSH_TARGET" "sudo systemctl restart $SERVICE_NAME"
sleep 2
ssh "$HOST" "systemctl status $SERVICE_NAME --no-pager"
ssh "$SSH_TARGET" "systemctl status $SERVICE_NAME --no-pager"
else
echo ""
echo "Deploy complete. To restart service, run:"
echo " ssh $HOST 'sudo systemctl restart $SERVICE_NAME'"
echo " ssh $SSH_TARGET 'sudo systemctl restart $SERVICE_NAME'"
echo ""
echo "Or run this script with --restart flag"
fi

View File

@@ -1,5 +1,6 @@
{
"host": "pi@smartserow.local",
"user": "mikkeli",
"host": "192.168.2.102",
"remote_path": "/opt/smartserow",
"service_name": "smartserow-ui"
}

View File

@@ -6,6 +6,11 @@ set -e
echo "=== Smart Serow Pi Setup ==="
# Use current user (whoever is running this script on the Pi)
PI_USER="${USER:-$(whoami)}"
PI_UID=$(id -u "$PI_USER")
echo "Setting up for user: $PI_USER (uid: $PI_UID)"
# Check if running on Pi (arm architecture)
ARCH=$(uname -m)
if [[ "$ARCH" != "aarch64" && "$ARCH" != "armv7l" ]]; then
@@ -15,11 +20,12 @@ fi
APP_DIR="/opt/smartserow"
SERVICE_FILE="/etc/systemd/system/smartserow-ui.service"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Create app directory
echo "Creating app directory: $APP_DIR"
sudo mkdir -p "$APP_DIR/bundle"
sudo chown -R pi:pi "$APP_DIR"
sudo chown -R "$PI_USER:$PI_USER" "$APP_DIR"
# Install runtime dependencies for flutter-elinux
echo "Installing runtime dependencies..."
@@ -41,11 +47,15 @@ sudo apt-get install -y \
libx11-6 \
libxkbcommon-x11-0
# Copy systemd service
# Generate systemd service with correct user
echo "Installing systemd service..."
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "$SCRIPT_DIR/smartserow-ui.service" ]; then
sudo cp "$SCRIPT_DIR/smartserow-ui.service" "$SERVICE_FILE"
# Patch the template with actual user values
sed -e "s/User=.*/User=$PI_USER/" \
-e "s/Group=.*/Group=$PI_USER/" \
-e "s|HOME=/home/.*|HOME=/home/$PI_USER|" \
-e "s|XDG_RUNTIME_DIR=/run/user/.*|XDG_RUNTIME_DIR=/run/user/$PI_UID|" \
"$SCRIPT_DIR/smartserow-ui.service" | sudo tee "$SERVICE_FILE" > /dev/null
else
echo "WARNING: Service file not found at $SCRIPT_DIR/smartserow-ui.service"
echo "Copy it manually to $SERVICE_FILE"
@@ -56,11 +66,11 @@ echo "Enabling service..."
sudo systemctl daemon-reload
sudo systemctl enable smartserow-ui
# Add pi user to required groups for DRM/KMS access
echo "Setting up permissions..."
sudo usermod -aG video pi
sudo usermod -aG input pi
sudo usermod -aG render pi 2>/dev/null || true
# Add user to required groups for DRM/KMS access
echo "Setting up permissions for $PI_USER..."
sudo usermod -aG video "$PI_USER"
sudo usermod -aG input "$PI_USER"
sudo usermod -aG render "$PI_USER" 2>/dev/null || true
echo ""
echo "=== Setup Complete ==="

View File

@@ -5,12 +5,13 @@ Wants=multi-user.target
[Service]
Type=simple
User=pi
Group=pi
User=mikkeli
Group=mikkeli
WorkingDirectory=/opt/smartserow/bundle
# DRM/KMS backend for direct framebuffer (no X11 needed)
ExecStart=/opt/smartserow/bundle/smartserow_ui -b drm
# GBM backend is compiled in. Just specify bundle path.
# Scale factor 2.5 for 5.5" 1080p screen (high DPI)
ExecStart=/opt/smartserow/bundle/smartserow_ui --bundle=/opt/smartserow/bundle --force-scale-factor=2.5
# Restart on crash
Restart=always
@@ -18,7 +19,8 @@ RestartSec=3
# Environment for DRM/KMS access
Environment=XDG_RUNTIME_DIR=/run/user/1000
Environment=HOME=/home/pi
Environment=HOME=/home/mikkeli
Environment=LD_LIBRARY_PATH=/opt/smartserow/bundle/lib
# Give time for GPU to initialize on boot
ExecStartPre=/bin/sleep 2