feat(updater): auto-update for non-Docker standalone installs#526
Merged
feat(updater): auto-update for non-Docker standalone installs#526
Conversation
Adds a generic import_migrations table to track two-phase migration state (Phase 1 = import NZBs into AltMount; Phase 2 = rewrite arr library symlinks). Includes goose migrations for SQLite and PostgreSQL, ImportMigration model + status consts, a full ImportMigrationRepository with Upsert/MarkImported/MarkFailed/MarkSymlinksMigrated/LookupByExternalID/ ListByStatus/Stats/ExistsForSource/BackfillFromImportQueue, and wires MigrationRepo into the DB struct.
…avIds Delete HandleIDMetadataLinks and id_linker.go; remove UpdateIDSymlink and RemoveIDSymlink methods from MetadataService; remove the .id sidecar write block from WriteFileMetadata (read path preserved for Phase 2 compatibility); remove FilterExistingNzbdavIds from QueueRepository, Repository, and the BatchQueueAdder interface; remove related call sites in nzbfilesystem MOVE handler and nzbdav scanner processBatch.
- Add MigrationRecorder interface to scanner package with UpsertMigration and IsMigrationCompleted methods - Update NzbDavImporter to accept MigrationRecorder as second constructor parameter alongside BatchQueueAdder - processBatch now checks IsMigrationCompleted before enqueueing (skip already-imported/symlinks_migrated items) and calls UpsertMigration for new items, then strips nzbdav_id from the queue item metadata leaving only extracted_files if present - createNzbFileAndPrepareItem sets SkipArrNotification=true on all items - batchQueueAdapterForImporter gains migrationRepo field and implements MigrationRecorder via ImportMigrationRepository.Upsert/LookupByExternalID
…lure Wire s.database.MigrationRepo into handleProcessingSuccess and handleProcessingFailure so that import_migrations rows are marked imported/failed when the corresponding queue item finishes. Both calls are non-fatal: failures are logged as warnings and do not affect the main processing outcome. If no matching migration row exists (non-nzbdav import), the UPDATE simply affects 0 rows.
Adds RewriteLibrarySymlinks in internal/importer/migration to walk a library directory and atomically rewrite arr symlinks that point at <nzbdav_mount>/.ids/<guid> to the final altmount path. Introduces DBSymlinkLookup adapter in internal/database, a new POST /import/nzbdav/migrate-symlinks handler, and enriches the existing status endpoint with migration_stats when available.
Add binary self-update path alongside the existing Docker update flow and publish a rolling `dev` prerelease of CLI binaries so non-Docker users can track the dev channel. - internal/updater: fetch GitHub release, verify SHA-512, extract from tar.gz/zip, swap binary via minio/selfupdate. Skip when running inside a container (/.dockerenv or KUBERNETES_SERVICE_HOST). - internal/api: route POST /system/update/apply to docker or binary path based on environment; expose binary_update_available in status. - frontend: enable the Apply button whenever either path is available and tailor the copy to the active mode. - .github/workflows/build-cli.yml: reusable workflow_call that builds the full OS/arch matrix and (optionally) attaches assets to a release. - release.yml + dev-image.yml: consume the shared workflow; dev-image publishes to a rolling `dev` prerelease. Closes #497
…son-638589 # Conflicts: # internal/api/nzbdav_handlers.go # internal/api/server.go # internal/database/import_migration_repository.go # internal/database/symlink_lookup.go # internal/importer/migration/symlinks.go # internal/importer/migration/symlinks_test.go # internal/importer/scanner/nzbdav.go # internal/importer/service.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a binary self-update path for standalone (non-Docker) altmount installs and publishes a rolling
devprerelease with CLI binaries so the dev channel works outside Docker too.Closes #497.
What changed
Backend (
internal/updater,internal/api)internal/updaterpackage: fetches GitHub release metadata, picks the asset matchingruntime.GOOS/GOARCH(darwin uses the universal build), verifies SHA-512 againstchecksums-cli.txt, extracts the binary in-memory from tar.gz/zip, and applies it viaminio/selfupdate./.dockerenvandKUBERNETES_SERVICE_HOST— self-update is skipped inside containers so Docker users still get thedocker pullpath.handleApplyUpdatenow routes:docker pull+ restart400with guidanceUpdateStatusResponsegainsbinary_update_availableso the frontend can reflect the real state.Frontend (
UpdateSection.tsx)docker_availableorbinary_update_availableis true.CI workflows
.github/workflows/build-cli.yml(workflow_call) with the full OS/arch matrix, zig cross-compilation, universal darwin, and checksums. Optionally attaches assets to a GitHub release.release.ymlconsumes the reusable workflow for stable tag releases.dev-image.ymlgetsprepare-dev-release+publish-dev-binariesjobs that maintain a rollingdevprerelease with fresh binaries on every push tomain.Why
Before this PR,
/api/system/update/applyshort-circuited to400 "Auto-update is not available"whenever/var/run/docker.sockwasn't mounted, and the dev channel shipped only a Docker image — users running the standalone Linux/macOS/Windows binary had no auto-update path at all.Test plan
go build ./...go test -race ./internal/updater/... ./internal/api/...— new tests cover asset selection, checksum verify (happy + mismatch), tar.gz/zip extraction, handler routing for all three branches.bun run checkinfrontend/— TS + lint + format clean.dev-image.ymlrun on merge to confirm thedevprerelease is updated with freshaltmount-cli_*archives +checksums-cli.txt.docker.sockmounted.