Commit Graph
278 Commits
Author SHA1 Message Date
Safihre bcd1585ea1 Set timeout for translations job
Prevents the workflow from running indefinitely.
2026-09-08 13:24:58 +02:00
Safihre 8343f182aa Pass Discord webhook secrets to release workflow 2026-09-08 11:14:07 +02:00
Safihre 64f342ca1d Use dedicated token for tools update workflow
Replaces `github.token` with `secrets.AUTOMATION_GITHUB_TOKEN` to provide consistent and appropriate permissions for automated tasks like creating pull requests.
2026-09-04 11:43:30 +02:00
mnightingale e1009e1e92 Install the browser and its system dependencies in one step 2026-08-30 17:01:15 +02:00
mnightingale 5088e14fa6 Drive the functional tests with Playwright instead of Selenium 2026-08-30 17:01:15 +02:00
Safihre 90f092a1a5 Automate LinuxServer.io Docker image builds
Trigger the corresponding LinuxServer.io Docker image build (develop for
pre-releases, master for stable) after a SABnzbd release, ensuring the
Docker images are kept up-to-date.
2026-08-27 11:54:55 +02:00
renovate[bot] 743ff89cff Update all dependencies (#3591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-24 07:37:39 +02:00
Safihre bdd821233f Re-enable par2cmdline in tools-update workflow 2026-08-20 17:30:33 +02:00
renovate[bot]andSafihre e0bf9218bb Update all dependencies (#3575)
* Update all dependencies

* Add feedparser-sgmllib

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Safihre <safihre@sabnzbd.org>
2026-08-18 10:01:04 +02:00
Safihre 1fcada54f9 Fetch full history for Claude AI review workflow
The Claude AI code action requires the complete Git history to properly diff pull requests against their base branches.
2026-08-11 13:31:29 +01:00
mnightingale 35d5355f49 Replace CherryPy with Uvicorn and Starlette (#3550)
* Migrate web interface from CherryPy to Uvicorn/Starlette

Squashed rebase of feature/uvicorn (34 commits) onto develop, reconciled
with ~3 months of intervening develop changes.

Replaces the CherryPy webserver and request handling with Uvicorn/Starlette
across the API, web interface, RSS, config pages and related modules.

Reconciliation with develop during the rebase:
- api.py: kept develop's security/behaviour fixes (orphan path-traversal
  guard, expanded log redaction incl. host_whitelist and
  remote_label_replacement, get_dconfig single-return, get_retryable_jobs,
  connections default, translated NNTP test errors) on top of the Starlette
  request/response rewrite.
- interface.py: ported the RSS route handlers to develop's DB-backed
  RSSRepository API (process_feed, rss_repository / find_job_by_url /
  clear_feed / clear_downloaded / flag_downloaded).
- misc.py: kept develop's hachoir-based get_media_duration.
- requirements.txt: dropped the CherryPy stack, adopted develop's newer pins.

Also applied ruff --fix (PEP 604 unions, builtin generics) to align with
develop's lint config.

Verified: ruff check, black --check, and the affected test suites
(9413 passed, 1 skipped) all pass.

* Update starlette/uvicorn versions

* Fix race issues in global rss state

* Fix test race in server shutdown

The uvicorn migration turned /shutdown (and the shutdown API) into fire-and-forget: it spawned shutdown_program() in a background thread and replied immediately, whereas develop ran it synchronously and only replied once halt() had persisted all state. Because the module-scoped test teardown doesn't wait for the process to exit, the next module's clean_cache_dir wiped the shared cache dir (and reused the fixed port) while the previous instance was still saving state and holding the port — producing the three intermittent failures (deleted sabnzbd.log → "File log disabled or not found"; un-persisted [sorters] → KeyError; stale instance → missing wizard .quoteBlock).

* Fix robots and description, add favicon

* Remove remains of http basic auth

* Setup Starlette once configuration is available, fix static file relative cwd and url_base config

* abort_and_show_error when webserver fails to start

* Guard stopping webserver that never started

* Delegate XFF handling to ProxyHeadersMiddleware

* Merged params at request.state.params instead of modifying private apis

* Both shutdown routes share implementation and do not block event loop

* Run sync handlers via run_in_threadpool and facilitate eventual migration to async

* Pool database connections

* Online backup of database due to WAL changes

* Fix exception on None request.client (test clients or unix sockets)

* Fix flakey tests due to process not fully shutting down

* Restore X-Frame-Options behaviour via middleware

* Fix set_config_default with multiple keywords

* Remove broken logging call

* Restore api logging functionality

* Cache-Control: no-store

* Login only via POST

* Remove 401 (basic-auth) and add 404 handling via redirect

* Fix crash when shutdown not an int

* Use BaseRedirectResponse helper

* Remove trailing slashes from wizard routes

* URL helper, absolute URLs everywhere, fixes issues with nested navigation

* Fix scheduler adding multiple daysofweek

* Restore CherryPy api behaviour merging body with query params (body wins)

* Clearer documentation of get_request_params and request_params

* First stage supporting gradual api async

* Fix rss ajax consuming flash

* Restore access log functionality

* Hostname check in middleware

* Request logging in middleware

* Param parsing in middleware

* Security checks in middleware

* secured_expose is now purely route registration

* Lookup api handler once per request

* Fix flakey alert dialogs

* Trigger restart via BackgroundTask

* Restore CherryPy first param wins and get/post consistency

* Remove dead code

* Secure cookies based on protocol the client used

* Fix various issues with port_is_free

1. port_is_free answered the wrong question. It connect-probed ("is something answering?") rather than bind-probed ("can I bind?"). A port could report free and then kill startup at uvicorn's bind().
2. The bind-all remap crossed address families. :: was mapped to 127.0.0.1, probing IPv4 for an IPv6 bind — a regression against portend, which maps :: → ::1.
3. The call sites passed the wrong host. browserhost is a client-reachable address; the thing that has to be bindable is web_host.
4. Errors were swallowed. A bare except OSError hid gaierror, so an unresolvable host reported "free".
5. find_free_port had a port-0 trap. Under a bind-probe, currentport=0 always succeeds and returned 0 — the old failure sentinel. Now guarded, and None instead of 0.
6. Ports 80/443 were misdiagnosed. EACCES was folded into "occupied", producing ten futile probes and a panic claiming another program held the port. PermissionError now propagates to a dedicated panic explaining the actual remedies.
7. The tests were largely tautological. Three tests covering one branch, an IPv6 test with no IPv6 in it, a timeout test that never engaged the timeout, TOCTOU-prone fixed-range probes, no SO_REUSEADDR on the helper listener, and nothing asserting the property that matters — that "free" implies bindable.
8. A portability bug I introduced, then fixed. I'd baked Linux SO_REUSEADDR overlap semantics into four assertions; macOS differs. Now platform-aware, with the IPv6 regression re-covered by checking the socket family directly.

* Claim the bind address for uvicorn on startup, resolves "49" in err handling from cherrypy

* Rename function BaseRedirectResponse to base_redirect_response

* Restore error response on change web directory

* Add missing typings

* Fix return type of retry job for future types

* A better fix for xdist compatibility - test overwrote db_path

* Secure session cookies (rss flash)

* Inline or remove some functions

* Retry job futuretype behaviour

* Sneak a worksteal fix in

* Test and fix retry_job futuretype behaviour
2026-08-11 13:27:51 +01:00
mnightingale ec6ba3baae Speed up tests with pytest-xdist (#3546)
* Speed up tests with pytest-xdist

* Ignore request failures when the server disappeared

* Fix tests which modify module globals

* Fix lang change leaking

* Fix transaction compilation order breaking tests

* Always load a clean config and fix related tests

* No module globals

* Fix other test classes assigning module level by making calls

* Replace from sabnzbd.cfg import so monkeypatch works

* More global poisoning

* Fix dependant tests which worksteal breaks

* More global vars

* Drop loadscope until more failures are resolved

* Due to how pytest-xdist is implemented, the -s/--capture=no option does not work

* monkeypatch db_path

* Also patch startup_done

* loadscope
2026-08-10 17:44:18 +01:00
Safihre d6474cb695 Skip par2cmdline update for now due to custom macOS binaries 2026-08-10 14:11:30 +01:00
Safihre d530764a6d Allow collaborators to trigger Claude review 2026-08-10 08:59:37 +02:00
renovate[bot] b7da5b6684 Update actions/setup-python action to v7 (#3543)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-03 08:42:06 +02:00
renovate[bot] 2d2b88e771 Update all dependencies (#3509)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-20 08:34:32 +02:00
Safihre ab879cc7d0 Add workflow for manual Claude AI code reviews
Allows maintainers to trigger an AI code review on a pull request by commenting `@claude`.
2026-07-16 21:05:55 +02:00
Safihre 44777dc3cf Add Python 3.15-dev to integration testing matrix
Install libxml2 and libxslt for integration testing
2026-07-14 16:04:10 +02:00
renovate[bot] 28eaa6c20d Update all dependencies (#3495)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-13 07:00:26 +02:00
Safihre 02ced74783 Validate SABnzbd web UI availability in snap build workflow
The previous smoke test only verified that the snap binary could be executed. This change enhances the CI workflow to confirm the SABnzbd web UI starts successfully and responds on its default port after snap installation, improving the robustness of the build pipeline.
2026-07-09 11:08:30 +02:00
renovate[bot] 8afb8a91e2 Update all dependencies (#3487)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-06 14:16:16 +02:00
Safihre ef8df5b578 Consolidate Python versioning in build workflow
Moves the `PYTHON_VERSION` environment variable to a global scope in `build_release.yml`. This ensures consistent Python versions across build jobs (Windows and macOS) and centralizes it for easier future updates (e.g., via Renovate).
2026-07-03 14:09:41 +02:00
Safihre 6b76603c60 Add workflow for automated bundled tool updates (#3482)
* Add workflow for automated bundled tool updates

Introduces a GitHub Actions workflow to automatically check for new releases of unrar, 7-Zip, and par2cmdline-turbo. When new versions are found, it creates a pull request with the updated binaries for review.

* Use preinstalled 7Zip so we don't execute any downloaded executables

Leverage the preinstalled 7-Zip utility on GitHub Actions runners to
extract Windows UnRAR.exe and 7za.exe. This prevents executing internet executables with write-permission GH-token.

* Inline the unrar version detection

And rename to RAW_VERSION
2026-07-03 09:23:04 +02:00
renovate[bot] 6db37d9883 Update all dependencies (#3474)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-29 10:18:02 +02:00
Safihre 2a9e9954a8 Stop Renovate from updating cryptography
It is already pinned for macOS release and open-ended for all others (like the CI-tests).
2026-06-29 09:59:49 +02:00
Safihre a55251f698 Adjust Windows artifact uploads for SignPath requirements
Unsigned Windows binaries and installers are now uploaded with `archive: true` for release tags. This creates a "zip-in-zip" layout that SignPath requires for consuming artifacts.
2026-06-26 14:46:54 +02:00
Safihre e21798b163 Conditionally push local translation edits to Transifex
The `translations.yml` workflow now fetches `fetch-depth: 2` and uses `git show`
to detect if the current commit includes local `.po` file changes. If local
translation edits are present, `tx push --translation` is used; otherwise,
only `--source` is pushed. This prevents accidental overwrites of Transifex
translations with outdated local files when no `.po` changes were intended.

This commit also includes updated translations in various `.po` files and adds
guidance for translators to `po_to_json.py` for consistency.
2026-06-22 10:24:51 +02:00
Safihre 7daa0159ec Add Renovate manager for Transifex CLI
Configures Renovate to automatically track and update the `transifex/cli`
version specified in the `translations.yml` GitHub Actions workflow.
2026-06-19 14:33:50 +02:00
Safihre f0d3e6b8b9 Restrict stale bot to 'Support' labeled issues
Once we confirm a request or bug, the Support label is removed
2026-06-19 14:06:44 +02:00
Safihre 5d3286654e Enforce explicit dependency pinning for improved build security
All direct and transitive dependencies are now explicitly listed in
`requirements.txt` files, and `pip install` commands consistently use
`--no-dependencies`.

This approach ensures that only the specified versions are installed,
enhancing supply chain security and build reproducibility by preventing
automatic dependency resolution. The `--upgrade` flag was removed from
these installations as it is no longer necessary with fully pinned
dependencies.
2026-06-16 11:54:11 +02:00
Safihre 4d6df7dd22 Remove no-binary workaround for charset-normalizer
The explicit `--no-binary` flag for `charset-normalizer` is no longer required in the release build workflow, simplifying dependency installation.
2026-06-15 11:34:46 +02:00
Safihre 6f342dade5 Streamline release artifact handling and enforce Windows signing
This update improves the release workflow by:
*   Configuring GitHub Actions `upload-artifact` to transfer files directly without unnecessary zipping, simplifying artifact retrieval for subsequent jobs.
*   Integrating `pefile` to perform an Authenticode signature check on the Windows installer, ensuring all official releases are properly signed.
2026-06-15 10:26:24 +02:00
Safihre 957d0fcd01 Apprise now supports paho-mqtt 2.1.0 2026-06-15 08:54:00 +02:00
Safihre 92489bb624 Configure Renovate to track Python and sabctools versions
Adds custom managers to allow Renovate to detect and propose updates for the Python version used in the build workflow and the `SABCTOOLS_VERSION_REQUIRED` constant. Removes `sabctools` from the ignore list to enable these updates.
2026-06-07 13:03:03 +02:00
Safihre fa982d4f69 Update macOS build Python to 3.14.5 2026-06-07 12:42:59 +02:00
Safihre f3ef46e5c2 Add concurrency control to translations workflow
Cancel in-progress runs on the same branch to prevent redundant executions and conserve resources.
2026-06-04 11:08:31 +02:00
Safihre 57e371aba5 Pin tempora to 5.8.1
Tempora 5.9.0 introduced an incompatibility with jaraco.classes that caused issues. Downgrade to the previous stable version and prevent Renovate from automatically updating it again.
Closes #3441
2026-05-26 16:45:58 +02:00
Safihre a344726c68 Drop support for Python 3.9
Luckily no Ubuntu LTS versions uses it!
https://documentation.ubuntu.com/ubuntu-for-developers/reference/availability/python/
2026-05-26 14:34:19 +02:00
Safihre 60f555117c Limit GitHub Actions workflow concurrency
Configures `concurrency` for the build, snap, and integration testing workflows. This prevents multiple concurrent runs of the same workflow on the same branch and automatically cancels older, in-progress runs when a new one is triggered.
2026-05-15 16:26:27 +02:00
Safihre b942e06297 Introduce Ruff linter for improved code quality
Integrates the Ruff linter into the CI workflow alongside Black. This enhances code quality and consistency by catching common issues. Addresses an initial `F821` (undefined name) finding in `__init__.py` identified by Ruff, ensuring explicit module referencing.
2026-05-13 14:25:06 +02:00
Safihre 7abb39d02d Move black config to pyproject
So later we can also add ruff
2026-05-10 12:00:01 +02:00
Safihre 4ded1e242e Use github-actions user for translations updates
The `translations.yml` workflow commits generated updates to the repository. This change explicitly grants `contents: write` permission, removes the custom `AUTOMATION_GITHUB_TOKEN`, and streamlines redundant `git config` setup, relying on the default `GITHUB_TOKEN` for all repository modifications.
2026-04-30 16:11:38 +02:00
Safihre 7bdfb54bee Limit GitHub Actions workflow permissions
Explicitly define the minimum required permissions for various GitHub Actions workflows. This adheres to the principle of least privilege, enhancing security by limiting the scope of access granted to the GITHUB_TOKEN.
2026-04-30 15:51:52 +02:00
Safihre 96975050b5 Increase Renovate minimum release age to 14 days
Further reduces the risk of immediately adopting new dependency versions by allowing more time for potential issues or vulnerabilities to be discovered.
2026-04-30 11:06:57 +02:00
Safihre 2cb598309d Add type field to issue templates 2026-04-29 16:25:26 +02:00
Safihre c776f086cd Secure Transifex CLI installation in workflow
To mitigate supply-chain attack risks, this changes the Transifex CLI installation method. Instead of executing a shell script from the `master` branch, a specific version (v1.6.17) is now downloaded directly as a pre-built binary from GitHub releases. This ensures a consistent, verified tool version is used in a workflow that commits directly to the repository.
2026-04-28 23:50:59 +02:00
Safihre f1f9be77d7 Replace git-auto-commit-action with native git commands
Remove reliance on an external GitHub Action by using standard `git` commands for committing and pushing translation updates. This aligns with the strategy of minimizing third-party dependencies in workflows.
2026-04-28 23:20:40 +02:00
Safihre e5eb66bc7b Set minimum release age to 7 days for Renovate dependency updates
Reducing the supply chain-attack risk of immediately adopting versions.
2026-04-28 23:08:10 +02:00
Safihre 395f8dc4c5 Only build snaps for tags and relevant file changes 2026-04-14 18:01:18 +02:00
Safihre 375cc4955d Put releasing a new version behind manual approval 2026-04-14 09:42:13 +02:00