diff --git a/CHANGELOG.md b/CHANGELOG.md index ad9a64506..63e262741 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ All notable changes to Bambuddy will be documented in this file. ### Fixed - **Queue Stuck on "Busy" for "Any Model" Jobs** ([#435](https://github.com/maziggy/bambuddy/issues/435)) — When a print was queued with "Any [Model]" (e.g., "Any P1S"), it was created with `printer_id=NULL` and `target_model="P1S"`. After the assigned printer finished, the queue widget queried only for items matching `printer_id=X`, missing the next pending model-based item (`printer_id IS NULL`). With no next item found, the "Clear Plate & Start Next" button never appeared, leaving the scheduler stuck reporting "Busy". The queue API now accepts an optional `target_model` parameter; when combined with `printer_id`, it uses OR logic to also return unassigned items whose `target_model` matches the printer's model. The frontend passes the printer's model through to this query. +### New Features +- **Include Beta Updates Setting** — New toggle in Settings → Updates to opt in to beta/prerelease update notifications. Default: off (stable only). The update checker now fetches `/releases` instead of `/releases/latest` and filters by `parse_version()` prerelease detection (not GitHub's `prerelease` flag, which may not be set correctly). Users on the Docker `latest` tag will no longer see notifications for beta releases they can't install. + ## [0.2.1b] - 2026-02-19 ### Fixed diff --git a/backend/app/api/routes/settings.py b/backend/app/api/routes/settings.py index 8e8a094be..fa32038d2 100644 --- a/backend/app/api/routes/settings.py +++ b/backend/app/api/routes/settings.py @@ -89,6 +89,7 @@ async def get_settings( "spoolman_report_partial_usage", "check_updates", "check_printer_firmware", + "include_beta_updates", "virtual_printer_enabled", "ftp_retry_enabled", "mqtt_enabled", diff --git a/backend/app/api/routes/updates.py b/backend/app/api/routes/updates.py index 1580c5fac..4861e4531 100644 --- a/backend/app/api/routes/updates.py +++ b/backend/app/api/routes/updates.py @@ -189,6 +189,11 @@ async def check_for_updates( "message": "Update checks are disabled", } + # Check if beta updates should be included + result = await db.execute(select(Settings).where(Settings.key == "include_beta_updates")) + beta_setting = result.scalar_one_or_none() + include_beta = beta_setting and beta_setting.value.lower() == "true" + _update_status = { "status": "checking", "progress": 0, @@ -199,7 +204,7 @@ async def check_for_updates( try: async with httpx.AsyncClient() as client: response = await client.get( - f"https://api.github.com/repos/{GITHUB_REPO}/releases/latest", + f"https://api.github.com/repos/{GITHUB_REPO}/releases?per_page=20", headers={"Accept": "application/vnd.github.v3+json"}, timeout=10.0, ) @@ -220,7 +225,36 @@ async def check_for_updates( } response.raise_for_status() - release_data = response.json() + releases = response.json() + + # Find the appropriate release based on beta setting + release_data = None + for release in releases: + tag = release.get("tag_name", "") + if include_beta: + # Accept any release (first = newest) + release_data = release + break + else: + # Skip prereleases (based on version parsing, not GitHub flag) + parsed = parse_version(tag) + if parsed[4] == 0: # is_prerelease == 0 + release_data = release + break + + if not release_data: + _update_status = { + "status": "idle", + "progress": 100, + "message": "No releases found", + "error": None, + } + return { + "update_available": False, + "current_version": APP_VERSION, + "latest_version": None, + "message": "No releases found", + } latest_version = release_data.get("tag_name", "").lstrip("v") release_name = release_data.get("name", latest_version) diff --git a/backend/app/schemas/settings.py b/backend/app/schemas/settings.py index 995b3db0d..b6d3fd97a 100644 --- a/backend/app/schemas/settings.py +++ b/backend/app/schemas/settings.py @@ -35,6 +35,7 @@ class AppSettings(BaseModel): # Updates check_updates: bool = Field(default=True, description="Automatically check for updates on startup") check_printer_firmware: bool = Field(default=True, description="Check for printer firmware updates from Bambu Lab") + include_beta_updates: bool = Field(default=False, description="Include beta/prerelease versions in update checks") # Language notification_language: str = Field(default="en", description="Language for push notifications (en, de)") @@ -165,6 +166,7 @@ class AppSettingsUpdate(BaseModel): spoolman_report_partial_usage: bool | None = None check_updates: bool | None = None check_printer_firmware: bool | None = None + include_beta_updates: bool | None = None notification_language: str | None = None bed_cooled_threshold: float | None = None ams_humidity_good: int | None = None diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 424dc0264..2e75c3ebe 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -761,6 +761,7 @@ export interface AppSettings { energy_tracking_mode: 'print' | 'total'; check_updates: boolean; check_printer_firmware: boolean; + include_beta_updates: boolean; notification_language: string; // AMS threshold settings ams_humidity_good: number; // <= this is green diff --git a/frontend/src/i18n/locales/de.ts b/frontend/src/i18n/locales/de.ts index ebf9aa67f..f8e1de252 100644 --- a/frontend/src/i18n/locales/de.ts +++ b/frontend/src/i18n/locales/de.ts @@ -1259,6 +1259,8 @@ export default { // Updates checkForUpdatesLabel: 'Nach Updates suchen', checkPrinterFirmware: 'Drucker-Firmware prüfen', + includeBetaUpdates: 'Beta-Versionen einschließen', + includeBetaUpdatesDesc: 'Über Beta- und Vorabversionen bei der Updateprüfung benachrichtigen', // Queue enableRetry: 'Wiederholung aktivieren', // Home Assistant diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 9b1d002eb..4606a940b 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -1259,6 +1259,8 @@ export default { // Updates checkForUpdatesLabel: 'Check for updates', checkPrinterFirmware: 'Check printer firmware', + includeBetaUpdates: 'Include beta versions', + includeBetaUpdatesDesc: 'Notify about beta and prerelease versions when checking for updates', // Queue enableRetry: 'Enable retry', // Home Assistant diff --git a/frontend/src/i18n/locales/fr.ts b/frontend/src/i18n/locales/fr.ts index 337d624fb..fd6e12183 100644 --- a/frontend/src/i18n/locales/fr.ts +++ b/frontend/src/i18n/locales/fr.ts @@ -1247,6 +1247,8 @@ export default { // Updates checkForUpdatesLabel: 'Vérifier les mises à jour', checkPrinterFirmware: 'Vérifier le firmware imprimante', + includeBetaUpdates: 'Inclure les versions bêta', + includeBetaUpdatesDesc: 'Notifier des versions bêta et préliminaires lors de la vérification des mises à jour', // Queue enableRetry: 'Activer la rétentative', // Home Assistant diff --git a/frontend/src/i18n/locales/it.ts b/frontend/src/i18n/locales/it.ts index 4d8d2ca97..8c624e666 100644 --- a/frontend/src/i18n/locales/it.ts +++ b/frontend/src/i18n/locales/it.ts @@ -1151,6 +1151,8 @@ export default { // Updates checkForUpdatesLabel: 'Controlla aggiornamenti', checkPrinterFirmware: 'Controlla firmware stampante', + includeBetaUpdates: 'Includi versioni beta', + includeBetaUpdatesDesc: 'Notifica versioni beta e prerelease durante il controllo aggiornamenti', // Queue enableRetry: 'Abilita retry', // Home Assistant diff --git a/frontend/src/i18n/locales/ja.ts b/frontend/src/i18n/locales/ja.ts index c9e11326b..a0aa76673 100644 --- a/frontend/src/i18n/locales/ja.ts +++ b/frontend/src/i18n/locales/ja.ts @@ -1248,6 +1248,8 @@ export default { captureFinishPhoto: '完了写真を撮影', noPrintersConfigured: 'プリンターが設定されていません', checkPrinterFirmware: 'プリンターファームウェアの確認', + includeBetaUpdates: 'ベータ版を含める', + includeBetaUpdatesDesc: 'アップデート確認時にベータ版およびプレリリース版を通知する', enableRetry: 'リトライを有効化', homeAssistantDescription: 'Home Assistantに接続してHA REST APIでスマートプラグを制御します。switch、light、input_booleanエンティティに対応しています。', environmentManagedLabel: '(環境変数で管理)', diff --git a/frontend/src/i18n/locales/pt-BR.ts b/frontend/src/i18n/locales/pt-BR.ts index 24d45987d..fce5e742d 100644 --- a/frontend/src/i18n/locales/pt-BR.ts +++ b/frontend/src/i18n/locales/pt-BR.ts @@ -1259,6 +1259,8 @@ export default { // Updates checkForUpdatesLabel: 'Verificar atualizações', checkPrinterFirmware: 'Verificar firmware da impressora', + includeBetaUpdates: 'Incluir versões beta', + includeBetaUpdatesDesc: 'Notificar sobre versões beta e pré-lançamento ao verificar atualizações', // Queue enableRetry: 'Habilitar tentativa', // Home Assistant diff --git a/frontend/src/pages/SettingsPage.tsx b/frontend/src/pages/SettingsPage.tsx index 1817a2194..b2532e189 100644 --- a/frontend/src/pages/SettingsPage.tsx +++ b/frontend/src/pages/SettingsPage.tsx @@ -699,6 +699,7 @@ export function SettingsPage() { settings.energy_tracking_mode !== localSettings.energy_tracking_mode || settings.check_updates !== localSettings.check_updates || (settings.check_printer_firmware ?? true) !== (localSettings.check_printer_firmware ?? true) || + (settings.include_beta_updates ?? false) !== (localSettings.include_beta_updates ?? false) || settings.notification_language !== localSettings.notification_language || (settings.bed_cooled_threshold ?? 35) !== (localSettings.bed_cooled_threshold ?? 35) || settings.ams_humidity_good !== localSettings.ams_humidity_good || @@ -764,6 +765,7 @@ export function SettingsPage() { energy_tracking_mode: localSettings.energy_tracking_mode, check_updates: localSettings.check_updates, check_printer_firmware: localSettings.check_printer_firmware, + include_beta_updates: localSettings.include_beta_updates, notification_language: localSettings.notification_language, bed_cooled_threshold: localSettings.bed_cooled_threshold, ams_humidity_good: localSettings.ams_humidity_good, @@ -1654,6 +1656,24 @@ export function SettingsPage() {
+{t('settings.includeBetaUpdates')}
++ {t('settings.includeBetaUpdatesDesc')} +
+