diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..978d8488
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,15 @@
+# These are supported funding model platforms
+
+github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
+polar: # Replace with a single Polar username
+buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
+thanks_dev: # Replace with a single thanks.dev username
+custom: ["https://openwisp.org/sponsorship/"]
diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml
new file mode 100644
index 00000000..0281a31c
--- /dev/null
+++ b/.github/workflows/pypi.yml
@@ -0,0 +1,32 @@
+name: Publish Python Package to Pypi.org
+
+on:
+ release:
+ types: [published]
+
+permissions:
+ id-token: write
+
+jobs:
+ pypi-publish:
+ name: Release Python Package on Pypi.org
+ runs-on: ubuntu-latest
+ environment:
+ name: pypi
+ url: https://pypi.org/p/openwisp-ipam
+ permissions:
+ id-token: write
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.10'
+ - name: Install dependencies
+ run: |
+ pip install -U pip
+ pip install build
+ - name: Build package
+ run: python -m build
+ - name: Publish package distributions to PyPI
+ uses: pypa/gh-action-pypi-publish@v1.11.0
diff --git a/docs/user/notification-cache.rst b/docs/developer/cache.rst
similarity index 97%
rename from docs/user/notification-cache.rst
rename to docs/developer/cache.rst
index 83ffe920..0fc0ef30 100644
--- a/docs/user/notification-cache.rst
+++ b/docs/developer/cache.rst
@@ -4,7 +4,7 @@ Notification Cache
In a typical OpenWISP installation, ``actor``, ``action_object`` and
``target`` objects are same for a number of notifications. To optimize
database queries, these objects are cached using `Django's cache framework
-`_. The cached values
+`_. The cached values
are updated automatically to reflect actual data from database. You can
control the duration of caching these objects using
:ref:`OPENWISP_NOTIFICATIONS_CACHE_TIMEOUT setting
diff --git a/docs/developer/extending.rst b/docs/developer/extending.rst
index a91c54d9..b48d332d 100644
--- a/docs/developer/extending.rst
+++ b/docs/developer/extending.rst
@@ -148,9 +148,11 @@ to the `models of the sample app in the test project
You can add fields in a similar way in your ``models.py`` file.
-**Note**: For doubts regarding how to use, extend or develop models please
-refer to the `"Models" section in the django documentation
-`_.
+.. note::
+
+ If you have questions about using, extending, or developing models,
+ refer to the `"Models" section of the Django documentation
+ `_.
8. Add swapper configurations
-----------------------------
@@ -191,10 +193,12 @@ Refer to the `admin.py file of the sample app
To introduce changes to the admin, you can do it in two main ways which
are described below.
-**Note**: For more information regarding how the django admin works, or
-how it can be customized, please refer to `"The django admin site" section
-in the django documentation
-`_.
+.. note::
+
+ For more information regarding how the django admin works, or how it
+ can be customized, please refer to `"The django admin site" section in
+ the django documentation
+ `_.
1. Monkey patching
~~~~~~~~~~~~~~~~~~
@@ -320,9 +324,11 @@ See the `tests of the sample_notifications
`_
to find out how to do this.
-**Note**: Some tests will fail if ``templatetags`` and ``admin/base.html``
-are not configured properly. See preceding sections to configure them
-properly.
+.. note::
+
+ Some tests will fail if ``templatetags`` and ``admin/base.html`` are
+ not configured properly. See preceding sections to configure them
+ properly.
Other base classes that can be inherited and extended
-----------------------------------------------------
diff --git a/docs/developer/index.rst b/docs/developer/index.rst
index 99915fc9..88776a44 100644
--- a/docs/developer/index.rst
+++ b/docs/developer/index.rst
@@ -8,9 +8,10 @@ Developer Docs
./installation.rst
./utils.rst
+ ./cache.rst
./extending.rst
Other useful resources:
- - :doc:`../user/rest-api`
- - :doc:`../user/settings`
+- :doc:`../user/rest-api`
+- :doc:`../user/settings`
diff --git a/docs/index.rst b/docs/index.rst
index db07b475..48bbef6a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -46,7 +46,6 @@ within the OpenWISP architecture.
./user/scheduled-deletion-of-notifications.rst
./user/rest-api.rst
./user/settings.rst
- ./user/notification-cache.rst
./user/management-commands.rst
.. toctree::
diff --git a/docs/user/settings.rst b/docs/user/settings.rst
index 1ad84bb1..08053c05 100644
--- a/docs/user/settings.rst
+++ b/docs/user/settings.rst
@@ -49,7 +49,7 @@ Configure Django's settings as follows:
CSRF_COOKIE_DOMAIN = "example.com"
Please refer to `Django's settings documentation
-`_ for more
+`_ for more
information on ``SESSION_COOKIE_DOMAIN`` and ``CSRF_COOKIE_DOMAIN``
settings.
diff --git a/requirements-test.txt b/requirements-test.txt
index 7c267db4..9cef3b7a 100644
--- a/requirements-test.txt
+++ b/requirements-test.txt
@@ -1,7 +1,7 @@
-openwisp-utils[qa,selenium] @ https://github.com/openwisp/openwisp-utils/tarball/master
+openwisp-utils[qa,selenium]~=1.1.0
django-cors-headers~=4.4.0
django-redis~=5.4.0
channels_redis~=4.2.0
-pytest-asyncio~=0.23.8
-pytest-django~=4.8.0
+pytest-asyncio~=0.24.0
+pytest-django~=4.9.0
freezegun~=1.5.1
diff --git a/requirements.txt b/requirements.txt
index 8e29af7f..51d89b3f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
django-notifications-hq~=1.8.3
channels~=3.0.2
openwisp-users @ https://github.com/openwisp/openwisp-users/tarball/master
-openwisp-utils[rest,celery] @ https://github.com/openwisp/openwisp-utils/tarball/master
-markdown~=3.6.0
+openwisp-utils[rest,celery]~=1.1.0
+markdown~=3.7.0
diff --git a/tests/openwisp2/settings.py b/tests/openwisp2/settings.py
index 373b33cd..89394685 100644
--- a/tests/openwisp2/settings.py
+++ b/tests/openwisp2/settings.py
@@ -66,6 +66,7 @@
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'allauth.account.middleware.AccountMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]