Skip to content

fix(library): oldest first like the Queue, and Queue remove only stops the extraction (#772) - #819

Merged
thcp merged 2 commits into
big-releasefrom
fix/library-order-queue-remove-772
Oct 20, 2026
Merged

thcp merged 2 commits into
big-releasefrom
fix/library-order-queue-remove-772

Conversation

@thcp

@thcp thcp commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Closes #772

What changed

  • Library order: the desktop Library (every folder, and Favorites) and the phone list songs oldest first, by when each was added (createdAt), with the id as a fixed tie-break. Same order as the Queue. No new sort toggle.
  • Existing libraries now show oldest first. The order is computed at render time, not from how a folder was stored, so every library flips on upgrade.
  • Queue remove: the button now calls a new POST /api/jobs/{id}/stop instead of /cancel. The job settles as stopped with its files kept and is not trashed, so the Library shows it with Extract (the state a song restored from the Trash has). Extract runs it again.
    • Waiting job: leaves the queue.
    • Running job: its process is terminated through the existing cancel path; the runner settles it.
    • A stopped run's partial separation folder is now removed when it settles (also applies to a trashed import, which Extract cleared anyway).
    • /stop validates the id (JOB_ID_RE, 404 job not found), and leaves a finished job untouched.
  • Song with no audio yet (a link not downloaded): it stays stopped with its link, because Extract on a link always downloads it again, so nothing is lost and no new state is needed.
  • Button title and label now say it stops extracting and keeps the song, in all ten tables; new Guide row help.queueStop.
  • Specs: queue-progress stubs /stop; acceptance E5 expects stopped; spec-map.json maps the two new specs.

What did not change

Tests

  • New: tests/test_queue_remove.py, tests/e2e/library-order.spec.mjs, tests/e2e/queue-remove.spec.mjs, tests/js/library-order.test.mjs. All failed on big-release (first commit) and pass now.
  • pytest full suite: 3264 passed, 5 failed (the known libvorbis ogg tests).
  • Full Playwright suite run locally. The failures that remain also fail on big-release on this Mac: artist-discogs:265, karaoke:94, three trash-restore Ctrl+click tests, and a flaky footer-time:48.

thcp added 2 commits October 20, 2026 00:29
library-order: the Library and the phone list songs newest first, while the Queue runs them oldest first.
queue-remove and test_queue_remove: removing a song from the Queue cancels it, which deletes its files, so it leaves the Library and never reaches the Trash.

All fail on big-release.
…s the extraction

Library order: the desktop Library (every folder and Favorites) and the phone list songs oldest first by when they were added (createdAt), with the id as a fixed tie-break. The order no longer depends on how a folder was stored, so existing libraries show oldest first too.

Queue remove: the button now sends the new POST /api/jobs/{id}/stop instead of /cancel. The job settles as "stopped" with its files kept, out of the Trash, so the Library shows it with Extract, which runs it again. A waiting job just leaves the queue; a running one has its process terminated through the existing cancel path. A link with no audio yet keeps its link and Extract downloads it again. A stopped run's partial separation folder is now removed when it settles. Library delete and the job panel's Cancel are unchanged.

The button's title and label say it stops extracting and keeps the song, in all ten tables, and the Guide explains it (help.queueStop). queue-progress now stubs /stop, and acceptance E5 expects "stopped".

Closes #772
@thcp
thcp marked this pull request as ready for review October 20, 2026 00:10
@thcp
thcp merged commit ea784c7 into big-release Oct 20, 2026
10 checks passed
thcp added a commit that referenced this pull request Oct 22, 2026
…g-release (#836)

Closes #835

## What changed

- **PR to `main`, push to `main`, release:** full suite, as before.
- **PR to any other base:** smoke + changed specs + mapped specs. A hub
module (former `full` source entries: `main.js`, `state.js`, `mixer.js`,
`catalog.js`, `index.html`, `app/api/jobs.py`, `stems.py`,
`app/core/**`, ...) or an unmapped file under `static/` or `app/` now
adds a fixed **core set** (17 specs) instead of everything. `uv.lock`
and `pyproject.toml` add core too.
- **Full suite on a non-main PR** only for a change to how the suite
runs: `playwright.config.mjs`, `tests/e2e/helpers*`, `serve.sh`,
`seed.py`, `package*.json`, the three e2e workflows, the selector,
`spec-map.json`, or unmapped code under `tests/e2e/`.
- **New `e2e-full.yml`:** full suite on every push to `big-release`,
nightly (04:17 UTC) on `big-release`, and `workflow_dispatch` with a
`ref` input.
- **New reusable `e2e.yml`** (`workflow_call`, inputs `mode`,
`base-ref`, `checkout-ref`) holds the steps once. Same pinned SHAs,
`permissions: {}`, no secrets.
- **Concurrency:** a new push to a PR cancels that PR's older e2e run.
Pushes, releases, nightly and manual runs are never cancelled.
`timeout-minutes: 30` per shard.

## What did not change

- Application code, specs, `uv.lock`, package files. Three shards,
`--pass-with-no-tests`.
- Check names gain a prefix: `frontend-e2e / frontend-e2e (1)` to `(3)`.
A reusable workflow always prefixes the caller job. No branch protection
or ruleset requires these names today (checked).

## Real diffs, before and after

| Diff | Files | Before | After |
|---|---|---|---|
| #806 (queue.js, catalog.js) | 5 | FULL 105 | 30 (core), includes
queue-progress |
| #820 | 7 | FULL 105 | 59 (core) |
| #821 | 2 | 47 | 47 |
| #823 | 8 | 5 | 5 |
| #828 (uv.lock) | 4 | 5 | 22 (core) |
| #819, #830, #831 | 7 to 19 | FULL 105 | FULL 105 (edit
`spec-map.json`) |
| #829 | 19 | FULL 105 | FULL 105 (edits `helpers.mjs`) |
| #822 | 33 | FULL 105 | FULL 105 (edits `seed.py`) |
| `main...big-release` | 331 | FULL | FULL (PR to main) |

`npx playwright test --list <selected>` matches the selector exactly for
#806 (30 files, 200 tests) and #820 (59 files, 465 tests). Full suite:
724 tests in 105 files. Core + smoke alone: 159 tests in 22 files.

## Trade-off

A non-main PR can pass while a spec outside its core and mapped sets
breaks. The push to `big-release` run catches it on the merge commit,
minutes later.

## Limits

- **The nightly schedule only starts once `e2e-full.yml` reaches
`main`.** GitHub runs scheduled workflows from the default branch, and
the job checks out `big-release` explicitly for that reason.
- Neither concurrency nor the timeout helps a hosted runner GitHub never
assigns (queue time does not count toward the timeout). Fix by hand:
re-run the job, or `gh run cancel <id>` then `gh run rerun <id>
--failed`.
- This PR changes `ci.yml`, so its own CI runs the full suite. Expected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant