Skip to content

feat: add dry-run workflows#1395

Merged
s0up4200 merged 8 commits intodevelopfrom
codex/1122-dry-run-toggle
Feb 6, 2026
Merged

feat: add dry-run workflows#1395
s0up4200 merged 8 commits intodevelopfrom
codex/1122-dry-run-toggle

Conversation

@s0up4200
Copy link
Collaborator

@s0up4200 s0up4200 commented Feb 2, 2026

Adds dry run toggle and logging for workflow automations.

Closes #1393

Summary by CodeRabbit

  • New Features

    • Per-workflow dry-run mode with detailed dry-run activity recording and non-mutating previews.
  • UI

    • Dry-run badge, descriptive notes and adjusted dialog titles; dry-run summaries shown across tags, categories, limits, moves, programs, and deletes.
    • Dry run toggle and enable-with/without-dry-run prompt when enabling workflows.
  • Import/Export

    • Workflow export/import preserves dry-run setting.
  • Database

    • Added dry_run column to automations schema.
  • Types

    • Dry-run outcome and related fields surfaced in activity and automation types.
  • Tests

    • Tests added for dry-run activity recording.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

Walkthrough

Adds per-automation dry-run support end-to-end: DB migration and model fields, API payload, service orchestration to record dry-run activities without mutating state, tests, export/import and type updates, and UI changes to toggle and display dry-run results.

Changes

Cohort / File(s) Summary
Database & Migration
internal/database/migrations/058_add_automation_dry_run.sql, internal/database/db_test.go
Adds dry_run INTEGER NOT NULL DEFAULT 0 column to automations table and updates test schema.
Core Model
internal/models/automation.go
Adds exported DryRun bool to Automation and propagates dry_run through ListByInstance/Get/Create/Update SQL paths.
Activity Model
internal/models/automation_activity.go
Adds ActivityOutcomeDryRun = "dry-run" to activity outcomes.
API Handler
internal/api/handlers/automations.go
Adds optional DryRun *bool to AutomationPayload and applies provided value when creating/updating automations.
Service Logic
internal/services/automations/service.go
Introduces dry-run orchestration (separates dry-run vs live apply), adds helpers (ruleUsesCondition, dedupeHashes), pendingDeletion, recordDryRunActivities, run-item builders, and integrates dry-run recording without mutating state.
Service Tests
internal/services/automations/service_test.go
Adds TestRecordDryRunActivities_Deletes to assert dry-run delete activity logging; imports time.
Frontend Types & Export/Import
web/src/types/index.ts, web/src/lib/workflow-utils.ts
Adds dryRun to Automation/AutomationInput and WorkflowExport round-trip; includes "dry-run" in activity outcome union.
Workflow Dialog UI
web/src/components/instances/preferences/WorkflowDialog.tsx
Adds dryRun to form state, Dry run toggle, localStorage-backed prompt when enabling workflows, and flows to preview/apply with dry-run.
Activity Run Dialog UI
web/src/components/instances/preferences/AutomationActivityRunDialog.tsx
Displays "(dry run)" in dialog title and shows descriptive note when outcome is dry-run.
Workflows Overview UI
web/src/components/instances/preferences/WorkflowsOverview.tsx
Adds formatCountWithVerb, formatDeleteDryRunSummary, updates formatters to accept optional outcome, renders dry-run badges/text, and includes dry-run in filtering logic.
Misc / Manifest
internal/api/handlers/automations.go, package.json
Handler accepts dryRun in payload; minor manifest/test adjustments.

Sequence Diagram

sequenceDiagram
    actor User
    participant UI as WorkflowDialog
    participant API as API Handler
    participant Service as Automation Service
    participant ActivityStore as Activity Store
    participant DB as Database

    User->>UI: Toggle Enable + Dry run
    UI->>API: POST/PUT automation { dryRun: true }
    API->>Service: Create/Update + trigger apply flow
    Service->>Service: Split apply -> dry-run branch & live branch
    Service->>ActivityStore: recordDryRunActivities(pending items)
    ActivityStore->>DB: INSERT activities (outcome="dry-run")
    DB-->>ActivityStore: OK
    Service-->>API: return dry-run activity summary
    API-->>UI: Response with dry-run activities
    UI->>User: Display "(dry run)" badges and run details
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

