Skip to content

LocalDrop 1.1.0

Choose a tag to compare

@github-actions github-actions released this 01 Oct 20:22
· 58 commits to main since this release
70ce650

LocalDrop 1.1.0

[1.1.0] — 2026-10-01

LocalDrop is now installable on every platform. 1.0.0 shipped a Docker-only
install that worked, but left a Linux server, a Mac, and a Windows desktop with
three different un-documented workarounds. This release closes that gap and makes
the repository releaseable as open source.

Added — installation

  • One-line Linux/macOS installer. curl -fsSL …/install.sh | sh downloads a
    checksummed binary, verifies its SHA-256, creates a locked localdrop system
    account, installs a systemd unit (Linux) or a launchd job (macOS), generates a
    secret key, and starts the service. --no-service installs the binary alone;
    your data and config are never overwritten.
  • Windows installer. A proper Inno Setup package (Start Menu and desktop
    shortcuts, optional start-at-login, uninstaller) plus a portable zip of the
    same payload. Both are checksummed.
  • install.ps1 for Windows: fetches, verifies, installs, and runs
    localdrop --check to prove the install works before it reports success.
  • Homebrew formula for macOS (brew install abhi-subedi/localdrop) —
    per-user, no sudo, no service auto-install.
  • uninstall.sh that keeps your data by default and only deletes it when
    you pass --purge and confirm.
  • Self-contained installs need no database at all. When
    LOCALDROP_DATABASE_URL is unset, the launcher provisions an embedded
    PostgreSQL inside the data directory, so a native install is a single binary
    with nothing else to install. Point it at your own PostgreSQL and the
    embedded cluster is never started.
  • Frozen binaries for every platform — linux-x64, linux-arm64,
    macos-x64, macos-arm64, windows-x64 — with a published SHA256SUMS.
  • Published container image on ghcr.io/abhi-subedi/localdrop for
    linux/amd64 and linux/arm64, tagged :1.1.0, :1.1, :stable,
    :latest, with OCI labels and provenance attestation.

Added — operating the server

  • localdrop --check verifies an install is self-sufficient and exits: every
    bundled resource, the heavy C extensions (psycopg, argon2, Pillow) and the app
    factory. It needs no database, so it works when the thing that is broken is
    the database. The release pipeline runs it against every artefact before
    publishing.
  • localdrop --setup-token prints the one-time onboarding token on demand,
    so a headless install does not have to dig it out of journalctl.
  • localdrop install-service / uninstall-service / service-status for a
    per-user macOS LaunchAgent — the launchd job Homebrew users need, since
    Homebrew will not install one for them.
  • localdrop-migrate applies migrations programmatically, so the packaged
    Alembic environment is found regardless of working directory. Docker, systemd,
    the launcher and the frozen binary all use the same path.
  • localdrop.env is read from the data directory when present, so every
    platform is configured the same way. Real environment variables still win.
  • GET /api/v1/version reports the running build (public, and free of any
    deployment detail). The Settings "About" panel reads it instead of showing a
    hard-coded string.
  • /api/v1/health/ready reports the failing subsystem by name, and
    LOCALDROP_DB_CONNECT_TIMEOUT / LOCALDROP_DB_KEEPALIVE_SECONDS bound how
    long it can take to find out.

Added — working on the project

  • Continuous integration (.github/workflows/ci.yml): lint, types, the
    test suite against real PostgreSQL 16, a frontend type-check and build, a
    frozen-binary build that self-checks, and a Docker build that must serve
    /api/v1/version.
  • Automated releases (release.yml): tag a version and get binaries for
    five platforms, a multi-arch image, checksums, a Release whose notes come
    from this file, an updated VERSION file, and a pushed Homebrew formula.
  • Nightly checks (nightly.yml): pip-audit, npm audit, a Trivy scan of
    the published image, CodeQL, and an end-to-end pass against the real
    stable image that fails if it is not the version VERSION claims.
  • Dependabot, grouped by ecosystem so review is a handful of PRs, not
    dozens.
  • scripts/check_version.py, scripts/check_config_docs.py and
    scripts/check_fr_traceability.py — the doc-drift gates the spec asked
    for and never had. Requirement-to-test traceability is now enforced, with the
    remaining gaps registered and visible instead of assumed.
  • SECURITY.md, SUPPORT.md, bug and feature issue templates, a PR
    template, CODEOWNERS, .editorconfig and .gitattributes.

Fixed

  • Readiness took 130 seconds to report a dead database. The engine had no
    connect_timeout, so libpq waited its default ~2 minutes — longer than the
    Docker healthcheck's 5-second timeout. Now ~5 seconds, with a regression test
    that fails if the bound is removed.
  • Pool hygiene: pool_recycle and pool_timeout are set, and TCP keepalives
    close half-open connections instead of letting them pin a pool slot.
  • Production builds shipped without any CSS. index.css was never imported
    by the app entry, so the built SPA rendered unstyled.
  • A pip install could not run. The migrations and the built web UI lived
    outside the package, so only the Docker layout — which copied them back in by
    hand — worked. Both now ship inside the wheel, and pip install localdrop
    and the frozen binary resolve them identically.
  • docker compose pull could not work. The compose file referenced a
    locally built tag that was never published. It now pulls from GHCR, so the
    documented upgrade path is real.

Changed

  • One version, one source of truth. __version__ in
    __about__.py feeds the wheel, the binary, the HTTP API, the Settings panel
    and the release tooling. The three-way drift between 1.0.0, 1.1.0 and
    "unreleased" is no longer possible; CI fails if it comes back.
  • The repository's own quality gates now pass. ruff and mypy were
    reporting 230 and 37 problems respectively before this release. Both are clean.
  • docs/CONFIGURATION.md is complete — it was missing 15 settings.

Security

  • Release artefacts are SHA-256 verified by every installer before anything is
    unpacked, and releases carry a provenance attestation.
  • The systemd unit runs as a dedicated account with NoNewPrivileges,
    ProtectSystem=strict and ReadWritePaths limited to the data directory.
  • Windows and macOS installs write the config file 0600; the launchd plist
    holds the secret key and is not world-readable.
  • Reports go through private vulnerability reporting, not public issues.

Known limitations

  • Single owner account; no multi-user sharing (use public links).
  • Files live in folders; no folder or zip download.
  • No live cross-device refresh (no SSE): the UI refreshes after your own
    actions, and another device's changes appear on reload.
  • LAN discovery is URL + QR. LOCALDROP_MDNS_ENABLED is reserved and unused.
  • macOS Homebrew ships raw tarballs, not bottles: no brew install of a
    pre-built binary, so the formula builds from the release archive.
  • Windows binaries are unsigned. SmartScreen will warn on first run.
  • 9 of 31 Must-have requirements have no automated test; they are listed with
    reasons in scripts/check_fr_traceability.py under KNOWN_GAPS.
  • The embedded PostgreSQL is downloaded from Maven Central on first run and is
    not checksum-verified. (Release artefacts are; this one is not yet.)

Full changelog: https://github.com/Abhi-Subedi/LocalDrop/blob/v1.1.0/CHANGELOG.md

Upgrade notes: forward-only migrations. Take a backup first (docs/BACKUP.md).