# Flatpak manifest — native Linux build (replaces the AppImage's # browser fallback with a real WebKitGTK window). See # docs/linux-flatpak.md for scope and the staged plan. # # Builds against the GNOME 49 runtime (Python 3.13, GTK 3, WebKit2 # 4.1). Verified end-to-end in CI on every tag — and on PRs that # touch this file or release.yml. app-id: com.tidaldownloader.Tideway runtime: org.gnome.Platform # GNOME 49 maps to the freedesktop 25.08 base (drives the Node # SDK-extension version below). Pinned; bump deliberately. GNOME # 47 (the original scaffold) went EOL 2025-10-15. runtime-version: "49" sdk: org.gnome.Sdk sdk-extensions: # Node only exists in the build sandbox to produce web/dist; it # is not part of the runtime the app ships against. - org.freedesktop.Sdk.Extension.node20 command: tideway # flatpak-builder auto-runs `appstream-compose` against our metainfo # file for the legacy share/appdata/.appdata.xml output. GNOME # 49's Sdk doesn't ship that binary (it was deprecated in favour of # `appstreamcli compose` years ago) and modern AppStream readers # index share/metainfo/.metainfo.xml directly. Disable the # auto-step at the manifest level so the build doesn't fail here. appstream-compose: false finish-args: - --share=network # Tidal / Spotify / Last.fm - --socket=pulseaudio # PortAudio/sounddevice out - --socket=wayland # native window - --socket=fallback-x11 # X11 fallback - --device=dri # WebKitGTK GPU compositing # Download folders. The app's defaults are the Music and Videos # user dirs (~/Music/Tidal, ~/Videos/Tidal, localized via # user-dirs.dirs); without these grants those paths are unmounted # tmpfs inside the sandbox, so downloads "complete" and then # vanish on restart (#261). xdg-download stays granted for users # who point output_dir at ~/Downloads instead. - --filesystem=xdg-music:create - --filesystem=xdg-videos:create - --filesystem=xdg-download - --talk-name=org.freedesktop.Notifications # libnotify # MPRIS: the app owns this well-known name on the session bus so # desktop media widgets / playerctl can find it (app/mpris.py). - --own-name=org.mpris.MediaPlayer2.tideway cleanup: - /include - /lib/pkgconfig - /share/man - "*.a" - "*.la" modules: # sounddevice needs libportaudio; the GNOME runtime does not ship # it. Built here; sha256 computed off the upstream tarball. # # Sourced from the GitHub release tag rather than # files.portaudio.com, which stopped resolving entirely — the v1.32.2 # release build failed with "Could not resolve host: # files.portaudio.com", and it does not resolve from a developer # machine either, so this is the host being gone rather than a flaky # runner. The project's own GitHub release for v19.7.0 carries no # assets, so the tag archive is the source that remains. # # Same upstream code, different packaging: the tag archive ships a # generated `configure`, so autotools still applies unchanged (this # was checked rather than assumed — a repo snapshot without it would # have needed an autoreconf step). - name: portaudio buildsystem: autotools sources: - type: archive url: https://github.com/PortAudio/portaudio/archive/refs/tags/v19.7.0.tar.gz sha256: 5af29ba58bbdbb7bbcefaaecc77ec8fc413f0db6f4c4e286c40c3e1b83174fa0 # Offline, hashed PyPI deps generated from requirements.txt with # flatpak-pip-generator. Regenerate by running the script in the # VM against the project's requirements.txt and copying the # resulting JSON over this file. - python3-requirements.json - name: tideway buildsystem: simple # Node extension is mounted under /usr/lib/sdk/node20/bin. The # build sandbox has no network; npm reads from the offline cache # laid down by flatpak-node-generator under flatpak-node/. build-options: append-path: /usr/lib/sdk/node20/bin env: XDG_CACHE_HOME: /run/build/tideway/flatpak-node/cache npm_config_cache: /run/build/tideway/flatpak-node/npm-cache npm_config_offline: "true" build-commands: # Web bundle (offline; tarballs come from node-sources.json). - npm --prefix web ci --offline --no-audit --no-fund - npm --prefix web run build # App payload. The runtime Python imports `gi`, so pywebview # uses the GTK/WebKit backend — no browser fallback. # # `web/dist` MUST land at `/app/share/tideway/web/dist/`, not # `/app/share/tideway/dist/`. server.py's static mount resolves # the Vite build via `bundled_resource_dir() / "web" / "dist"`, # and `bundled_resource_dir()` returns the package root # (`/app/share/tideway` inside the sandbox). Earlier releases # used a single `cp -r ... web/dist /app/share/tideway/` which # flattens the destination to `/app/share/tideway/dist/`; the # static mount then skipped registration, the SPA fallback # route was never wired up, and the pywebview window loaded # `{"detail":"Not Found"}` instead of the React app. - install -d /app/share/tideway/web - cp -r app server.py desktop.py VERSION /app/share/tideway/ - cp -r web/dist /app/share/tideway/web/ - install -Dm755 flatpak/tideway-launcher.sh /app/bin/tideway - install -Dm644 flatpak/com.tidaldownloader.Tideway.desktop /app/share/applications/com.tidaldownloader.Tideway.desktop - install -Dm644 assets/icon.png /app/share/icons/hicolor/512x512/apps/com.tidaldownloader.Tideway.png # AppStream metainfo. GNOME Software and KDE Discover read # this to render the app card and surface "Updates available" # notifications. Required for Flathub; useful for self-hosted # because software centres pick the file up automatically. - install -Dm644 flatpak/com.tidaldownloader.Tideway.metainfo.xml /app/share/metainfo/com.tidaldownloader.Tideway.metainfo.xml sources: - type: dir path: .. - node-sources.json