api

Poem

🐰 I hopped through rules with cautious cheer,
I logged each step but kept things clear.
A gentle preview, no files gone astray,
I nibble the path and show the way.
Dry-run lights glow — safe as play.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: add dry-run workflows' directly describes the main objective: adding dry-run support to workflow automations.
Linked Issues check ✅ Passed The implementation fully addresses issue #1393: adds a dry-run toggle in the workflow editor [UI in WorkflowDialog.tsx], implements dry-run simulation without executing actions [via recordDryRunActivities and applyRulesForInstance], provides activity logging showing what would happen [ActivityOutcomeDryRun], and includes optional prompt on first enable [dryRunPrompt logic].
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing dry-run workflows: database schema additions, backend service orchestration, activity tracking, and frontend UI controls. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/1122-dry-run-toggle

Comment @coderabbitai help to get the list of available commands and usage tips.

@s0up4200 s0up4200 added enhancement New feature or request automations area/backend Backend changes area/frontend Frontend changes database:migrations go Pull requests that update go code typescript labels Feb 2, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
web/src/lib/workflow-utils.ts (1)

175-188: ⚠️ Potential issue | 🟠 Major

Preserve dryRun when parsing import JSON.
parseImportJSON never reads dryRun, so imported workflows lose the flag.

✅ Suggested fix
   // Optional intervalSeconds
   if (typeof obj.intervalSeconds === "number" && obj.intervalSeconds >= 60) {
     data.intervalSeconds = obj.intervalSeconds
   }
+
+  // Optional dryRun
+  if (typeof obj.dryRun === "boolean") {
+    data.dryRun = obj.dryRun
+  } else if (obj.dryRun !== undefined) {
+    return { data: null, error: "Invalid 'dryRun' field" }
+  }
web/src/types/index.ts (1)

356-379: ⚠️ Potential issue | 🔴 Critical

Remove duplicate programName field (TS2300).
programName is declared twice in the details object (lines 367 and 378), causing a TypeScript compilation error. Remove the second occurrence.

🛠️ Proposed fix
-    programName?: string
🤖 Fix all issues with AI agents
In `@internal/services/automations/service_test.go`:
- Around line 1336-1338: Replace the explicit empty-string equality check with
testify's empty assertion: change the assertion that compares
mockDB.activities[0].Hash to "" to use assert.Empty(t,
mockDB.activities[0].Hash) so the test uses the idiomatic empty check alongside
the existing require.Len(t, mockDB.activities, 1) and assert.Equal for Action
(models.ActivityActionDeletedCondition).

In `@internal/services/automations/service.go`:
- Around line 1519-1525: The file fails gofmt; reformat the affected block
around the dryRun check and the instLastApplied update to comply with gofmt
style: run `gofmt -w` (or `gofmt -w internal/services/automations/service.go`)
or use your editor's Go formatter so the code around the `if !dryRun { ...
s.mu.Lock(); instLastApplied[h] = now; s.mu.Unlock() }` block is properly
formatted; ensure no stray spacing or line breaks remain so the linter/pipeline
passes.
- Around line 1032-1049: The current sequence runs live rules before dry-run
rules causing live updates to instLastApplied and making dry-run rules skip
recent torrents; swap the calls so s.applyRulesForInstance(ctx, instanceID,
force, dryRunRules, true) runs before s.applyRulesForInstance(ctx, instanceID,
force, liveRules, false) to ensure dry-run rules evaluate all torrents
(reference variables liveRules, dryRunRules and function applyRulesForInstance,
and the instLastApplied/SkipWithin behavior).
🧹 Nitpick comments (1)
web/src/components/instances/preferences/WorkflowsOverview.tsx (1)

243-253: Consider simplifying the nested ternary for readability.

The deeply nested ternary operators can be harder to read and maintain. A mapping object would be cleaner:

♻️ Suggested refactor
 function formatDeleteDryRunSummary(details: AutomationActivity["details"], action: AutomationActivity["action"]): string {
   const count = details?.count ?? 0
-  const label = action === "deleted_ratio"
-    ? "ratio limit"
-    : action === "deleted_seeding"
-      ? "seeding limit"
-      : action === "deleted_unregistered"
-        ? "unregistered"
-        : "condition"
+  const labelMap: Record<string, string> = {
+    deleted_ratio: "ratio limit",
+    deleted_seeding: "seeding limit",
+    deleted_unregistered: "unregistered",
+    deleted_condition: "condition",
+  }
+  const label = labelMap[action] ?? "condition"
   return `${count} torrent${count !== 1 ? "s" : ""} would be deleted (${label})`
 }

@blacksmith-sh

This comment has been minimized.

q6xxmtnpjn-bit

This comment was marked as spam.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@web/src/components/instances/preferences/WorkflowsOverview.tsx`:
- Around line 187-253: The dry-run verbs should use passive voice for
consistency: update formatPausedSummary to set verb to "would be paused" when
outcome === "dry-run", update formatCategoryChangedSummary to set verb to "would
be moved" for dry-run, and update formatMovedSummary to use "would be moved" for
dry-run (keeping the existing failed branch using "failed to move"); these
changes are in the functions formatPausedSummary, formatCategoryChangedSummary,
and formatMovedSummary and rely on the existing formatCountWithVerb helper to
produce the final string.

