Skip to content

Commit 794d07d

Browse files
committed
feat(ci): add Django 6 support and multi-package testing matrix
1 parent 6bbde1f commit 794d07d

File tree

10 files changed

+132
-36
lines changed

10 files changed

+132
-36
lines changed

.github/workflows/test.yml

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,21 @@ jobs:
2020
enable-cache: true
2121
python-version: "3.11"
2222
- name: Install tox
23-
run: uv tool install tox --with tox-uv --with git+https://github.com/huynguyengl99/tox-gh.git
23+
run: uv tool install tox --with tox-uv --with tox-gh
2424
- name: Run lint
2525
run: tox -e lint
2626

27-
test:
27+
test-django:
28+
name: test py${{ matrix.py }}-django${{ matrix.django }}
2829
runs-on: ubuntu-latest
2930
strategy:
3031
matrix:
31-
python-version: ["3.11", "3.12", "3.13"]
32+
py: ["3.11", "3.12", "3.13"]
33+
django: ["50", "51", "60"]
34+
exclude:
35+
# Django 6.0 requires Python 3.12+
36+
- py: "3.11"
37+
django: "60"
3238
fail-fast: false
3339
services:
3440
postgres:
@@ -60,18 +66,69 @@ jobs:
6066
POSTGRES_HOST: localhost
6167
POSTGRES_PORT: 5432
6268
REDIS_URL: redis://localhost:6379
63-
TOX_GH_MAJOR_MINOR: ${{ matrix.python-version }}
69+
TOX_GH_MAJOR_MINOR: ${{ matrix.py }}
6470
steps:
6571
- uses: actions/checkout@v4
6672
- name: Install the latest version of uv
6773
uses: astral-sh/setup-uv@v5
6874
with:
6975
enable-cache: true
70-
python-version: ${{ matrix.python-version }}
76+
python-version: ${{ matrix.py }}
7177
- name: Install tox
72-
run: uv tool install tox --with tox-uv --with git+https://github.com/huynguyengl99/tox-gh.git
78+
run: uv tool install tox --with tox-uv --with tox-gh
7379
- name: Run tests
74-
run: tox
80+
run: tox -e py$(echo "${{ matrix.py }}" | tr -d '.')-django${{ matrix.django }}
81+
82+
test-other:
83+
name: test py${{ matrix.py }}-${{ matrix.package }}
84+
runs-on: ubuntu-latest
85+
strategy:
86+
matrix:
87+
py: ["3.11", "3.12", "3.13"]
88+
package: ["fastapi", "core"]
89+
fail-fast: false
90+
services:
91+
postgres:
92+
image: postgres
93+
env:
94+
POSTGRES_PASSWORD: chanx_test_pass
95+
POSTGRES_DB: chanx_test_db
96+
POSTGRES_USER: chanx_test_user
97+
options: >-
98+
--health-cmd pg_isready
99+
--health-interval 10s
100+
--health-timeout 5s
101+
--health-retries 5
102+
ports:
103+
- 5432:5432
104+
redis:
105+
image: redis
106+
options: >-
107+
--health-cmd "redis-cli ping"
108+
--health-interval 10s
109+
--health-timeout 5s
110+
--health-retries 5
111+
ports:
112+
- 6379:6379
113+
env:
114+
POSTGRES_DB: chanx_test_db
115+
POSTGRES_USER: chanx_test_user
116+
POSTGRES_PASSWORD: chanx_test_pass
117+
POSTGRES_HOST: localhost
118+
POSTGRES_PORT: 5432
119+
REDIS_URL: redis://localhost:6379
120+
TOX_GH_MAJOR_MINOR: ${{ matrix.py }}
121+
steps:
122+
- uses: actions/checkout@v4
123+
- name: Install the latest version of uv
124+
uses: astral-sh/setup-uv@v5
125+
with:
126+
enable-cache: true
127+
python-version: ${{ matrix.py }}
128+
- name: Install tox
129+
run: uv tool install tox --with tox-uv --with tox-gh
130+
- name: Run tests
131+
run: tox -e py$(echo "${{ matrix.py }}" | tr -d '.')-${{ matrix.package }}
75132

