With the PyGObject girepository-2.0 fix in place, the linux-smoke step
ran its server-boot assertion for the first time and failed: on a fresh
runner the first-run bootstrap writes a default config and calls
sys.exit(0) ("First run: generated default config ... then restart")
instead of serving, so /api/health never came up and the 15s wait
timed out.
That exit-on-first-run is deliberate product behavior (never silently
start in insecure no-auth mode), so adjust the test rather than the app:
invoke the server once to seed the config (it exits 0 before binding the
port), then launch it for real. /api/health requires no auth, so the
auto-generated token is irrelevant to the check.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PyGObject >= 3.52 dropped the standalone gobject-introspection
girepository-1.0 dependency and now builds against girepository-2.0,
which was merged into GLib 2.80. The linux extra pins PyGObject>=3.46
with no upper bound, so pip resolves the newest release (3.56.3) and
meson aborts metadata generation with:
Dependency 'girepository-2.0' is required but not found.
because CI only installed the old libgirepository1.0-dev.
Swap libgirepository1.0-dev -> libgirepository-2.0-dev (shipped by
GLib 2.80 on the ubuntu-latest / 24.04 runner) across all three Linux
pip-install paths so they stay in sync:
- test.yml: the failing linux-smoke job.
- release.yml: build-linux, which would otherwise ship a broken
Linux tarball on the next tag.
- build.yml: build-linux had no system-deps step at all; added the
matching apt install so the manual artifact build works too.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Gitea instance currently has no macOS runner attached, so the
build-macos job was failing visibly on every release even with
continue-on-error: true, and the release body advertised macOS
downloads that were never produced.
- Gate build-macos with `if: false` (job is preserved verbatim
except for the gate, so re-enablement is a one-line delete).
- Drop the macOS rows from the Downloads table generated by the
create-release job. Kept as commented-out lines inside the heredoc.
Both changes carry a `TODO(macos-runner)` marker — `grep` for it
to find every site that needs flipping when a macOS runner is
connected.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add `linux` (dbus-python, PyGObject, python-xlib) and `macos`
(pyobjc) extras to pyproject.toml with sys_platform markers; move
cross-platform screen-brightness-control + monitorcontrol to base deps.
- build-dist-linux.sh: install `.[linux]`, pkg-config pre-flight for
dbus-1/glib-2.0, emit a systemd unit with DBUS_SESSION_BUS_ADDRESS +
XDG_RUNTIME_DIR + ReadWritePaths for ~/.config and ~/.cache so MPRIS
works and audit-log / thumbnail writes aren't blocked by ProtectHome.
- New build-dist-macos.sh + per-user LaunchAgent installer producing
MediaServer-vX.Y-macos-{arm64,x86_64}.tar.gz.
- Templated media-server.service updated to match the dist layout with
proper session-bus env vars and a writable state-dir grant.
- install_linux.sh: drop dead requirements.txt path; install via
`pip install ".[linux]"` and pre-create the writable state dirs.
- Cross-platform album artwork: abstract MediaController.get_album_art()
with Linux (mpris:artUrl, file:// + http(s)://) and macOS (Spotify URL)
impls; routes/media artwork endpoint now awaits the controller.
- LinuxMediaController connects to the session bus lazily — failure no
longer crashes lifespan startup; MPRIS calls return idle until the bus
is reachable. Logged once at INFO with a hint about
`loginctl enable-linger`.
- Startup preflight on Linux warns if DBUS_SESSION_BUS_ADDRESS or
XDG_RUNTIME_DIR is unset and informs the user when Wayland disables
the foreground probe.
- /api/media/visualizer/status now reports a per-OS unavailable_reason.
- tray._confirm guarded against ctypes.windll on non-Windows.
- config.example.yaml: per-OS commented script examples; on_turn_off
default is now a no-op echo (used to silently fail off Windows).
- README: replace stale `pip install -r requirements.txt` instructions
with the new extras; add systemd lingering doc + troubleshooting
section; add macOS LaunchAgent section.
- CI: new linux-smoke job (installs `.[linux]`, boots the server under
dbus-run-session, asserts /api/health). Release workflow gains
apt-deps step for the Linux build and a best-effort macOS build job.
setup-node and actions/cache@v4 hang trying to talk to a missing
cache server, adding 1-3min per step. Drop the cache: directives
and explicit cache blocks. Keep the single pip-download call in
build-dist-windows.sh which is independent of any cache backend.
- Add pip and npm caching to build-windows and build-linux jobs
- Cache embedded Python zip and Windows wheels across runs
- Collapse per-dep pip download loop into a single resolver call
First run after this lands populates the caches; subsequent
release builds should drop from ~11min to ~3-5min.
workflow_dispatch-triggered build.yml that produces Windows
installer/portable and Linux tarball as CI artifacts without
creating a release. Trigger from Gitea UI → Actions → Run.
- Rename GITEA_TOKEN to DEPLOY_TOKEN in release workflow
- Extract shared version detection into build-common.sh
- Use importlib.metadata for runtime version instead of hardcoded string
- Use PEP 440 parsing (packaging lib) for update version comparison
- Add packaging>=23.0 to dependencies
- Fix update banner close button alignment (CSS)
- Update CLAUDE.md with versioning docs and frontend rebuild notes
If the Gitea release already exists for a tag (e.g. from a retried
workflow), fall back to fetching the existing release ID instead of
failing with KeyError.
- Add build-dist-linux.sh: venv-based tarball with systemd installer
- Add build-linux job to release.yml (parallel with build-windows)
- Include Linux download in release body
- Allow pytest to pass when no tests are collected (exit code 5)