@s0up4200 s0up4200 merged commit 13aaac8 into develop Feb 6, 2026
13 checks passed
@s0up4200 s0up4200 deleted the codex/1122-dry-run-toggle branch February 6, 2026 11:29
@ShagoY
Copy link

ShagoY commented Feb 8, 2026

Since pr-1362, when I try to go back to develop, I get the following error:
{ "level": "fatal", "error": "failed to run migrations: failed to apply migrations: failed to execute migration 058_add_automation_dry_run.sql: SQL logic error: duplicate column name: dry_run (1)", "time": "2026-02-08T19:02:35+01:00", "message": "Failed to initialize database" }

@s0up4200
Copy link
Collaborator Author

s0up4200 commented Feb 8, 2026

Since pr-1362, when I try to go back to develop, I get the following error: { "level": "fatal", "error": "failed to run migrations: failed to apply migrations: failed to execute migration 058_add_automation_dry_run.sql: SQL logic error: duplicate column name: dry_run (1)", "time": "2026-02-08T19:02:35+01:00", "message": "Failed to initialize database" }

Please dont run PRs like this without knowing the consequences.

Easiest fix for you right now is to shut down qui, delete qui.db + qui.db-shm and qui.db-wal. Then start qui again.
This means you have to reconnect and add your automations etc. again.

Alternatively you could try this:

Shut down qui.
Run:

sqlite3 -cmd ".timeout 5000" qui.db "PRAGMA table_info(automations);"
sqlite3 -cmd ".timeout 5000" qui.db "SELECT filename, applied_at FROM migrations WHERE filename LIKE '058%';"

If automations already has dry_run but no row for 058_add_automation_dry_run.sql, just mark it applied:

sqlite3 -cmd ".timeout 5000" qui.db \
"INSERT OR IGNORE INTO migrations (filename) VALUES ('058_add_automation_dry_run.sql');"

If you see some other 058 row then rename that row:

sqlite3 -cmd ".timeout 5000" qui.db \
"UPDATE migrations SET filename='058_add_automation_dry_run.sql' WHERE filename='058_add_dryrun.sql';"

