chore(release): v0.12.0
🏗️ Build and Test JellyTau / Run Tests (push) Skipped
🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
🏗️ Build and Test JellyTau / Supply Chain (push) Failing after 53s
📱 Test APK / Build test APK (push) Successful in 54m6s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 8m54s
Traceability Validation / Check Requirement Traces (push) Successful in 18s
Build & Release / Run Tests (push) Successful in 23m38s
Build & Release / Build Linux (push) Successful in 31m12s
Build & Release / Build Windows (push) Successful in 32m21s
Build & Release / Build Android (push) Successful in 49m32s
Build & Release / Create Release (push) Successful in 1m24s
🏗️ Build and Test JellyTau / Run Tests (push) Skipped
🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
🏗️ Build and Test JellyTau / Supply Chain (push) Failing after 53s
📱 Test APK / Build test APK (push) Successful in 54m6s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 8m54s
Traceability Validation / Check Requirement Traces (push) Successful in 18s
Build & Release / Run Tests (push) Successful in 23m38s
Build & Release / Build Linux (push) Successful in 31m12s
Build & Release / Build Windows (push) Successful in 32m21s
Build & Release / Build Android (push) Successful in 49m32s
Build & Release / Create Release (push) Successful in 1m24s
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,96 @@ generated trace matrix lives in [docs/traceability.md](docs/traceability.md).
|
|||||||
For how long each fixed defect had been shipping before it was found, see
|
For how long each fixed defect had been shipping before it was found, see
|
||||||
[docs/defect-windows.md](docs/defect-windows.md).
|
[docs/defect-windows.md](docs/defect-windows.md).
|
||||||
|
|
||||||
|
## v0.12.0
|
||||||
|
|
||||||
|
JellyTau works against Jellyfin 12. Jellyfin 12.0 shipped on 2026-09-08 and
|
||||||
|
turns off, by default, the two ways every earlier JellyTau build identified
|
||||||
|
itself to a server — including on servers that were upgraded rather than freshly
|
||||||
|
installed. An app that was not changed for it stops signing in the day the server
|
||||||
|
updates. This release is changed for it, and still works against 10.11, so the
|
||||||
|
app can be updated first and the server whenever it suits.
|
||||||
|
|
||||||
|
There is no Jellyfin 11. The project dropped the leading `10` from its version
|
||||||
|
scheme: what would have been 10.12.0 shipped as 12.0. Anything that compares
|
||||||
|
Jellyfin version numbers needed to learn that, and this app now has.
|
||||||
|
|
||||||
|
### ✨ Changes
|
||||||
|
|
||||||
|
- **Signing in survives a server upgrade to Jellyfin 12.** The server used to be
|
||||||
|
told who was asking through a header and a URL parameter that 12.0 disables by
|
||||||
|
default — a migration disables them on upgraded servers too, so nothing in an
|
||||||
|
admin's hands changes the outcome. The replacement spellings are accepted by
|
||||||
|
10.11 and 12 alike, so this is one way of identifying the app that works
|
||||||
|
everywhere, not a switch between two. The URL half matters more than it
|
||||||
|
sounds: video and audio are streamed by the device's media player, which cannot
|
||||||
|
send headers at all, so the URL parameter is the only way playback can
|
||||||
|
authenticate. A test now refuses any request built with the old spellings,
|
||||||
|
because the failure is silent right up until a server upgrades.
|
||||||
|
(UR-085 → DR-287)
|
||||||
|
|
||||||
|
- **Browsing a library returns the same things on both server versions.** 12.0
|
||||||
|
changed what a filtered library listing means — asked for the films in a
|
||||||
|
library, 10.11 returned the folder's immediate contents and 12.0 returns
|
||||||
|
everything beneath it, and nothing in the reply says which rule applied. The
|
||||||
|
app now says which it wants, so both servers answer the same way, and the
|
||||||
|
answer is the one it always had. (UR-085 → DR-288)
|
||||||
|
|
||||||
|
- **The app knows what server it is talking to, once, and adapts.** The server
|
||||||
|
version was already fetched at sign-in and then thrown away. It is now
|
||||||
|
resolved into a small set of named capabilities that every version-dependent
|
||||||
|
decision reads from, rather than the version number being compared wherever
|
||||||
|
somebody needed it — which is unreadable by the second occurrence and cannot
|
||||||
|
express a backport. A server newer than this build is treated as the newest
|
||||||
|
one it knows and keeps working; refusing it would make every release expire
|
||||||
|
the moment the server updated. Only a server older than 10.10 is refused, and
|
||||||
|
the sign-in screen says so and names the minimum. (UR-085 → IR-035, DR-280,
|
||||||
|
DR-286)
|
||||||
|
|
||||||
|
- **The cached library re-fetches itself after a server upgrade.** Nothing had
|
||||||
|
recorded which server version wrote the cached catalog, so a server upgraded
|
||||||
|
underneath the app kept serving rows read under the old rules. The generation
|
||||||
|
is now recorded, and a change clears the cache so it fills back under the new
|
||||||
|
one. The first launch of this version records and clears nothing — an
|
||||||
|
existing install is not charged a full re-download to defend against an
|
||||||
|
upgrade that has not happened. (UR-085 → DR-284)
|
||||||
|
|
||||||
|
### 🛠 Development
|
||||||
|
|
||||||
|
- **Every route the app speaks lives in one place.** Fifty-seven inline URL
|
||||||
|
strings across the server adapter became one module of route functions, each
|
||||||
|
taking the resolved capabilities. Both shapes of the item routes Jellyfin has
|
||||||
|
deprecated are built and tested, though nothing selects the second yet — the
|
||||||
|
family still works on 12.0, and 12.0's written policy that unlisted endpoints
|
||||||
|
may go in any major release is why having the alternative ready costs less
|
||||||
|
than needing it. (UR-085 → DR-279, DR-282)
|
||||||
|
|
||||||
|
- **The server adapter is tested against a server.** There was no HTTP mocking
|
||||||
|
in the Rust tree at all: every test of the adapter asserted on a URL string it
|
||||||
|
had built, and none exercised a reply. A fake Jellyfin now answers over real
|
||||||
|
HTTP and reports whichever version a test asks for, so the same assertions run
|
||||||
|
against both generations through the production resolution path. The one
|
||||||
|
file that had tried this before reimplemented the URL builders inside its own
|
||||||
|
mock and asserted against itself — and had never compiled, and had once
|
||||||
|
stayed green while the real code shipped a download endpoint that 404s. It is
|
||||||
|
deleted, and the rule it teaches is written at the top of its replacement.
|
||||||
|
(UR-085 → DR-281)
|
||||||
|
|
||||||
|
- **A Jellyfin URL was being built in the interface layer** — the last one,
|
||||||
|
and, it turned out, unused. Deleted rather than moved. (UR-085 → DR-285)
|
||||||
|
|
||||||
|
### ⚠️ Known limits
|
||||||
|
|
||||||
|
Every cross-version assertion runs against a fake server built from a
|
||||||
|
source-level diff of the two Jellyfin releases, not against a running 12.0. Two
|
||||||
|
things that diff could not settle: whether remote control and casting behave
|
||||||
|
identically, and whether the audio-codec check that forces a transcode on 10.11
|
||||||
|
is still needed on 12 — it is left on, which errs toward an unnecessary
|
||||||
|
transcode rather than silent playback. Both resolve with a real 12.0 server;
|
||||||
|
reports welcome.
|
||||||
|
|
||||||
|
**Upgrading:** install this version *before* upgrading the server, not after.
|
||||||
|
It works against both; an older JellyTau does not work against 12.
|
||||||
|
|
||||||
## v0.11.6
|
## v0.11.6
|
||||||
|
|
||||||
Found by an audit of the stack's most fragile seams rather than by hitting them,
|
Found by an audit of the stack's most fragile seams rather than by hitting them,
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jellytau",
|
"name": "jellytau",
|
||||||
"version": "0.11.6",
|
"version": "0.12.0",
|
||||||
"description": "A cross-platform Jellyfin client built with Tauri, SvelteKit and Rust.",
|
"description": "A cross-platform Jellyfin client built with Tauri, SvelteKit and Rust.",
|
||||||
"author": "Duncan Tourolle <duncan@tourolle.paris>",
|
"author": "Duncan Tourolle <duncan@tourolle.paris>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
Generated
+1
-1
@@ -2275,7 +2275,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jellytau"
|
name = "jellytau"
|
||||||
version = "0.11.6"
|
version = "0.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
"argon2",
|
"argon2",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ name = "jellytau"
|
|||||||
# `player-conformance`, and a second binary makes a bare `cargo run` —
|
# `player-conformance`, and a second binary makes a bare `cargo run` —
|
||||||
# which `tauri dev` issues — ambiguous.
|
# which `tauri dev` issues — ambiguous.
|
||||||
default-run = "jellytau"
|
default-run = "jellytau"
|
||||||
version = "0.11.6"
|
version = "0.12.0"
|
||||||
description = "A cross-platform Jellyfin client"
|
description = "A cross-platform Jellyfin client"
|
||||||
authors = ["Duncan Tourolle <duncan@tourolle.paris>"]
|
authors = ["Duncan Tourolle <duncan@tourolle.paris>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "JellyTau",
|
"productName": "JellyTau",
|
||||||
"version": "0.11.6",
|
"version": "0.12.0",
|
||||||
"identifier": "com.dtourolle.jellytau",
|
"identifier": "com.dtourolle.jellytau",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "bun run dev",
|
"beforeDevCommand": "bun run dev",
|
||||||
|
|||||||
Reference in New Issue
Block a user