76133
coverage:
77134
runs-on: ubuntu-latest
@@ -113,7 +170,7 @@ jobs:
113170
enable-cache: true
114171
python-version: "3.11"
115172
- name: Install tox
116-
run: uv tool install tox --with tox-uv --with git+https://github.com/huynguyengl99/tox-gh.git
173+
run: uv tool install tox --with tox-uv --with tox-gh
117174
- name: Run coverage
118175
run: tox -e coverage
119176
- name: Upload coverage reports to Codecov

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dev = [
1313
"freezegun>=1.5.1,<2",
1414
"interrogate>=1.7.0",
1515
"mock>=5.2.0,<6",
16+
"pytest-asyncio>=1.2.0",
1617
"pytest-cov>=6.1.1,<7",
1718
"pytest-mock>=3.14.0,<4",
1819
"pytest-rerunfailures>=16.0.1",
@@ -51,7 +52,7 @@ dev-django = [
5152
dev-fastapi = [
5253
"arq>=0.26.3",
5354
"fast-channels[redis]>=1.0.2",
54-
"pytest-asyncio>=1.2.0",
55+
"httpx>=0.27.0,<1",
5556
"pytest-env>=1.1.5",
5657
{include-group = "dev"}
5758
]
@@ -110,7 +111,7 @@ version = "2.4.1"
110111

111112
[project.optional-dependencies]
112113
channels = [
113-
"Django>=5,<6",
114+
"Django>=5",
114115
"channels>=4,<5",
115116
"chanx[core]",
116117
"djangorestframework>=3,<4"

sandbox_django/asyncapi/tests/test_asyncapi_schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def test_json_schema(self) -> None:
2121

2222
def test_yaml_schema(self) -> None:
2323
response = self.client.get(reverse("asyncapi_schema") + "?format=yaml")
24-
data = response.text
24+
data = response.content.decode()
2525
with open(results_dir / "asyncapi_schema_res.yaml", "w") as f:
2626
f.write(data)
2727

sandbox_django/config/settings/base.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
from pathlib import Path
1313
from typing import Any
1414

15+
import django
16+
1517
import django_stubs_ext
1618
import structlog
1719
from environs import env
@@ -141,18 +143,19 @@
141143
# =========================================================================
142144
# DATABASE CONFIGURATION
143145
# =========================================================================
146+
_db_options = {}
147+
if django.VERSION >= (5, 1):
148+
_db_options["pool"] = True
144149

145-
DATABASES = {
150+
DATABASES: dict[str, Any] = {
146151
"default": {
147152
"ENGINE": "django.db.backends.postgresql",
148153
"NAME": env.str("POSTGRES_DB", ""),
149154
"USER": env.str("POSTGRES_USER", ""),
150155
"PASSWORD": env.str("POSTGRES_PASSWORD", ""),
151156
"HOST": env.str("POSTGRES_HOST", "localhost"),
152157
"PORT": env.int("POSTGRES_PORT", 5432),
153-
"OPTIONS": {
154-
"pool": True,
155-
},
158+
"OPTIONS": _db_options,
156159
}
157160
}
158161

scripts/test_all.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ if [ "$RUN_COVERAGE" = true ]; then
4040

4141
pytest --cov=chanx --cov-report= --cov-append tests/ext/channels
4242

43+
pytest --cov=chanx --cov-report= --cov-append tests/ext/fast_channels
44+
4345
pytest --cov=chanx --cov-report= --cov-append tests/client_generation/
4446

4547
pytest --cov=chanx --cov-append --cov-report=xml --cov-report=term-missing tests/core
@@ -53,6 +55,8 @@ else
5355

5456
pytest tests/ext/channels
5557

58+
pytest tests/ext/fast_channels
59+
5660
pytest tests/client_generation/
5761

5862
pytest tests/core

tests/ext/channels/conftest.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pathlib import Path
33
from typing import Any
44

5+
import django
56
from django.conf import settings as django_settings
67

78
import pytest
@@ -18,6 +19,10 @@
1819

1920

2021
def pytest_configure() -> None:
22+
_db_options = {}
23+
if django.VERSION >= (5, 1):
24+
_db_options["pool"] = True
25+
2126
django_settings.configure(
2227
DATABASES={
2328
"default": {
@@ -27,9 +32,7 @@ def pytest_configure() -> None:
2732
"PASSWORD": env.str("POSTGRES_PASSWORD", ""),
2833
"HOST": env.str("POSTGRES_HOST", "localhost"),
2934
"PORT": env.int("POSTGRES_PORT", 5432),
30-
"OPTIONS": {
31-
"pool": True,
32-
},
35+
"OPTIONS": _db_options,
3336
}
3437
},
3538
INSTALLED_APPS=[

tests/ext/fast_channels/test_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class TestBuildDefaultConfigFromApp:
1414
def setup_method(self) -> None:
1515
"""Set up test fixtures."""
1616
self.mock_request = Mock(spec=Request)
17-
self.mock_request.url.hostname = "localhost"
17+
self.mock_request.url.netloc = "localhost"
1818
self.mock_request.url.scheme = "http"
1919

2020
def test_build_config_with_basic_app(self) -> None:
@@ -91,7 +91,7 @@ def test_build_config_empty_attributes(self) -> None:
9191

9292
def test_build_config_different_hostname(self) -> None:
9393
"""Test building config with different hostname."""
94-
self.mock_request.url.hostname = "api.example.com"
94+
self.mock_request.url.netloc = "api.example.com"
9595
mock_app = Mock()
9696
mock_app.title = "External API"
9797

tests/ext/fast_channels/test_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class TestGenerateAsyncAPISchema:
2525
def setup_method(self) -> None:
2626
"""Set up test fixtures."""
2727
self.mock_request = Mock(spec=Request)
28-
self.mock_request.url.hostname = "localhost"
28+
self.mock_request.url.netloc = "localhost"
2929
self.mock_request.url.scheme = "http"
3030

3131
async def websocket_endpoint(websocket: WebSocket) -> None:

tox.ini

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
[tox]
2-
env_list = py311, py312, py313, lint, coverage
2+
env_list =
3+
py{311,312,313}-django{50,51}
4+
py{312,313}-django60
5+
py{311,312,313}-fastapi
6+
py{311,312,313}-core
7+
lint
8+
coverage
39
isolated_build = True
410

511
[gh]
612
python =
7-
3.11 = py311
8-
3.12 = py312
9-
3.13 = py313
13+
3.11 = py311-django{50,51}, py311-fastapi, py311-core
14+
3.12 = py312-django{50,51,60}, py312-fastapi, py312-core
15+
3.13 = py313-django{50,51,60}, py313-fastapi, py313-core
1016

1117
[testenv]
1218
pass_env =
@@ -19,26 +25,40 @@ allowlist_externals =
1925
python
2026
scripts/test_all.sh
2127
scripts/mypy.sh
22-
dependency_groups = dev-django, dev-fastapi, test
23-
extras = channels, fast_channels
2428
package = editable
2529
runner = uv-venv-lock-runner
2630
setenv =
2731
PYTHONPATH = {toxinidir}
28-
commands =
29-
scripts/test_all.sh
3032

31-
[testenv:py311]
32-
basepython = python3.11
33+
[testenv:py{311,312,313}-django{50,51,60}]
34+
runner = uv-venv-runner
35+
deps =
36+
django50: Django>=5.0,<5.1
37+
django51: Django>=5.1,<5.2
38+
django60: Django>=6.0,<6.1
39+
dependency_groups = dev-django, test
40+
extras = channels
41+
commands =
42+
pytest sandbox_django
43+
pytest tests/ext/channels
3344

34-
[testenv:py312]
35-
basepython = python3.12
45+
[testenv:py{311,312,313}-fastapi]
46+
dependency_groups = dev-fastapi, test
47+
extras = fast_channels
48+
commands =
49+
pytest sandbox_fastapi
50+
pytest tests/ext/fast_channels
3651

37-
[testenv:py313]
38-
basepython = python3.13
52+
[testenv:py{311,312,313}-core]
53+
dependency_groups = dev, test
54+
extras = cli, core, channels
55+
commands =
56+
pytest tests/core
57+
pytest tests/client_generation
3958

4059
[testenv:lint]
4160
dependency_groups = dev, dev-django, dev-fastapi, lint
61+
extras = channels, fast_channels
4262
commands =
4363
black --check chanx
4464
ruff check chanx
@@ -49,5 +69,7 @@ commands =
4969
pyright --venvpath {envdir}
5070

5171
[testenv:coverage]
72+
dependency_groups = dev-django, dev-fastapi, test
73+
extras = channels, fast_channels
5274
commands =
5375
scripts/test_all.sh --cov

uv.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)