@coderabbitai coderabbitai bot mentioned this pull request Feb 21, 2026
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Feb 22, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.13.1` → `v1.14.0` |

---

### Release Notes

<details>
<summary>autobrr/qui (ghcr.io/autobrr/qui)</summary>

### [`v1.14.0`](https://github.com/autobrr/qui/releases/tag/v1.14.0)

[Compare Source](autobrr/qui@v1.13.1...v1.14.0)

#### Changelog

##### New Features

- [`6f8e6ed`](autobrr/qui@6f8e6ed): feat(api): add torrent field endpoint for select all copy ([#&#8203;1477](autobrr/qui#1477)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`2d9b4c7`](autobrr/qui@2d9b4c7): feat(automation): trigger external programs automatically via automation rules ([#&#8203;1284](autobrr/qui#1284)) ([@&#8203;0rkag](https://github.com/0rkag))
- [`32692a4`](autobrr/qui@32692a4): feat(automations): Add the ability to define the move automation with a templated path ([#&#8203;1376](autobrr/qui#1376)) ([@&#8203;ColinHebert](https://github.com/ColinHebert))
- [`61bbeb1`](autobrr/qui@61bbeb1): feat(automations): add Resume action to Automations ([#&#8203;1350](autobrr/qui#1350)) ([@&#8203;cy1der](https://github.com/cy1der))
- [`450b98f`](autobrr/qui@450b98f): feat(automations): grouping + release fields ([#&#8203;1467](autobrr/qui#1467)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`18d4a64`](autobrr/qui@18d4a64): feat(automations): match tracker conditions by display name ([#&#8203;1420](autobrr/qui#1420)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`7c67b82`](autobrr/qui@7c67b82): feat(automations): show activity run details ([#&#8203;1385](autobrr/qui#1385)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`177ef4d`](autobrr/qui@177ef4d): feat(crossseed): Multiple hard/reflink dirs ([#&#8203;1289](autobrr/qui#1289)) ([@&#8203;rybertm](https://github.com/rybertm))
- [`a72b673`](autobrr/qui@a72b673): feat(crossseed): gazelle-only OPS/RED ([#&#8203;1436](autobrr/qui#1436)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6a29384`](autobrr/qui@6a29384): feat(crossseed): match bit depth ([#&#8203;1427](autobrr/qui#1427)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c7fd5aa`](autobrr/qui@c7fd5aa): feat(dirscan): add max searchee age filter ([#&#8203;1486](autobrr/qui#1486)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`d595a55`](autobrr/qui@d595a55): feat(documentation): add AI doc actions and llms discoverability ([#&#8203;1451](autobrr/qui#1451)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`562ab3f`](autobrr/qui@562ab3f): feat(metrics): add tracker metrics ([#&#8203;1073](autobrr/qui#1073)) ([@&#8203;Winter](https://github.com/Winter))
- [`1b9aa9d`](autobrr/qui@1b9aa9d): feat(notifications): add shoutrrr and notifiarr ([#&#8203;1371](autobrr/qui#1371)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6d1dac7`](autobrr/qui@6d1dac7): feat(pwa): add protocol and file handlers for magnet links and torrent files ([#&#8203;783](autobrr/qui#783)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`42fa501`](autobrr/qui@42fa501): feat(torrents): add unified cross-instance torrent table ([#&#8203;1481](autobrr/qui#1481)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`498eaca`](autobrr/qui@498eaca): feat(ui): show speeds in page title ([#&#8203;1292](autobrr/qui#1292)) ([@&#8203;NoLife141](https://github.com/NoLife141))
- [`94a506e`](autobrr/qui@94a506e): feat(unregistered): nem talalhato ([#&#8203;1483](autobrr/qui#1483)) ([@&#8203;KyleSanderson](https://github.com/KyleSanderson))
- [`8bf366c`](autobrr/qui@8bf366c): feat(web): add logs nav ([#&#8203;1458](autobrr/qui#1458)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`babc88d`](autobrr/qui@babc88d): feat(web): add responsive popover with mobile drawer support ([#&#8203;1398](autobrr/qui#1398)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`06d341b`](autobrr/qui@06d341b): feat(web): add torrent table selection quick wins ([#&#8203;1455](autobrr/qui#1455)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`56fbbec`](autobrr/qui@56fbbec): feat(web): hide selection column ([#&#8203;1460](autobrr/qui#1460)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`46814aa`](autobrr/qui@46814aa): feat(web): qBittorrent autorun preferences ([#&#8203;1430](autobrr/qui#1430)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`342643e`](autobrr/qui@342643e): feat(web): unify instance settings & qbit options dialog ([#&#8203;1257](autobrr/qui#1257)) ([@&#8203;0rkag](https://github.com/0rkag))
- [`e634d01`](autobrr/qui@e634d01): feat: add cross-seed blocklist ([#&#8203;1391](autobrr/qui#1391)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`13aaac8`](autobrr/qui@13aaac8): feat: add dry-run workflows ([#&#8203;1395](autobrr/qui#1395)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`f01101d`](autobrr/qui@f01101d): feat: add option to disable built-in authentication ([#&#8203;1464](autobrr/qui#1464)) ([@&#8203;libussa](https://github.com/libussa))
- [`6d1da50`](autobrr/qui@6d1da50): feat: download individual content files from context menu ([#&#8203;1465](autobrr/qui#1465)) ([@&#8203;libussa](https://github.com/libussa))
- [`77e9abf`](autobrr/qui@77e9abf): feat: migrate to dodopayments ([#&#8203;1407](autobrr/qui#1407)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`9f6c856`](autobrr/qui@9f6c856): feat: support basic auth for ARR and Torznab ([#&#8203;1442](autobrr/qui#1442)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Bug Fixes

- [`8a06d4b`](autobrr/qui@8a06d4b): fix(api): correct add-torrent OpenAPI param names and add missing fields ([#&#8203;1426](autobrr/qui#1426)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b9a687c`](autobrr/qui@b9a687c): fix(api): honor explicit basic auth clear from URL userinfo ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`948ca67`](autobrr/qui@948ca67): fix(api): tighten CORS/auth routing and base URL joins ([#&#8203;1325](autobrr/qui#1325)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`12bea13`](autobrr/qui@12bea13): fix(automations): improve applied action summaries ([#&#8203;1478](autobrr/qui#1478)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8fe658b`](autobrr/qui@8fe658b): fix(automations): negate regex match for NotContains/NotEqual operators ([#&#8203;1441](autobrr/qui#1441)) ([@&#8203;andresatierf](https://github.com/andresatierf))
- [`8a808eb`](autobrr/qui@8a808eb): fix(automations): respect remove-only tag conditions ([#&#8203;1444](autobrr/qui#1444)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`a72715e`](autobrr/qui@a72715e): fix(backups): add failure cooldown and export throttling ([#&#8203;1214](autobrr/qui#1214)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`2e75c14`](autobrr/qui@2e75c14): fix(backups): skip exports missing metadata ([#&#8203;1362](autobrr/qui#1362)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5658421`](autobrr/qui@5658421): fix(config): update commented log settings in place ([#&#8203;1402](autobrr/qui#1402)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`62c50c0`](autobrr/qui@62c50c0): fix(crossseed): tighten TV title matching ([#&#8203;1445](autobrr/qui#1445)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`e7cc489`](autobrr/qui@e7cc489): fix(dirscan): prevent immediate requeue after cancel ([#&#8203;1446](autobrr/qui#1446)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`36cbfcf`](autobrr/qui@36cbfcf): fix(docs): avoid mdx jsx parse error ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`d8d6f62`](autobrr/qui@d8d6f62): fix(filters): stabilize dense sidebar layout ([#&#8203;1384](autobrr/qui#1384)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b959fc6`](autobrr/qui@b959fc6): fix(orphanscan): NFC-normalize paths to avoid false orphans ([#&#8203;1422](autobrr/qui#1422)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`598e994`](autobrr/qui@598e994): fix(reflink): retry EAGAIN clones ([#&#8203;1360](autobrr/qui#1360)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`aaa5ee0`](autobrr/qui@aaa5ee0): fix(reflinktree): retry transient FICLONE EINVAL and add diagnostics ([#&#8203;1487](autobrr/qui#1487)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`647af31`](autobrr/qui@647af31): fix(rss): enable rules list scrolling ([#&#8203;1359](autobrr/qui#1359)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c356a6f`](autobrr/qui@c356a6f): fix(sync): Optimize torrent sorting and reference management ([#&#8203;1474](autobrr/qui#1474)) ([@&#8203;KyleSanderson](https://github.com/KyleSanderson))
- [`cf4310e`](autobrr/qui@cf4310e): fix(ui): update placeholder text in ArrInstanceForm based on instance type ([#&#8203;1375](autobrr/qui#1375)) ([@&#8203;pashioya](https://github.com/pashioya))
- [`92b6748`](autobrr/qui@92b6748): fix(web): format IPv6 peer addresses and copy IP without port ([#&#8203;1417](autobrr/qui#1417)) ([@&#8203;sleepm](https://github.com/sleepm))
- [`25039bc`](autobrr/qui@25039bc): fix(web): handle SSO session expiry behind Cloudflare Access and other proxies ([#&#8203;1438](autobrr/qui#1438)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`77fe310`](autobrr/qui@77fe310): fix(web): prevent category submenu re-render ([#&#8203;1357](autobrr/qui#1357)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`a42ab1e`](autobrr/qui@a42ab1e): fix(web): raise instance preferences max value from 999 to 99999 ([#&#8203;1311](autobrr/qui#1311)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`540168c`](autobrr/qui@540168c): fix(web): raise virtualization threshold ([#&#8203;1355](autobrr/qui#1355)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`8547dc6`](autobrr/qui@8547dc6): fix(web): remove column filters when column is hidden ([#&#8203;1418](autobrr/qui#1418)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`6b09b8d`](autobrr/qui@6b09b8d): fix(web): remove panel size bounds ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`db4cdc4`](autobrr/qui@db4cdc4): fix(web): show piece size in torrent details ([#&#8203;1365](autobrr/qui#1365)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1f94a06`](autobrr/qui@1f94a06): fix(web): use absolute for scroll-to-top on desktop ([#&#8203;1419](autobrr/qui#1419)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`e31fe3a`](autobrr/qui@e31fe3a): fix: detect tracker health support after qBit upgrade ([#&#8203;909](autobrr/qui#909)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`52f01da`](autobrr/qui@52f01da): fix: disable update indicators when update checks are off ([#&#8203;1364](autobrr/qui#1364)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`f7e3fed`](autobrr/qui@f7e3fed): fix: normalize DD+ and DDP file keys ([#&#8203;1456](autobrr/qui#1456)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Other Changes

- [`d914301`](autobrr/qui@d914301): chore(ci): fire Blacksmith (my wallet screamed) ([#&#8203;1408](autobrr/qui#1408)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b43327d`](autobrr/qui@b43327d): chore(deps): bump the golang group with 2 updates ([#&#8203;1378](autobrr/qui#1378)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`57747bd`](autobrr/qui@57747bd): chore(deps): bump the npm group across 1 directory with 27 updates ([#&#8203;1379](autobrr/qui#1379)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`a43850d`](autobrr/qui@a43850d): chore(docs): add BIMI SVG logo ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`914bede`](autobrr/qui@914bede): chore(funding): add Patreon to FUNDING.yml ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8b76f1e`](autobrr/qui@8b76f1e): docs(automations): clarify tag matching examples ([#&#8203;1457](autobrr/qui#1457)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`2994054`](autobrr/qui@2994054): docs(readme): restore concise README ([#&#8203;1452](autobrr/qui#1452)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`51237d4`](autobrr/qui@51237d4): docs: Add configuration reference ([#&#8203;1440](autobrr/qui#1440)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`741462c`](autobrr/qui@741462c): docs: add Windows installation guide ([#&#8203;1463](autobrr/qui#1463)) ([@&#8203;soggy-cr0uton](https://github.com/soggy-cr0uton))
- [`6a11430`](autobrr/qui@6a11430): docs: clarify autobrr filter + apply troubleshooting ([#&#8203;1459](autobrr/qui#1459)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5a2edc2`](autobrr/qui@5a2edc2): docs: update 2 documentation files ([#&#8203;1454](autobrr/qui#1454)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`139ada9`](autobrr/qui@139ada9): docs: update contributing.md ([#&#8203;1470](autobrr/qui#1470)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`3909aa1`](autobrr/qui@3909aa1): docs: update docs/features/automations.md ([#&#8203;1447](autobrr/qui#1447)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5dc57ca`](autobrr/qui@5dc57ca): docs: update intro.md ([#&#8203;1453](autobrr/qui#1453)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5d9e986`](autobrr/qui@5d9e986): perf(web): memoize useDateTimeFormatters ([#&#8203;1403](autobrr/qui#1403)) ([@&#8203;jabloink](https://github.com/jabloink))

**Full Changelog**: <autobrr/qui@v1.13.1...v1.14.0>

#### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.14.0`
- `docker pull ghcr.io/autobrr/qui:latest`

#### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNS43IiwidXBkYXRlZEluVmVyIjoiNDMuMjUuNyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4154
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/backend Backend changes area/frontend Frontend changes automations database:migrations enhancement New feature or request go Pull requests that update go code typescript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add "Dry Run" Toggle to Workflow Automation

3 participants