Skip to content

v1.4.3: post-audit followup + auto-updater fix - #2

Merged
yaniswav merged 7 commits into
mainfrom
chore/post-audit-followup
May 19, 2026
Merged

v1.4.3: post-audit followup + auto-updater fix#2
yaniswav merged 7 commits into
mainfrom
chore/post-audit-followup

Conversation

@yaniswav

Copy link
Copy Markdown
Owner

Summary

6 commits on top of main, suivi de l'audit + lots post-audit. Pousse aussi le fix de l'auto-updater : latest.json est désormais correctement composé et publié sur la release.

Commits

  1. ci: enforce cargo clippy as hard gate — retire continue-on-error sur le step clippy maintenant que la baseline est verte.
  2. fix(extractor/batch): runtime counters, streaming checkpoint, dead-code cleanup — corrige le compteur failed figé pendant un batch + persistance streaming des échecs au checkpoint (crash-safe) + nettoyage dead code dans le même fichier.
  3. refactor: prune dead code, scope #[allow] to real reasons — supprime 10 items dead code (fns, variants, champs) jamais utilisés, garde 1 (with_vendor) avec justification précise.
  4. fix(svelte): wrap bind:this refs in $state for true reactivity — corrige 2 vrais bugs de réactivité Svelte 5 (auto-scroll du log + dropdown CustomSelect).
  5. fix(ci): generate latest.json for auto-updater on release — refactor release.yml : ajout de 3 steps post-build (upload des .sig et bundles updater que tauri-action@v0 ignore) + nouveau job publish-updater-json qui compose latest.json via jq.
  6. chore: bump version to v1.4.3 — package.json, Cargo.toml, Cargo.lock, tauri.conf.json synchronisés.

Test plan

  • cargo check + clippy (hard gate) + test = 113/113 passing
  • npm run check = 0 errors
  • npm run build OK
  • Tag v1.4.3 pushé → workflow Release vert → release créée avec latest.json + tous les .sig files
  • curl du endpoint updater = 200 OK
  • auto-updater fonctionnel en runtime

🤖 Generated with Claude Code

yaniswav and others added 6 commits May 19, 2026 18:38
Now that the backend is clippy-clean, remove `continue-on-error` on
the clippy step so future violations block the PR instead of piling up
as soft warnings.

cargo fmt and cargo test remain soft gates for now — to be hardened
separately after confirming the baseline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…de cleanup

Three intertwined fixes on the same file, atomic so the test added at
the end exercises all of them together.

1. failed counter increment at runtime
   The `failed` field on BatchProgress used to be loaded from the
   checkpoint at batch start and never updated, so the UI showed a
   stale value (usually 0) regardless of how many items actually
   failed. Add `process_all_with_progress` on BatchProcessor that
   fires a per-item completion callback once retries are done; the
   batch.rs caller uses it to bump succeeded/failed cleanly without
   double-counting retry attempts. Counters become Cell<usize> so
   the per-attempt closure can read them for the progress event
   while the completion callback writes.

2. streaming-style failure persistence
   `checkpoint.mark_failed` was only called in the post-batch
   failures loop, so a crash mid-batch lost the partial failure
   trace and resumption replayed already-failed items. Move it into
   the on_item_done callback and unify the save call so both Ok and
   Err paths persist after each item. Drop the now-redundant block
   from the failures-mapping loop.

3. dead code pruning around the batch/resilience modules
   Remove `process_batch_with_defaults`, `TimeoutGuard::elapsed`,
   and collapse the `AppError::UnsupportedFormat | InvalidArchive`
   match arm (InvalidArchive variant is removed in a separate
   commit).

Tests:
  - failed_counter_increments_on_runtime_failures
  - failed_items_are_streamed_to_checkpoint

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Trim the speculative-code allowances introduced during the clippy
sweep. Each item was checked with `git grep` (Rust + Svelte/TS).

DELETE (no callers found):
  - Checkpoint::find_latest
  - ExtractionTimingSession::record_step
  - timing::measure / timing::timed
  - ImportTasksRepository::list_recent_tasks
  - product_files::insert_product_files (production uses _batch instead;
    tests migrated to insert_product_files_batch)
  - product_files::delete_product_files (cascade on products DELETE
    handles it — test_delete_product_files removed too)
  - ManifestFile.action field (parser wrote it, no one read it)
  - WatchEventType::Modified variant (never constructed; only Created
    and Removed are emitted)
  - AppError::InvalidArchive variant (never constructed; the batch.rs
    match arm collapses to UnsupportedFormat alone)
  - unused `Duration` import from timing.rs (consequence)
  - process_batch_with_defaults re-export in extractor/mod.rs

KEEP with refined justification:
  - NewProduct::with_vendor — builder-style setter, kept for API
    symmetry with with_source / with_tags.

No behavioral change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
scrollEl in TaskLogger.svelte and listEl in CustomSelect.svelte were
declared as plain `let` while bound via `bind:this`. Svelte 5 only
re-runs reactive blocks on `$state(...)` mutations, so the $effect
that auto-scrolled on new log entries never saw the ref being
attached, and CustomSelect's dropdown ref toggled inside {#if open}
without observers being notified.

Wrap both as `let x: T | undefined = $state()` and capture the ref
into a local const inside the async tick().then() block so TS strict
null-checks pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tauri-action@v0 builds + signs the updater bundles correctly but its
asset filter only uploads the primary installers (.msi / .exe / .dmg /
.AppImage / .deb). The matching .sig files and the .zip / .tar.gz
updater archives are left behind, which is why latest.json was never
composed — the logs ended with "Signature not found for the updater
JSON. Skipping upload..." on every platform.

