Compare commits
3 Commits
v0.1.0-alp
...
v0.1.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c80500d48 | |||
| 39e3d64654 | |||
| 47a62b1aed |
@@ -160,16 +160,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Login to Gitea Container Registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: ${{ gitea.server_url }}
|
|
||||||
username: ${{ gitea.actor }}
|
|
||||||
password: ${{ secrets.GITEA_TOKEN }}
|
|
||||||
|
|
||||||
- name: Extract version metadata
|
- name: Extract version metadata
|
||||||
id: meta
|
id: meta
|
||||||
run: |
|
run: |
|
||||||
@@ -182,21 +172,37 @@ jobs:
|
|||||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||||
echo "registry=$REGISTRY" >> "$GITHUB_OUTPUT"
|
echo "registry=$REGISTRY" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
# Build tag list: version + latest (only for stable releases)
|
- name: Login to Gitea Container Registry
|
||||||
TAGS="$REGISTRY:$TAG,$REGISTRY:$VERSION"
|
run: |
|
||||||
if ! echo "$TAG" | grep -qE '(alpha|beta|rc)'; then
|
echo "${{ secrets.GITEA_TOKEN }}" | docker login \
|
||||||
TAGS="$TAGS,$REGISTRY:latest"
|
"$(echo '${{ gitea.server_url }}' | sed 's|https\?://||')" \
|
||||||
fi
|
-u "${{ gitea.actor }}" --password-stdin
|
||||||
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build Docker image
|
||||||
uses: docker/build-push-action@v5
|
run: |
|
||||||
with:
|
TAG="${{ gitea.ref_name }}"
|
||||||
context: ./server
|
REGISTRY="${{ steps.meta.outputs.registry }}"
|
||||||
push: true
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
docker build \
|
||||||
labels: |
|
--label "org.opencontainers.image.version=${{ steps.meta.outputs.version }}" \
|
||||||
org.opencontainers.image.version=${{ steps.meta.outputs.version }}
|
--label "org.opencontainers.image.revision=${{ gitea.sha }}" \
|
||||||
org.opencontainers.image.revision=${{ gitea.sha }}
|
-t "$REGISTRY:$TAG" \
|
||||||
cache-from: type=gha
|
-t "$REGISTRY:${{ steps.meta.outputs.version }}" \
|
||||||
cache-to: type=gha,mode=max
|
./server
|
||||||
|
|
||||||
|
# Tag as latest only for stable releases
|
||||||
|
if ! echo "$TAG" | grep -qE '(alpha|beta|rc)'; then
|
||||||
|
docker tag "$REGISTRY:$TAG" "$REGISTRY:latest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Push Docker image
|
||||||
|
run: |
|
||||||
|
TAG="${{ gitea.ref_name }}"
|
||||||
|
REGISTRY="${{ steps.meta.outputs.registry }}"
|
||||||
|
|
||||||
|
docker push "$REGISTRY:$TAG"
|
||||||
|
docker push "$REGISTRY:${{ steps.meta.outputs.version }}"
|
||||||
|
|
||||||
|
if ! echo "$TAG" | grep -qE '(alpha|beta|rc)'; then
|
||||||
|
docker push "$REGISTRY:latest"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -73,11 +73,16 @@ if [ -z "$PTH_FILE" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Uncomment 'import site' and add Lib\site-packages
|
# Uncomment 'import site', add Lib\site-packages and app source path
|
||||||
sed -i 's/^#\s*import site/import site/' "$PTH_FILE"
|
sed -i 's/^#\s*import site/import site/' "$PTH_FILE"
|
||||||
if ! grep -q 'Lib\\site-packages' "$PTH_FILE"; then
|
if ! grep -q 'Lib\\site-packages' "$PTH_FILE"; then
|
||||||
echo 'Lib\site-packages' >> "$PTH_FILE"
|
echo 'Lib\site-packages' >> "$PTH_FILE"
|
||||||
fi
|
fi
|
||||||
|
# Embedded Python ._pth overrides PYTHONPATH, so we must add the app
|
||||||
|
# source directory here for wled_controller to be importable
|
||||||
|
if ! grep -q '\.\./app/src' "$PTH_FILE"; then
|
||||||
|
echo '../app/src' >> "$PTH_FILE"
|
||||||
|
fi
|
||||||
echo " Patched $(basename "$PTH_FILE")"
|
echo " Patched $(basename "$PTH_FILE")"
|
||||||
|
|
||||||
# ── Download pip and install into embedded Python ────────────
|
# ── Download pip and install into embedded Python ────────────
|
||||||
@@ -238,6 +243,9 @@ cd /d "%~dp0"
|
|||||||
set PYTHONPATH=%~dp0app\src
|
set PYTHONPATH=%~dp0app\src
|
||||||
set WLED_CONFIG_PATH=%~dp0app\config\default_config.yaml
|
set WLED_CONFIG_PATH=%~dp0app\config\default_config.yaml
|
||||||
|
|
||||||
|
:: Read port from env var or use default
|
||||||
|
if "%WLED_SERVER__PORT%"=="" set WLED_SERVER__PORT=8080
|
||||||
|
|
||||||
:: Create data directory if missing
|
:: Create data directory if missing
|
||||||
if not exist "%~dp0data" mkdir "%~dp0data"
|
if not exist "%~dp0data" mkdir "%~dp0data"
|
||||||
if not exist "%~dp0logs" mkdir "%~dp0logs"
|
if not exist "%~dp0logs" mkdir "%~dp0logs"
|
||||||
@@ -245,13 +253,13 @@ if not exist "%~dp0logs" mkdir "%~dp0logs"
|
|||||||
echo.
|
echo.
|
||||||
echo =============================================
|
echo =============================================
|
||||||
echo LedGrab v${VERSION_CLEAN}
|
echo LedGrab v${VERSION_CLEAN}
|
||||||
echo Open http://localhost:8080 in your browser
|
echo Open http://localhost:%WLED_SERVER__PORT% in your browser
|
||||||
echo =============================================
|
echo =============================================
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
:: Start the server (open browser after short delay)
|
:: Start the server — uses config from WLED_CONFIG_PATH, port from config or env
|
||||||
start "" /b cmd /c "timeout /t 2 /nobreak >nul && start http://localhost:8080"
|
start "" /b cmd /c "timeout /t 2 /nobreak >nul && start http://localhost:%WLED_SERVER__PORT%"
|
||||||
"%~dp0python\python.exe" -m uvicorn wled_controller.main:app --host 0.0.0.0 --port 8080
|
"%~dp0python\python.exe" -m wled_controller.main
|
||||||
|
|
||||||
pause
|
pause
|
||||||
LAUNCHER
|
LAUNCHER
|
||||||
@@ -259,6 +267,64 @@ LAUNCHER
|
|||||||
# Convert launcher to Windows line endings
|
# Convert launcher to Windows line endings
|
||||||
sed -i 's/$/\r/' "$DIST_DIR/LedGrab.bat"
|
sed -i 's/$/\r/' "$DIST_DIR/LedGrab.bat"
|
||||||
|
|
||||||
|
# ── Create autostart scripts ─────────────────────────────────
|
||||||
|
|
||||||
|
cat > "$DIST_DIR/install-autostart.bat" << 'AUTOSTART'
|
||||||
|
@echo off
|
||||||
|
:: Install LedGrab to start automatically on Windows login
|
||||||
|
:: Creates a shortcut in the Startup folder
|
||||||
|
|
||||||
|
set SHORTCUT_NAME=LedGrab
|
||||||
|
set STARTUP_DIR=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
|
||||||
|
set TARGET=%~dp0LedGrab.bat
|
||||||
|
set SHORTCUT=%STARTUP_DIR%\%SHORTCUT_NAME%.lnk
|
||||||
|
|
||||||
|
echo Installing LedGrab autostart...
|
||||||
|
|
||||||
|
:: Use PowerShell to create a proper shortcut
|
||||||
|
powershell -NoProfile -Command ^
|
||||||
|
"$ws = New-Object -ComObject WScript.Shell; ^
|
||||||
|
$sc = $ws.CreateShortcut('%SHORTCUT%'); ^
|
||||||
|
$sc.TargetPath = '%TARGET%'; ^
|
||||||
|
$sc.WorkingDirectory = '%~dp0'; ^
|
||||||
|
$sc.WindowStyle = 7; ^
|
||||||
|
$sc.Description = 'LedGrab ambient lighting server'; ^
|
||||||
|
$sc.Save()"
|
||||||
|
|
||||||
|
if exist "%SHORTCUT%" (
|
||||||
|
echo.
|
||||||
|
echo [OK] LedGrab will start automatically on login.
|
||||||
|
echo Shortcut: %SHORTCUT%
|
||||||
|
echo.
|
||||||
|
echo To remove: run uninstall-autostart.bat
|
||||||
|
) else (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] Failed to create shortcut.
|
||||||
|
)
|
||||||
|
|
||||||
|
pause
|
||||||
|
AUTOSTART
|
||||||
|
sed -i 's/$/\r/' "$DIST_DIR/install-autostart.bat"
|
||||||
|
|
||||||
|
cat > "$DIST_DIR/uninstall-autostart.bat" << 'UNAUTOSTART'
|
||||||
|
@echo off
|
||||||
|
:: Remove LedGrab from Windows startup
|
||||||
|
|
||||||
|
set SHORTCUT=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\LedGrab.lnk
|
||||||
|
|
||||||
|
if exist "%SHORTCUT%" (
|
||||||
|
del "%SHORTCUT%"
|
||||||
|
echo.
|
||||||
|
echo [OK] LedGrab autostart removed.
|
||||||
|
) else (
|
||||||
|
echo.
|
||||||
|
echo LedGrab autostart was not installed.
|
||||||
|
)
|
||||||
|
|
||||||
|
pause
|
||||||
|
UNAUTOSTART
|
||||||
|
sed -i 's/$/\r/' "$DIST_DIR/uninstall-autostart.bat"
|
||||||
|
|
||||||
# ── Create ZIP ───────────────────────────────────────────────
|
# ── Create ZIP ───────────────────────────────────────────────
|
||||||
|
|
||||||
ZIP_PATH="$BUILD_DIR/$ZIP_NAME"
|
ZIP_PATH="$BUILD_DIR/$ZIP_NAME"
|
||||||
|
|||||||
@@ -106,6 +106,11 @@ $pthContent = $pthContent -replace '#\s*import site', 'import site'
|
|||||||
if ($pthContent -notmatch 'Lib\\site-packages') {
|
if ($pthContent -notmatch 'Lib\\site-packages') {
|
||||||
$pthContent = $pthContent.TrimEnd() + "`nLib\site-packages`n"
|
$pthContent = $pthContent.TrimEnd() + "`nLib\site-packages`n"
|
||||||
}
|
}
|
||||||
|
# Embedded Python ._pth overrides PYTHONPATH, so add the app source path
|
||||||
|
# directly for wled_controller to be importable
|
||||||
|
if ($pthContent -notmatch '\.\.[/\\]app[/\\]src') {
|
||||||
|
$pthContent = $pthContent.TrimEnd() + "`n..\app\src`n"
|
||||||
|
}
|
||||||
Set-Content -Path $pthFile.FullName -Value $pthContent -NoNewline
|
Set-Content -Path $pthFile.FullName -Value $pthContent -NoNewline
|
||||||
Write-Host " Patched $($pthFile.Name)"
|
Write-Host " Patched $($pthFile.Name)"
|
||||||
|
|
||||||
|
|||||||
@@ -101,22 +101,112 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|||||||
export PYTHONPATH="$SCRIPT_DIR/app/src"
|
export PYTHONPATH="$SCRIPT_DIR/app/src"
|
||||||
export WLED_CONFIG_PATH="$SCRIPT_DIR/app/config/default_config.yaml"
|
export WLED_CONFIG_PATH="$SCRIPT_DIR/app/config/default_config.yaml"
|
||||||
|
|
||||||
|
# Read port from env var or use default
|
||||||
|
PORT="${WLED_SERVER__PORT:-8080}"
|
||||||
|
|
||||||
mkdir -p "$SCRIPT_DIR/data" "$SCRIPT_DIR/logs"
|
mkdir -p "$SCRIPT_DIR/data" "$SCRIPT_DIR/logs"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " ============================================="
|
echo " ============================================="
|
||||||
echo " LedGrab vVERSION_PLACEHOLDER"
|
echo " LedGrab vVERSION_PLACEHOLDER"
|
||||||
echo " Open http://localhost:8080 in your browser"
|
echo " Open http://localhost:$PORT in your browser"
|
||||||
echo " ============================================="
|
echo " ============================================="
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
source "$SCRIPT_DIR/venv/bin/activate"
|
source "$SCRIPT_DIR/venv/bin/activate"
|
||||||
exec python -m uvicorn wled_controller.main:app --host 0.0.0.0 --port 8080
|
exec python -m wled_controller.main
|
||||||
LAUNCHER
|
LAUNCHER
|
||||||
|
|
||||||
sed -i "s/VERSION_PLACEHOLDER/${VERSION_CLEAN}/" "$DIST_DIR/run.sh"
|
sed -i "s/VERSION_PLACEHOLDER/${VERSION_CLEAN}/" "$DIST_DIR/run.sh"
|
||||||
chmod +x "$DIST_DIR/run.sh"
|
chmod +x "$DIST_DIR/run.sh"
|
||||||
|
|
||||||
|
# ── Create autostart scripts ─────────────────────────────────
|
||||||
|
|
||||||
|
cat > "$DIST_DIR/install-service.sh" << 'SERVICE_INSTALL'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
SERVICE_NAME="ledgrab"
|
||||||
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||||
|
RUN_SCRIPT="$SCRIPT_DIR/run.sh"
|
||||||
|
CURRENT_USER="$(whoami)"
|
||||||
|
|
||||||
|
if [ "$EUID" -ne 0 ] && [ "$CURRENT_USER" != "root" ]; then
|
||||||
|
echo "This script requires root privileges. Re-running with sudo..."
|
||||||
|
exec sudo "$0" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Resolve the actual user (not root) when run via sudo
|
||||||
|
ACTUAL_USER="${SUDO_USER:-$CURRENT_USER}"
|
||||||
|
ACTUAL_HOME=$(eval echo "~$ACTUAL_USER")
|
||||||
|
|
||||||
|
echo "Installing LedGrab systemd service..."
|
||||||
|
|
||||||
|
cat > "$SERVICE_FILE" << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=LedGrab ambient lighting server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=$ACTUAL_USER
|
||||||
|
WorkingDirectory=$SCRIPT_DIR
|
||||||
|
ExecStart=$RUN_SCRIPT
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
Environment=HOME=$ACTUAL_HOME
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable "$SERVICE_NAME"
|
||||||
|
systemctl start "$SERVICE_NAME"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " [OK] LedGrab service installed and started."
|
||||||
|
echo ""
|
||||||
|
echo " Commands:"
|
||||||
|
echo " sudo systemctl status $SERVICE_NAME # Check status"
|
||||||
|
echo " sudo systemctl stop $SERVICE_NAME # Stop"
|
||||||
|
echo " sudo systemctl restart $SERVICE_NAME # Restart"
|
||||||
|
echo " sudo journalctl -u $SERVICE_NAME -f # View logs"
|
||||||
|
echo ""
|
||||||
|
echo " To remove: run ./uninstall-service.sh"
|
||||||
|
SERVICE_INSTALL
|
||||||
|
chmod +x "$DIST_DIR/install-service.sh"
|
||||||
|
|
||||||
|
cat > "$DIST_DIR/uninstall-service.sh" << 'SERVICE_UNINSTALL'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SERVICE_NAME="ledgrab"
|
||||||
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||||
|
|
||||||
|
if [ "$EUID" -ne 0 ] && [ "$(whoami)" != "root" ]; then
|
||||||
|
echo "This script requires root privileges. Re-running with sudo..."
|
||||||
|
exec sudo "$0" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$SERVICE_FILE" ]; then
|
||||||
|
echo "LedGrab service is not installed."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Removing LedGrab systemd service..."
|
||||||
|
|
||||||
|
systemctl stop "$SERVICE_NAME" 2>/dev/null || true
|
||||||
|
systemctl disable "$SERVICE_NAME" 2>/dev/null || true
|
||||||
|
rm -f "$SERVICE_FILE"
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " [OK] LedGrab service removed."
|
||||||
|
SERVICE_UNINSTALL
|
||||||
|
chmod +x "$DIST_DIR/uninstall-service.sh"
|
||||||
|
|
||||||
# ── Create tarball ───────────────────────────────────────────
|
# ── Create tarball ───────────────────────────────────────────
|
||||||
|
|
||||||
echo "[7/7] Creating $TAR_NAME..."
|
echo "[7/7] Creating $TAR_NAME..."
|
||||||
|
|||||||
Reference in New Issue
Block a user