From 0d827e85117e5043128abb28fc25400b2b1c9885 Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Fri, 14 Nov 2025 21:41:07 -0800
Subject: [PATCH 01/13] Documentation: add {{doc_title}} placeholder
---
docs/usage.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/usage.md b/docs/usage.md
index d902f6814..cac2c964f 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -553,6 +553,7 @@ applied. You can use the following placeholders in the template with any trigger
- `{{added_time}}`: added time in HH:MM format
- `{{original_filename}}`: original file name without extension
- `{{filename}}`: current file name without extension
+- `{{doc_title}}`: current document title
The following placeholders are only available for "added" or "updated" triggers
From 7cd802cf48d742bab5afee5c91fb3c29b5ca315a Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sat, 15 Nov 2025 14:24:15 -0800
Subject: [PATCH 02/13] Bump version to 2.19.6
---
pyproject.toml | 2 +-
src-ui/package.json | 2 +-
src-ui/src/environments/environment.prod.ts | 2 +-
src/paperless/version.py | 2 +-
uv.lock | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 1c3f1ee2f..8c54ce8ae 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "paperless-ngx"
-version = "2.19.5"
+version = "2.19.6"
description = "A community-supported supercharged document management system: scan, index and archive all your physical documents"
readme = "README.md"
requires-python = ">=3.10"
diff --git a/src-ui/package.json b/src-ui/package.json
index c5e945759..339b378c2 100644
--- a/src-ui/package.json
+++ b/src-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "paperless-ngx-ui",
- "version": "2.19.5",
+ "version": "2.19.6",
"scripts": {
"preinstall": "npx only-allow pnpm",
"ng": "ng",
diff --git a/src-ui/src/environments/environment.prod.ts b/src-ui/src/environments/environment.prod.ts
index 8bec5f2e6..b81beb1c5 100644
--- a/src-ui/src/environments/environment.prod.ts
+++ b/src-ui/src/environments/environment.prod.ts
@@ -6,7 +6,7 @@ export const environment = {
apiVersion: '9', // match src/paperless/settings.py
appTitle: 'Paperless-ngx',
tag: 'prod',
- version: '2.19.5',
+ version: '2.19.6',
webSocketHost: window.location.host,
webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:',
webSocketBaseUrl: base_url.pathname + 'ws/',
diff --git a/src/paperless/version.py b/src/paperless/version.py
index 8efbb2728..5657b929a 100644
--- a/src/paperless/version.py
+++ b/src/paperless/version.py
@@ -1,6 +1,6 @@
from typing import Final
-__version__: Final[tuple[int, int, int]] = (2, 19, 5)
+__version__: Final[tuple[int, int, int]] = (2, 19, 6)
# Version string like X.Y.Z
__full_version_str__: Final[str] = ".".join(map(str, __version__))
# Version string like X.Y
diff --git a/uv.lock b/uv.lock
index c6808ae7b..17d7d9f30 100644
--- a/uv.lock
+++ b/uv.lock
@@ -2115,7 +2115,7 @@ wheels = [
[[package]]
name = "paperless-ngx"
-version = "2.19.5"
+version = "2.19.6"
source = { virtual = "." }
dependencies = [
{ name = "babel", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
From b6e3827ab19f8dd354a813dc9f57a69161c3b428 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sat, 15 Nov 2025 19:03:46 -0800
Subject: [PATCH 03/13] Documentation: Add v2.19.6 changelog (#11374)
---------
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
---
docs/changelog.md | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/docs/changelog.md b/docs/changelog.md
index 064e37adb..7abea13d4 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,5 +1,35 @@
# Changelog
+## paperless-ngx 2.19.6
+
+### Bug Fixes
+
+- Chore: include password validation on user edit [@shamoon](https://github.com/shamoon) ([#11308](https://github.com/paperless-ngx/paperless-ngx/pull/11308))
+- Fix: include BASE_URL when constructing for workflows [@ebardsley](https://github.com/ebardsley) ([#11360](https://github.com/paperless-ngx/paperless-ngx/pull/11360))
+- Fixhancement: refactor email attachment logic [@shamoon](https://github.com/shamoon) ([#11336](https://github.com/paperless-ngx/paperless-ngx/pull/11336))
+- Fixhancement: trim whitespace for some text searches [@shamoon](https://github.com/shamoon) ([#11357](https://github.com/paperless-ngx/paperless-ngx/pull/11357))
+- Fix: update Outlook refresh token when refreshed [@shamoon](https://github.com/shamoon) ([#11341](https://github.com/paperless-ngx/paperless-ngx/pull/11341))
+- Fix: only cache remote version data for version checking [@shamoon](https://github.com/shamoon) ([#11320](https://github.com/paperless-ngx/paperless-ngx/pull/11320))
+- Fix: include replace none logic in storage path preview, improve jinja conditionals for empty metadata [@shamoon](https://github.com/shamoon) ([#11315](https://github.com/paperless-ngx/paperless-ngx/pull/11315))
+
+### Dependencies
+
+- docker(deps): bump astral-sh/uv from 0.9.7-python3.12-bookworm-slim to 0.9.9-python3.12-bookworm-slim @[dependabot[bot]](https://github.com/apps/dependabot) ([#11338](https://github.com/paperless-ngx/paperless-ngx/pull/11338))
+
+### All App Changes
+
+
+7 changes
+
+- Fix: include BASE_URL when constructing for workflows [@ebardsley](https://github.com/ebardsley) ([#11360](https://github.com/paperless-ngx/paperless-ngx/pull/11360))
+- Fixhancement: refactor email attachment logic [@shamoon](https://github.com/shamoon) ([#11336](https://github.com/paperless-ngx/paperless-ngx/pull/11336))
+- Fixhancement: trim whitespace for some text searches [@shamoon](https://github.com/shamoon) ([#11357](https://github.com/paperless-ngx/paperless-ngx/pull/11357))
+- Fix: update Outlook refresh token when refreshed [@shamoon](https://github.com/shamoon) ([#11341](https://github.com/paperless-ngx/paperless-ngx/pull/11341))
+- Fix: only cache remote version data for version checking [@shamoon](https://github.com/shamoon) ([#11320](https://github.com/paperless-ngx/paperless-ngx/pull/11320))
+- Fix: include replace none logic in storage path preview, improve jinja conditionals for empty metadata [@shamoon](https://github.com/shamoon) ([#11315](https://github.com/paperless-ngx/paperless-ngx/pull/11315))
+- Chore: include password validation on user edit [@shamoon](https://github.com/shamoon) ([#11308](https://github.com/paperless-ngx/paperless-ngx/pull/11308))
+
+
## paperless-ngx 2.19.5
### Bug Fixes
From b3d6359afc32af7a110b6e3aa8a877161157f04a Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Mon, 17 Nov 2025 10:02:32 -0800
Subject: [PATCH 04/13] Chore: set signal receivers with weak=False
---
src/documents/management/commands/document_importer.py | 8 ++++++--
src/documents/signals/handlers.py | 6 +++---
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/documents/management/commands/document_importer.py b/src/documents/management/commands/document_importer.py
index 282f5c48e..3e614c6a6 100644
--- a/src/documents/management/commands/document_importer.py
+++ b/src/documents/management/commands/document_importer.py
@@ -48,12 +48,13 @@ if settings.AUDIT_LOG_ENABLED:
@contextmanager
-def disable_signal(sig, receiver, sender) -> Generator:
+def disable_signal(sig, receiver, sender, *, weak: bool | None = None) -> Generator:
try:
sig.disconnect(receiver=receiver, sender=sender)
yield
finally:
- sig.connect(receiver=receiver, sender=sender)
+ kwargs = {"weak": weak} if weak is not None else {}
+ sig.connect(receiver=receiver, sender=sender, **kwargs)
class Command(CryptMixin, BaseCommand):
@@ -258,16 +259,19 @@ class Command(CryptMixin, BaseCommand):
post_save,
receiver=update_filename_and_move_files,
sender=Document,
+ weak=False,
),
disable_signal(
m2m_changed,
receiver=update_filename_and_move_files,
sender=Document.tags.through,
+ weak=False,
),
disable_signal(
post_save,
receiver=update_filename_and_move_files,
sender=CustomFieldInstance,
+ weak=False,
),
disable_signal(
post_save,
diff --git a/src/documents/signals/handlers.py b/src/documents/signals/handlers.py
index 738ecb086..bce376f76 100644
--- a/src/documents/signals/handlers.py
+++ b/src/documents/signals/handlers.py
@@ -393,9 +393,9 @@ class CannotMoveFilesException(Exception):
# should be disabled in /src/documents/management/commands/document_importer.py handle
-@receiver(models.signals.post_save, sender=CustomFieldInstance)
-@receiver(models.signals.m2m_changed, sender=Document.tags.through)
-@receiver(models.signals.post_save, sender=Document)
+@receiver(models.signals.post_save, sender=CustomFieldInstance, weak=False)
+@receiver(models.signals.m2m_changed, sender=Document.tags.through, weak=False)
+@receiver(models.signals.post_save, sender=Document, weak=False)
def update_filename_and_move_files(
sender,
instance: Document | CustomFieldInstance,
From 533b64cb70ca2f5d895bd34110020a84c5f3896a Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Mon, 17 Nov 2025 10:22:54 -0800
Subject: [PATCH 05/13] Chore: replace test image URLs to our own files
(#11390)
---
src/paperless_mail/tests/samples/html.eml | 2 +-
src/paperless_mail/tests/samples/sample.html | 2 +-
src/paperless_mail/tests/test_parsers_live.py | 37 ++-----------------
3 files changed, 6 insertions(+), 35 deletions(-)
diff --git a/src/paperless_mail/tests/samples/html.eml b/src/paperless_mail/tests/samples/html.eml
index 97747ceab..aaac68cc4 100644
--- a/src/paperless_mail/tests/samples/html.eml
+++ b/src/paperless_mail/tests/samples/html.eml
@@ -55,7 +55,7 @@ Content-Transfer-Encoding: 7bit
Some Text
-
+
and an embedded image.
diff --git a/src/paperless_mail/tests/samples/sample.html b/src/paperless_mail/tests/samples/sample.html
index 584cd5d64..c1fd52d43 100644
--- a/src/paperless_mail/tests/samples/sample.html
+++ b/src/paperless_mail/tests/samples/sample.html
@@ -6,7 +6,7 @@
Some Text
-
+
and an embedded image.
diff --git a/src/paperless_mail/tests/test_parsers_live.py b/src/paperless_mail/tests/test_parsers_live.py
index 456cb47d5..fd052cc26 100644
--- a/src/paperless_mail/tests/test_parsers_live.py
+++ b/src/paperless_mail/tests/test_parsers_live.py
@@ -2,7 +2,6 @@ import os
import shutil
import subprocess
import tempfile
-import time
from pathlib import Path
import httpx
@@ -54,34 +53,6 @@ class TestUrlCanary:
Verify certain URLs are still available so testing is valid still
"""
- @classmethod
- def _fetch_wikimedia(cls, url: str) -> httpx.Response:
- """
- Wikimedia occasionally throttles automated requests (HTTP 429). Retry a few
- times with a short backoff so the tests stay stable, and skip if throttling
- persists.
- """
- last_resp: httpx.Response | None = None
- # Wikimedia rejects requests without a browser-like User-Agent header and returns 403.
- headers = {
- "User-Agent": (
- "Mozilla/5.0 (X11; Linux x86_64) "
- "AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/123.0.0.0 Safari/537.36"
- ),
- }
- for delay in (0, 1, 2):
- resp = httpx.get(url, headers=headers, timeout=30.0)
- if resp.status_code != httpx.codes.TOO_MANY_REQUESTS:
- return resp
- last_resp = resp
- time.sleep(delay)
-
- pytest.skip(
- "Wikimedia throttled the canary request with HTTP 429; try rerunning later.",
- )
- return last_resp # pragma: no cover
-
def test_online_image_exception_on_not_available(self):
"""
GIVEN:
@@ -96,8 +67,8 @@ class TestUrlCanary:
whether this image stays online forever, so here we check if we can detect if is not
available anymore.
"""
- resp = self._fetch_wikimedia(
- "https://upload.wikimedia.org/wikipedia/en/f/f7/nonexistent.png",
+ resp = httpx.get(
+ "https://docs.paperless-ngx.com/assets/non-existent.png",
)
with pytest.raises(httpx.HTTPStatusError) as exec_info:
resp.raise_for_status()
@@ -119,8 +90,8 @@ class TestUrlCanary:
"""
# Now check the URL used in samples/sample.html
- resp = self._fetch_wikimedia(
- "https://upload.wikimedia.org/wikipedia/en/f/f7/RickRoll.png",
+ resp = httpx.get(
+ "https://docs.paperless-ngx.com/assets/logo_full_white.svg",
)
resp.raise_for_status()
From 0e5ab7f3e0ccaf03fbcd90f9b484756f7f1b289b Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Mon, 17 Nov 2025 12:47:55 -0800
Subject: [PATCH 06/13] Fix: support for custom field ordering w advanced
search (#11383)
---
src/documents/index.py | 90 +++++++++++++++++++++++---
src/documents/tests/test_api_search.py | 59 +++++++++++++++++
2 files changed, 140 insertions(+), 9 deletions(-)
diff --git a/src/documents/index.py b/src/documents/index.py
index 90cbb8000..9446c7db1 100644
--- a/src/documents/index.py
+++ b/src/documents/index.py
@@ -287,15 +287,75 @@ class DelayedQuery:
self.first_score = None
self.filter_queryset = filter_queryset
self.suggested_correction = None
+ self._manual_hits_cache: list | None = None
def __len__(self) -> int:
+ if self._manual_sort_requested():
+ manual_hits = self._manual_hits()
+ return len(manual_hits)
+
page = self[0:1]
return len(page)
+ def _manual_sort_requested(self):
+ ordering = self.query_params.get("ordering", "")
+ return ordering.lstrip("-").startswith("custom_field_")
+
+ def _manual_hits(self):
+ if self._manual_hits_cache is None:
+ q, mask, suggested_correction = self._get_query()
+ self.suggested_correction = suggested_correction
+
+ results = self.searcher.search(
+ q,
+ mask=mask,
+ filter=MappedDocIdSet(self.filter_queryset, self.searcher.ixreader),
+ limit=None,
+ )
+ results.fragmenter = highlight.ContextFragmenter(surround=50)
+ results.formatter = HtmlFormatter(tagname="span", between=" ... ")
+
+ if not self.first_score and len(results) > 0:
+ self.first_score = results[0].score
+
+ if self.first_score:
+ results.top_n = [
+ (
+ (hit[0] / self.first_score) if self.first_score else None,
+ hit[1],
+ )
+ for hit in results.top_n
+ ]
+
+ hits_by_id = {hit["id"]: hit for hit in results}
+ matching_ids = list(hits_by_id.keys())
+
+ ordered_ids = list(
+ self.filter_queryset.filter(id__in=matching_ids).values_list(
+ "id",
+ flat=True,
+ ),
+ )
+ ordered_ids = list(dict.fromkeys(ordered_ids))
+
+ self._manual_hits_cache = [
+ hits_by_id[_id] for _id in ordered_ids if _id in hits_by_id
+ ]
+ return self._manual_hits_cache
+
def __getitem__(self, item):
if item.start in self.saved_results:
return self.saved_results[item.start]
+ if self._manual_sort_requested():
+ manual_hits = self._manual_hits()
+ start = 0 if item.start is None else item.start
+ stop = item.stop
+ hits = manual_hits[start:stop] if stop is not None else manual_hits[start:]
+ page = ManualResultsPage(hits)
+ self.saved_results[start] = page
+ return page
+
q, mask, suggested_correction = self._get_query()
self.suggested_correction = suggested_correction
sortedby, reverse = self._get_query_sortedby()
@@ -315,21 +375,33 @@ class DelayedQuery:
if not self.first_score and len(page.results) > 0 and sortedby is None:
self.first_score = page.results[0].score
- page.results.top_n = list(
- map(
- lambda hit: (
- (hit[0] / self.first_score) if self.first_score else None,
- hit[1],
- ),
- page.results.top_n,
- ),
- )
+ page.results.top_n = [
+ (
+ (hit[0] / self.first_score) if self.first_score else None,
+ hit[1],
+ )
+ for hit in page.results.top_n
+ ]
self.saved_results[item.start] = page
return page
+class ManualResultsPage(list):
+ def __init__(self, hits):
+ super().__init__(hits)
+ self.results = ManualResults(hits)
+
+
+class ManualResults:
+ def __init__(self, hits):
+ self._docnums = [hit.docnum for hit in hits]
+
+ def docs(self):
+ return self._docnums
+
+
class LocalDateParser(English):
def reverse_timezone_offset(self, d):
return (d.replace(tzinfo=django_timezone.get_current_timezone())).astimezone(
diff --git a/src/documents/tests/test_api_search.py b/src/documents/tests/test_api_search.py
index 8f316c145..5a2fc9b52 100644
--- a/src/documents/tests/test_api_search.py
+++ b/src/documents/tests/test_api_search.py
@@ -89,6 +89,65 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
self.assertEqual(len(results), 0)
self.assertCountEqual(response.data["all"], [])
+ def test_search_custom_field_ordering(self):
+ custom_field = CustomField.objects.create(
+ name="Sortable field",
+ data_type=CustomField.FieldDataType.INT,
+ )
+ d1 = Document.objects.create(
+ title="first",
+ content="match",
+ checksum="A1",
+ )
+ d2 = Document.objects.create(
+ title="second",
+ content="match",
+ checksum="B2",
+ )
+ d3 = Document.objects.create(
+ title="third",
+ content="match",
+ checksum="C3",
+ )
+ CustomFieldInstance.objects.create(
+ document=d1,
+ field=custom_field,
+ value_int=30,
+ )
+ CustomFieldInstance.objects.create(
+ document=d2,
+ field=custom_field,
+ value_int=10,
+ )
+ CustomFieldInstance.objects.create(
+ document=d3,
+ field=custom_field,
+ value_int=20,
+ )
+
+ with AsyncWriter(index.open_index()) as writer:
+ index.update_document(writer, d1)
+ index.update_document(writer, d2)
+ index.update_document(writer, d3)
+
+ response = self.client.get(
+ f"/api/documents/?query=match&ordering=custom_field_{custom_field.pk}",
+ )
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
+ self.assertEqual(
+ [doc["id"] for doc in response.data["results"]],
+ [d2.id, d3.id, d1.id],
+ )
+
+ response = self.client.get(
+ f"/api/documents/?query=match&ordering=-custom_field_{custom_field.pk}",
+ )
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
+ self.assertEqual(
+ [doc["id"] for doc in response.data["results"]],
+ [d1.id, d3.id, d2.id],
+ )
+
def test_search_multi_page(self):
with AsyncWriter(index.open_index()) as writer:
for i in range(55):
From c3ac102eba3641f8a43753068dc17a82966f8511 Mon Sep 17 00:00:00 2001
From: Michael Martin
Date: Mon, 17 Nov 2025 13:11:49 -0800
Subject: [PATCH 07/13] Enhancement: speed-up docker container startup (#11134)
This alters the retry/backoff logic in the init-wait-for-db script to be more
optimistic about database availability. During regular deployment and
operations of paperless-ngx, it's common to restart the application server with
the database instance already running, so we should optimize for this case.
Instead of unconditionally delaying 5 seconds between each connection attempt,
start with a minimum delay of 1 second and increase the delay linearly with
each attempt, maxing out at 10 seconds. This makes the retry count-based
failure mode less practical, so instead we just use a timeout-based approach.*
*NOTE: the original implementation would have an effective timeout of 25s. This
alters the behavior to 60s.
Additionally, this removes an unnecessary 5s delay that was injected in the
postgres case. The script uses a more comprehensive connection check for
postgres than it does mariadb, so if anything this 5s delay after getting an
"ok" response from the DB was extra unnecessary in the postgres case.
---
.../s6-overlay/s6-rc.d/init-wait-for-db/run | 90 +++++++++----------
1 file changed, 43 insertions(+), 47 deletions(-)
diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/run
index ede8a654a..1739edd61 100755
--- a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/run
+++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/run
@@ -1,70 +1,66 @@
#!/command/with-contenv /usr/bin/bash
# shellcheck shell=bash
+# vim: set ft=bash ts=4 sw=4 sts=4 et :
-declare -r log_prefix="[init-db-wait]"
+set -euo pipefail
+
+declare -r LOG_PREFIX="[init-db-wait]"
+
+declare -ri TIMEOUT=60
+declare -i ATTEMPT=0
+declare -i DELAY=0
+declare -i STARTED_AT=${EPOCHSECONDS:?EPOCHSECONDS var unset}
+
+delay_next_attempt() {
+ local -i elapsed=$(( EPOCHSECONDS - STARTED_AT ))
+ local -ri remaining=$(( TIMEOUT - elapsed ))
+
+ if (( remaining <= 0 )); then
+ echo "${LOG_PREFIX} Unable to connect after $elapsed seconds."
+ exit 1
+ fi
+
+ DELAY+=1
+
+ # clamp to remaining time
+ if (( DELAY > remaining )); then
+ DELAY=$remaining
+ fi
+
+ ATTEMPT+=1
+ echo "${LOG_PREFIX} Attempt $ATTEMPT failed! Trying again in $DELAY seconds..."
+ sleep "$DELAY"
+}
wait_for_postgres() {
- local attempt_num=1
- local -r max_attempts=5
-
- echo "${log_prefix} Waiting for PostgreSQL to start..."
+ echo "${LOG_PREFIX} Waiting for PostgreSQL to start..."
local -r host="${PAPERLESS_DBHOST:-localhost}"
local -r port="${PAPERLESS_DBPORT:-5432}"
local -r user="${PAPERLESS_DBUSER:-paperless}"
- # Disable warning, host and port can't have spaces
- # shellcheck disable=SC2086
- while [ ! "$(pg_isready -h ${host} -p ${port} --username ${user})" ]; do
-
- if [ $attempt_num -eq $max_attempts ]; then
- echo "${log_prefix} Unable to connect to database."
- exit 1
- else
- echo "${log_prefix} Attempt $attempt_num failed! Trying again in 5 seconds..."
- fi
-
- attempt_num=$(("$attempt_num" + 1))
- sleep 5
+ while ! pg_isready -h "${host}" -p "${port}" --username "${user}"; do
+ delay_next_attempt
done
- # Extra in case this is a first start
- sleep 5
- echo "Connected to PostgreSQL"
+ echo "${LOG_PREFIX} Connected to PostgreSQL"
}
wait_for_mariadb() {
- echo "${log_prefix} Waiting for MariaDB to start..."
+ echo "${LOG_PREFIX} Waiting for MariaDB to start..."
- local -r host="${PAPERLESS_DBHOST:=localhost}"
- local -r port="${PAPERLESS_DBPORT:=3306}"
+ local -r host="${PAPERLESS_DBHOST:-localhost}"
+ local -r port="${PAPERLESS_DBPORT:-3306}"
- local attempt_num=1
- local -r max_attempts=5
-
- # Disable warning, host and port can't have spaces
- # shellcheck disable=SC2086
- while ! true > /dev/tcp/$host/$port; do
-
- if [ $attempt_num -eq $max_attempts ]; then
- echo "${log_prefix} Unable to connect to database."
- exit 1
- else
- echo "${log_prefix} Attempt $attempt_num failed! Trying again in 5 seconds..."
-
- fi
-
- attempt_num=$(("$attempt_num" + 1))
- sleep 5
+ while ! true > "/dev/tcp/$host/$port"; do
+ delay_next_attempt
done
- echo "Connected to MariaDB"
+ echo "${LOG_PREFIX} Connected to MariaDB"
}
-if [[ "${PAPERLESS_DBENGINE}" == "mariadb" ]]; then
- echo "${log_prefix} Waiting for MariaDB to report ready"
+if [[ "${PAPERLESS_DBENGINE:-}" == "mariadb" ]]; then
wait_for_mariadb
-elif [[ -n "${PAPERLESS_DBHOST}" ]]; then
- echo "${log_prefix} Waiting for postgresql to report ready"
+elif [[ -n "${PAPERLESS_DBHOST:-}" ]]; then
wait_for_postgres
fi
- echo "${log_prefix} Database is ready"
+echo "${LOG_PREFIX} Database is ready"
From a45692aa0f716bf7ad893d6f1693e96e83b3c098 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 17 Nov 2025 13:38:26 -0800
Subject: [PATCH 08/13] docker(deps): bump astral-sh/uv (#11394)
---
updated-dependencies:
- dependency-name: astral-sh/uv
dependency-version: 0.9.10-python3.12-bookworm-slim
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
Dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dockerfile b/Dockerfile
index 49423d98a..aca06edc5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -32,7 +32,7 @@ RUN set -eux \
# Purpose: Installs s6-overlay and rootfs
# Comments:
# - Don't leave anything extra in here either
-FROM ghcr.io/astral-sh/uv:0.9.9-python3.12-bookworm-slim AS s6-overlay-base
+FROM ghcr.io/astral-sh/uv:0.9.10-python3.12-bookworm-slim AS s6-overlay-base
WORKDIR /usr/src/s6
From b053b353322507a6cfdb979f9735a2f27dd65a0e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 17 Nov 2025 21:58:10 +0000
Subject: [PATCH 09/13] Chore(deps): Update django-allauth[mfa,socialaccount]
requirement from ~=65.4.0 to ~=65.12.1 (#11198)
* Chore(deps): Update django-allauth[mfa,socialaccount] requirement
---
updated-dependencies:
- dependency-name: django-allauth[mfa,socialaccount]
dependency-version: 65.12.1
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
* Update ratelimit mock path
---------
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
---
pyproject.toml | 2 +-
src/paperless/tests/test_adapter.py | 4 ++--
uv.lock | 21 ++++-----------------
3 files changed, 7 insertions(+), 20 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 8c54ce8ae..b0b57279c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -26,7 +26,7 @@ dependencies = [
# WARNING: django does not use semver.
# Only patch versions are guaranteed to not introduce breaking changes.
"django~=5.2.5",
- "django-allauth[mfa,socialaccount]~=65.4.0",
+ "django-allauth[mfa,socialaccount]~=65.12.1",
"django-auditlog~=3.2.1",
"django-cachalot~=2.8.0",
"django-celery-results~=2.6.0",
diff --git a/src/paperless/tests/test_adapter.py b/src/paperless/tests/test_adapter.py
index b87c47096..bbd7ff73e 100644
--- a/src/paperless/tests/test_adapter.py
+++ b/src/paperless/tests/test_adapter.py
@@ -54,8 +54,8 @@ class TestCustomAccountAdapter(TestCase):
# False because request host is not in allowed hosts
self.assertFalse(adapter.is_safe_url(url))
- @mock.patch("allauth.core.ratelimit._consume_rate", return_value=True)
- def test_pre_authenticate(self, mock_consume_rate):
+ @mock.patch("allauth.core.internal.ratelimit.consume", return_value=True)
+ def test_pre_authenticate(self, mock_consume):
adapter = get_adapter()
request = HttpRequest()
request.get_host = mock.Mock(return_value="example.com")
diff --git a/uv.lock b/uv.lock
index 17d7d9f30..c40b0d273 100644
--- a/uv.lock
+++ b/uv.lock
@@ -689,13 +689,13 @@ wheels = [
[[package]]
name = "django-allauth"
-version = "65.4.1"
+version = "65.12.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "asgiref", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/b1/e7/b3232c27da9f43e3db72d16addd90891ee233fa058ddd0588bafcded2ea7/django_allauth-65.4.1.tar.gz", hash = "sha256:60b32aef7dbbcc213319aa4fd8f570e985266ea1162ae6ef7a26a24efca85c8c", size = 1558220, upload-time = "2025-02-07T09:35:18.359Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/52/94/75d7f8c59e061d1b66a6d917b287817fe02d2671c9e6376a4ddfb3954989/django_allauth-65.12.1.tar.gz", hash = "sha256:662666ff2d5c71766f66b1629ac7345c30796813221184e13e11ed7460940c6a", size = 1967971, upload-time = "2025-10-16T16:39:58.342Z" }
[package.optional-dependencies]
mfa = [
@@ -703,9 +703,9 @@ mfa = [
{ name = "qrcode", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
socialaccount = [
+ { name = "oauthlib", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "pyjwt", extra = ["crypto"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "requests", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
- { name = "requests-oauthlib", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
[[package]]
@@ -2262,7 +2262,7 @@ requires-dist = [
{ name = "concurrent-log-handler", specifier = "~=0.9.25" },
{ name = "dateparser", specifier = "~=1.2" },
{ name = "django", specifier = "~=5.2.5" },
- { name = "django-allauth", extras = ["mfa", "socialaccount"], specifier = "~=65.4.0" },
+ { name = "django-allauth", extras = ["mfa", "socialaccount"], specifier = "~=65.12.1" },
{ name = "django-auditlog", specifier = "~=3.2.1" },
{ name = "django-cachalot", specifier = "~=2.8.0" },
{ name = "django-celery-results", specifier = "~=2.6.0" },
@@ -3379,19 +3379,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
]
-[[package]]
-name = "requests-oauthlib"
-version = "2.0.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "oauthlib", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
- { name = "requests", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/42/f2/05f29bc3913aea15eb670be136045bf5c5bbf4b99ecb839da9b422bb2c85/requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9", size = 55650, upload-time = "2024-03-22T20:32:29.939Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", size = 24179, upload-time = "2024-03-22T20:32:28.055Z" },
-]
-
[[package]]
name = "rich"
version = "14.1.0"
From c924213f32a1307c4911ce2a3b3c9014668e56d4 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 17 Nov 2025 22:26:33 +0000
Subject: [PATCH 10/13] Chore(deps): Bump django-filter from 25.1 to 25.2
(#11020)
Bumps [django-filter](https://github.com/carltongibson/django-filter) from 25.1 to 25.2.
- [Release notes](https://github.com/carltongibson/django-filter/releases)
- [Changelog](https://github.com/carltongibson/django-filter/blob/main/CHANGES.rst)
- [Commits](https://github.com/carltongibson/django-filter/compare/25.1...25.2)
---
updated-dependencies:
- dependency-name: django-filter
dependency-version: '25.2'
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
uv.lock | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/uv.lock b/uv.lock
index c40b0d273..eff1972ca 100644
--- a/uv.lock
+++ b/uv.lock
@@ -787,14 +787,14 @@ wheels = [
[[package]]
name = "django-filter"
-version = "25.1"
+version = "25.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/b5/40/c702a6fe8cccac9bf426b55724ebdf57d10a132bae80a17691d0cf0b9bac/django_filter-25.1.tar.gz", hash = "sha256:1ec9eef48fa8da1c0ac9b411744b16c3f4c31176c867886e4c48da369c407153", size = 143021, upload-time = "2025-02-14T16:30:53.238Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/2c/e4/465d2699cd388c0005fb8d6ae6709f239917c6d8790ac35719676fffdcf3/django_filter-25.2.tar.gz", hash = "sha256:760e984a931f4468d096f5541787efb8998c61217b73006163bf2f9523fe8f23", size = 143818, upload-time = "2025-10-05T09:51:31.521Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/07/a6/70dcd68537c434ba7cb9277d403c5c829caf04f35baf5eb9458be251e382/django_filter-25.1-py3-none-any.whl", hash = "sha256:4fa48677cf5857b9b1347fed23e355ea792464e0fe07244d1fdfb8a806215b80", size = 94114, upload-time = "2025-02-14T16:30:50.435Z" },
+ { url = "https://files.pythonhosted.org/packages/c1/40/6a02495c5658beb1f31eb09952d8aa12ef3c2a66342331ce3a35f7132439/django_filter-25.2-py3-none-any.whl", hash = "sha256:9c0f8609057309bba611062fe1b720b4a873652541192d232dd28970383633e3", size = 94145, upload-time = "2025-10-05T09:51:29.728Z" },
]
[[package]]
From beb5fe22321178645b117a8cb5dd93595e74be0c Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 17 Nov 2025 22:55:50 +0000
Subject: [PATCH 11/13] Chore(deps): Bump drf-spectacular-sidecar from 2025.9.1
to 2025.10.1 (#11019)
Bumps [drf-spectacular-sidecar](https://github.com/tfranzel/drf-spectacular-sidecar) from 2025.9.1 to 2025.10.1.
- [Commits](https://github.com/tfranzel/drf-spectacular-sidecar/compare/2025.9.1...2025.10.1)
---
updated-dependencies:
- dependency-name: drf-spectacular-sidecar
dependency-version: 2025.10.1
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
pyproject.toml | 2 +-
uv.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index b0b57279c..84da482ae 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -41,7 +41,7 @@ dependencies = [
"djangorestframework~=3.16",
"djangorestframework-guardian~=0.4.0",
"drf-spectacular~=0.28",
- "drf-spectacular-sidecar~=2025.9.1",
+ "drf-spectacular-sidecar~=2025.10.1",
"drf-writable-nested~=0.7.1",
"filelock~=3.20.0",
"flower~=2.0.1",
diff --git a/uv.lock b/uv.lock
index eff1972ca..d26f5cc60 100644
--- a/uv.lock
+++ b/uv.lock
@@ -959,14 +959,14 @@ wheels = [
[[package]]
name = "drf-spectacular-sidecar"
-version = "2025.9.1"
+version = "2025.10.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/51/e2/85a0b8dbed8631165a6b49b2aee57636da8e4e710c444566636ffd972a7b/drf_spectacular_sidecar-2025.9.1.tar.gz", hash = "sha256:da2aa45da48fff76de7a1e357b84d1eb0b9df40ca89ec19d5fe94ad1037bb3c8", size = 2420902, upload-time = "2025-09-01T11:23:24.156Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/c3/e4/99cd1b1c8c69788bd6cb6a2459674f8c75728e79df23ac7beddd094bf805/drf_spectacular_sidecar-2025.10.1.tar.gz", hash = "sha256:506a5a21ce1ad7211c28acb4e2112e213f6dc095a2052ee6ed6db1ffe8eb5a7b", size = 2420998, upload-time = "2025-10-01T11:23:27.092Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/96/24/db59146ba89491fe1d44ca8aef239c94bf3c7fd41523976090f099430312/drf_spectacular_sidecar-2025.9.1-py3-none-any.whl", hash = "sha256:8e80625209b8a23ff27616db305b9ab71c2e2d1069dacd99720a9c11e429af50", size = 2440255, upload-time = "2025-09-01T11:23:22.822Z" },
+ { url = "https://files.pythonhosted.org/packages/ab/87/70c67391e4ce68715d4dfae8dd33caeda2552af22f436ba55b8867a040fe/drf_spectacular_sidecar-2025.10.1-py3-none-any.whl", hash = "sha256:f1de343184d1a938179ce363d318258fe1e5f02f2f774625272364835f1c42bd", size = 2440241, upload-time = "2025-10-01T11:23:25.743Z" },
]
[[package]]
@@ -2277,7 +2277,7 @@ requires-dist = [
{ name = "djangorestframework", specifier = "~=3.16" },
{ name = "djangorestframework-guardian", specifier = "~=0.4.0" },
{ name = "drf-spectacular", specifier = "~=0.28" },
- { name = "drf-spectacular-sidecar", specifier = "~=2025.9.1" },
+ { name = "drf-spectacular-sidecar", specifier = "~=2025.10.1" },
{ name = "drf-writable-nested", specifier = "~=0.7.1" },
{ name = "filelock", specifier = "~=3.20.0" },
{ name = "flower", specifier = "~=2.0.1" },
From f7f94762b69d6aac2d0fc036da32ba9c12c76fab Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 17 Nov 2025 23:13:30 +0000
Subject: [PATCH 12/13] Chore(deps): Bump the actions group with 7 updates
(#11259)
Bumps the actions group with 7 updates:
| Package | From | To |
| --- | --- | --- |
| [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) | `6` | `7` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4` | `5` |
| [actions/setup-node](https://github.com/actions/setup-node) | `5` | `6` |
| [actions/download-artifact](https://github.com/actions/download-artifact) | `5` | `6` |
| [stumpylog/image-cleaner-action](https://github.com/stumpylog/image-cleaner-action) | `0.11.0` | `0.12.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3` | `4` |
| [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) | `6` | `7` |
Updates `astral-sh/setup-uv` from 6 to 7
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v6...v7)
Updates `actions/upload-artifact` from 4 to 5
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)
Updates `actions/setup-node` from 5 to 6
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v5...v6)
Updates `actions/download-artifact` from 5 to 6
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)
Updates `stumpylog/image-cleaner-action` from 0.11.0 to 0.12.0
- [Release notes](https://github.com/stumpylog/image-cleaner-action/releases)
- [Changelog](https://github.com/stumpylog/image-cleaner-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stumpylog/image-cleaner-action/compare/v0.11.0...v0.12.0)
Updates `github/codeql-action` from 3 to 4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)
Updates `stefanzweifel/git-auto-commit-action` from 6 to 7
- [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases)
- [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/v6...v7)
---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
dependency-version: '7'
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: actions
- dependency-name: actions/upload-artifact
dependency-version: '5'
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: actions
- dependency-name: actions/setup-node
dependency-version: '6'
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: actions
- dependency-name: actions/download-artifact
dependency-version: '6'
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: actions
- dependency-name: stumpylog/image-cleaner-action
dependency-version: 0.12.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: actions
- dependency-name: github/codeql-action
dependency-version: '4'
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: actions
- dependency-name: stefanzweifel/git-auto-commit-action
dependency-version: '7'
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: actions
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/ci.yml | 28 ++++++++++++-------------
.github/workflows/cleanup-tags.yml | 4 ++--
.github/workflows/codeql-analysis.yml | 4 ++--
.github/workflows/translate-strings.yml | 6 +++---
4 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 17e9a4109..76ab247fb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -88,7 +88,7 @@ jobs:
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Install uv
- uses: astral-sh/setup-uv@v6
+ uses: astral-sh/setup-uv@v7
with:
version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true
@@ -115,7 +115,7 @@ jobs:
--frozen \
mkdocs gh-deploy --force --no-history
- name: Upload artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v5
with:
name: documentation
path: site/
@@ -142,7 +142,7 @@ jobs:
with:
python-version: "${{ matrix.python-version }}"
- name: Install uv
- uses: astral-sh/setup-uv@v6
+ uses: astral-sh/setup-uv@v7
with:
version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true
@@ -208,7 +208,7 @@ jobs:
with:
version: 10
- name: Use Node.js 20
- uses: actions/setup-node@v5
+ uses: actions/setup-node@v6
with:
node-version: 20.x
cache: 'pnpm'
@@ -241,7 +241,7 @@ jobs:
with:
version: 10
- name: Use Node.js 20
- uses: actions/setup-node@v5
+ uses: actions/setup-node@v6
with:
node-version: 20.x
cache: 'pnpm'
@@ -290,7 +290,7 @@ jobs:
with:
version: 10
- name: Use Node.js 20
- uses: actions/setup-node@v5
+ uses: actions/setup-node@v6
with:
node-version: 20.x
cache: 'pnpm'
@@ -333,7 +333,7 @@ jobs:
with:
version: 10
- name: Use Node.js 20
- uses: actions/setup-node@v5
+ uses: actions/setup-node@v6
with:
node-version: 20.x
cache: 'pnpm'
@@ -459,7 +459,7 @@ jobs:
docker create --name frontend-extract ${{ fromJSON(steps.docker-meta.outputs.json).tags[0] }}
docker cp frontend-extract:/usr/src/paperless/src/documents/static/frontend src/documents/static/frontend/
- name: Upload frontend artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v5
with:
name: frontend-compiled
path: src/documents/static/frontend/
@@ -479,7 +479,7 @@ jobs:
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Install uv
- uses: astral-sh/setup-uv@v6
+ uses: astral-sh/setup-uv@v7
with:
version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true
@@ -492,12 +492,12 @@ jobs:
sudo apt-get update -qq
sudo apt-get install -qq --no-install-recommends gettext liblept5
- name: Download frontend artifact
- uses: actions/download-artifact@v5
+ uses: actions/download-artifact@v6
with:
name: frontend-compiled
path: src/documents/static/frontend/
- name: Download documentation artifact
- uses: actions/download-artifact@v5
+ uses: actions/download-artifact@v6
with:
name: documentation
path: docs/_build/html/
@@ -560,7 +560,7 @@ jobs:
sudo chown -R 1000:1000 paperless-ngx/
tar -cJf paperless-ngx.tar.xz paperless-ngx/
- name: Upload release artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v5
with:
name: release
path: dist/paperless-ngx.tar.xz
@@ -577,7 +577,7 @@ jobs:
if: github.ref_type == 'tag' && (startsWith(github.ref_name, 'v') || contains(github.ref_name, '-beta.rc'))
steps:
- name: Download release artifact
- uses: actions/download-artifact@v5
+ uses: actions/download-artifact@v6
with:
name: release
path: ./
@@ -627,7 +627,7 @@ jobs:
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Install uv
- uses: astral-sh/setup-uv@v6
+ uses: astral-sh/setup-uv@v7
with:
version: ${{ env.DEFAULT_UV_VERSION }}
enable-cache: true
diff --git a/.github/workflows/cleanup-tags.yml b/.github/workflows/cleanup-tags.yml
index e0d81bb4a..bc2ae655f 100644
--- a/.github/workflows/cleanup-tags.yml
+++ b/.github/workflows/cleanup-tags.yml
@@ -27,7 +27,7 @@ jobs:
steps:
- name: Clean temporary images
if: "${{ env.TOKEN != '' }}"
- uses: stumpylog/image-cleaner-action/ephemeral@v0.11.0
+ uses: stumpylog/image-cleaner-action/ephemeral@v0.12.0
with:
token: "${{ env.TOKEN }}"
owner: "${{ github.repository_owner }}"
@@ -53,7 +53,7 @@ jobs:
steps:
- name: Clean untagged images
if: "${{ env.TOKEN != '' }}"
- uses: stumpylog/image-cleaner-action/untagged@v0.11.0
+ uses: stumpylog/image-cleaner-action/untagged@v0.12.0
with:
token: "${{ env.TOKEN }}"
owner: "${{ github.repository_owner }}"
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index b8acfeeff..77913ba81 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -37,7 +37,7 @@ jobs:
uses: actions/checkout@v5
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -45,4 +45,4 @@ jobs:
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@v4
diff --git a/.github/workflows/translate-strings.yml b/.github/workflows/translate-strings.yml
index f94191f19..a3326cbcf 100644
--- a/.github/workflows/translate-strings.yml
+++ b/.github/workflows/translate-strings.yml
@@ -23,7 +23,7 @@ jobs:
sudo apt-get update -qq
sudo apt-get install -qq --no-install-recommends gettext
- name: Install uv
- uses: astral-sh/setup-uv@v6
+ uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install backend python dependencies
@@ -38,7 +38,7 @@ jobs:
with:
version: 10
- name: Use Node.js 20
- uses: actions/setup-node@v5
+ uses: actions/setup-node@v6
with:
node-version: 20.x
cache: 'pnpm'
@@ -61,7 +61,7 @@ jobs:
cd src-ui
pnpm run ng extract-i18n
- name: Commit changes
- uses: stefanzweifel/git-auto-commit-action@v6
+ uses: stefanzweifel/git-auto-commit-action@v7
with:
file_pattern: 'src-ui/messages.xlf src/locale/en_US/LC_MESSAGES/django.po'
commit_message: "Auto translate strings"
From 56493d6640deae46b1aed3b4e01a1f6fce8bc2b4 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 17 Nov 2025 23:52:47 +0000
Subject: [PATCH 13/13] Chore(deps): Bump django-auditlog from 3.2.1 to 3.3.0
(#11021)
Bumps [django-auditlog](https://github.com/jazzband/django-auditlog) from 3.2.1 to 3.3.0.
- [Release notes](https://github.com/jazzband/django-auditlog/releases)
- [Changelog](https://github.com/jazzband/django-auditlog/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jazzband/django-auditlog/compare/v3.2.1...v3.3.0)
---
updated-dependencies:
- dependency-name: django-auditlog
dependency-version: 3.3.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
pyproject.toml | 2 +-
uv.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 84da482ae..afd76c63c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -27,7 +27,7 @@ dependencies = [
# Only patch versions are guaranteed to not introduce breaking changes.
"django~=5.2.5",
"django-allauth[mfa,socialaccount]~=65.12.1",
- "django-auditlog~=3.2.1",
+ "django-auditlog~=3.3.0",
"django-cachalot~=2.8.0",
"django-celery-results~=2.6.0",
"django-compression-middleware~=0.5.0",
diff --git a/uv.lock b/uv.lock
index d26f5cc60..355aeec57 100644
--- a/uv.lock
+++ b/uv.lock
@@ -710,15 +710,15 @@ socialaccount = [
[[package]]
name = "django-auditlog"
-version = "3.2.1"
+version = "3.3.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "python-dateutil", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/e1/46/9da1d94493832fa18d2f6324a76d387fa232001593866987a96047709f4e/django_auditlog-3.2.1.tar.gz", hash = "sha256:63a4c9f7793e94eed804bc31a04d9b0b58244b1d280e2ed273c8b406bff1f779", size = 72926, upload-time = "2025-07-03T20:08:17.734Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/37/d8/ddd1c653ffb7ed1984596420982e32a0b163a0be316721a801a54dcbf016/django_auditlog-3.3.0.tar.gz", hash = "sha256:01331a0e7bb1a8ff7573311b486c88f3d0c431c388f5a1e4a9b6b26911dd79b8", size = 85941, upload-time = "2025-10-02T17:16:27.591Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/a7/06/67296d050a72dcd76f57f220df621cb27e5b9282ba7ad0f5f74870dce241/django_auditlog-3.2.1-py3-none-any.whl", hash = "sha256:99603ca9d015f7e9b062b1c34f3e0826a3ce6ae6e5950c81bb7e663f7802a899", size = 38330, upload-time = "2025-07-03T20:07:51.735Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/bc/6e1b503d1755ab09cff6480cb088def073f1303165ab59b1a09247a2e756/django_auditlog-3.3.0-py3-none-any.whl", hash = "sha256:ab0f0f556a7107ac01c8fa87137bdfbb2b6f0debf70f7753169d9a40673d2636", size = 39676, upload-time = "2025-10-02T17:15:42.922Z" },
]
[[package]]
@@ -2263,7 +2263,7 @@ requires-dist = [
{ name = "dateparser", specifier = "~=1.2" },
{ name = "django", specifier = "~=5.2.5" },
{ name = "django-allauth", extras = ["mfa", "socialaccount"], specifier = "~=65.12.1" },
- { name = "django-auditlog", specifier = "~=3.2.1" },
+ { name = "django-auditlog", specifier = "~=3.3.0" },
{ name = "django-cachalot", specifier = "~=2.8.0" },
{ name = "django-celery-results", specifier = "~=2.6.0" },
{ name = "django-compression-middleware", specifier = "~=0.5.0" },