This commit keeps tauri-action for the heavy lifting and adds:

1. Three post-build steps inside the matrix (one per platform) that
   `gh release upload --clobber` the missing sig files and updater
   archives.

2. A new `publish-updater-json` job that runs once all three platforms
   have finished, downloads every *.sig from the release, composes
   latest.json via jq (which handles the multi-line .sig content as a
   JSON string), and uploads it.

The auto-updater endpoint configured in tauri.conf.json (releases/
latest/download/latest.json) will now actually resolve, and the
in-app silent check on startup will surface a toast when a newer
version is published.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- package.json
- src-tauri/Cargo.toml (+ Cargo.lock refresh)
- src-tauri/tauri.conf.json

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 19, 2026 17:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Release prep for v1.4.3: a post-audit cleanup pass (dead-code pruning, hard-gating Clippy in CI, scoped #[allow]s), real bug fixes in the batch extractor (runtime failed counter + streaming checkpoint persistence) and in two Svelte 5 components (bind:this refs not reactive), and a CI fix that finally composes/publishes latest.json so the in-app auto-updater works.

Changes:

  • Refactor batch extractor to use a new process_all_with_progress callback so per-item success/failure is counted definitively (no double-counting retries) and checkpoint is persisted streaming-style; covered by 2 regression tests.
  • Prune unused public APIs/variants/fields across db/, core/, error.rs and tighten remaining #[allow(dead_code)] justifications; switch CustomSelect / TaskLogger refs to $state(...) for Svelte 5 reactivity.
  • Bump version to 1.4.3 across all manifests; remove Clippy continue-on-error; add release-workflow steps that re-upload .sig/updater bundles missed by tauri-action and a new publish-updater-json job that composes latest.json via jq.

Reviewed changes

Copilot reviewed 19 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
.github/workflows/ci.yml Remove continue-on-error on Clippy → hard gate.
.github/workflows/release.yml Re-upload missing .sig/updater assets per platform; new publish-updater-json job to compose & upload latest.json.
package.json / src-tauri/Cargo.toml / Cargo.lock / tauri.conf.json Version bump to 1.4.3.
src-tauri/src/core/extractor/batch.rs Switch to process_all_with_progress; runtime failed counter via Cell; streaming checkpoint persistence on each item; drop process_batch_with_defaults; add 2 regression tests.
src-tauri/src/core/extractor/resilience.rs New process_all_with_progress with per-item completion callback; remove unused TimeoutGuard::elapsed.
src-tauri/src/core/extractor/checkpoint.rs Remove unused find_latest.
src-tauri/src/core/extractor/timing.rs Remove unused record_step / measure / timed helpers.
src-tauri/src/core/extractor/mod.rs Drop process_batch_with_defaults re-export.
src-tauri/src/core/manifest.rs Drop unused action field from ManifestFile.
src-tauri/src/core/watcher.rs / commands/watcher.rs Remove unused Modified variant + its DTO mapping.
src-tauri/src/db/product_files.rs Remove unused insert_product_files / delete_product_files; tests migrated to insert_product_files_batch.
src-tauri/src/db/import_tasks.rs Remove unused list_recent_tasks.
src-tauri/src/db/models.rs Tighten #[allow(dead_code)] reason for with_vendor.
src-tauri/src/error.rs Remove unused AppError::InvalidArchive variant + mapping.
src/lib/components/ui/CustomSelect.svelte Wrap listEl in $state(...) so the conditional bind:this is reactive.
src/lib/components/layout/TaskLogger.svelte Wrap scrollEl in $state(...) so the auto-scroll $effect re-runs on mount.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# jq is preinstalled on ubuntu-latest and handles JSON escaping
# (notably the newlines inside .sig contents).
jq -n \
--arg version "$TAG" \
Comment on lines +185 to +197
read_sig() {
local name="$1"
if [ -f "$name" ]; then cat "$name"; else echo ""; fi
}

# Asset naming matches Tauri 2's default bundler output.
DARWIN_SIG=$(read_sig "FileManagerDaz_aarch64.app.tar.gz.sig")
LINUX_SIG=$(read_sig "FileManagerDaz_${VERSION}_amd64.AppImage.tar.gz.sig")
WIN_SIG=$(read_sig "FileManagerDaz_${VERSION}_x64-setup.nsis.zip.sig")

DARWIN_URL="${BASE_URL}/FileManagerDaz_aarch64.app.tar.gz"
LINUX_URL="${BASE_URL}/FileManagerDaz_${VERSION}_amd64.AppImage.tar.gz"
WIN_URL="${BASE_URL}/FileManagerDaz_${VERSION}_x64-setup.nsis.zip"
CI uses rust-toolchain@stable which pulled 1.95 and added a handful
of lints that 1.91 (the local baseline) didn't run. Fix them all:

- `unnecessary_sort_by` ×3: replace `sort_by(|a, b| b.X.cmp(&a.X))`
  with `sort_by_key(|x| std::cmp::Reverse(x.X))` in
  `commands/products.rs`, `core/destination.rs`,
  `core/scene_analyzer.rs`.

- `collapsible_match` in `core/catalog.rs`: fold the inner
  `if e.name().as_ref() == b"Product"` into the match arm guard.

- `unused_assignments` ×4 in `core/extractor/recursive.rs`: every
  `move_counts.errors += 1` was immediately followed by `return Err(…)`
  so the counter mutation was dead. Drop the bumps; the move log
  already records the error.

113/113 tests still pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@yaniswav
yaniswav merged commit 1689319 into main May 19, 2026
1 check passed
@yaniswav
yaniswav deleted the chore/post-audit-followup branch May 19, 2026 20:06
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.

2 participants