Skip to content

Commit abdae36

Browse files
fsecada01claude
andcommitted
chore: CI workflow, CHANGELOG, explicit wheel includes — v0.1.0 complete
- Add .github/workflows/ci.yml with matrix for Python 3.11/3.12/3.13 - Replace [Unreleased] with [0.1.0] release notes and Technical Notes - Add explicit [tool.hatch.build] include for templates + static in pyproject.toml - Fix 16 ruff lint/format issues across tests (E402 noqa, F401 unused imports, E501 long line, E741 ambiguous var, I001 unsorted imports, UP035 typing import, ruff format on 21 files) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1b543f0 commit abdae36

28 files changed

Lines changed: 381 additions & 165 deletions

.github/workflows/ci.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master, main]
6+
pull_request:
7+
branches: [master, main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.11", "3.12", "3.13"]
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Install uv
20+
uses: astral-sh/setup-uv@v3
21+
22+
- name: Set up Python ${{ matrix.python-version }}
23+
run: uv python install ${{ matrix.python-version }}
24+
25+
- name: Install dependencies
26+
run: uv pip install -e ".[dev]"
27+
28+
- name: Install Playwright browsers
29+
run: playwright install chromium --with-deps
30+
31+
- name: Lint
32+
run: ruff check src tests
33+
34+
- name: Format check
35+
run: ruff format --check src tests
36+
37+
- name: Unit tests
38+
run: pytest tests/unit/ -q --tb=short
39+
40+
- name: Integration tests
41+
run: pytest tests/integration/ -q --tb=short
42+
43+
- name: E2E tests
44+
run: pytest tests/e2e/ -q --tb=short --browser chromium

CHANGELOG.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
# Changelog
22

3-
## [Unreleased]
3+
## [0.1.0] — 2026-04-25
44

55
### Added
6-
- Initial package scaffold
6+
- Initial release: Bulma theme (Jinja2/JinjaX + django-cotton)
7+
- 14 components: FormField, Select, Textarea, CheckboxGroup, Modal, Notification,
8+
Progress, Card, Table, Pagination, Panel, Navbar, Breadcrumb, Tabs
9+
- Django AppConfig with auto-registration of COTTON_DIRS
10+
- FastAPI `install_cf_ui()` with JinjaX `add_folder(prefix="Cf")` registration
11+
- Litestar `install_cf_ui()` with Jinja2 template directory injection
12+
- CDN asset tags: `{% cf_ui_head %}` / `{% cf_ui_body %}` (Django + Jinja2 macros)
13+
- `cf_ui_alpine.js`: named Alpine components (cfModal, cfNavbar, cfPanel, cfTabs)
14+
and `$store.cf` global store (notify, modal.open/close via custom events)
15+
- Three-tier test suite: unit (93 tests), integration (8 tests), E2E Playwright (17 tests, js_on + js_off)
16+
- Stubs for Bootstrap, Foundation, Fomantic UI, DaisyUI themes
17+
18+
### Technical Notes
19+
- django-cotton 2.x: uses `<c-vars>` (not `<c-props>`) for variable declarations
20+
- JinjaX 0.41+: uses `add_folder()` (not `add_path()`), `class` is reserved — use `extra_class`
21+
- Alpine modal control uses `cf-modal-open`/`cf-modal-close` custom events (not `_x_dataStack`)

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ build-backend = "hatchling.build"
5858
[tool.hatch.build.targets.wheel]
5959
packages = ["src/cf_ui"]
6060

61+
[tool.hatch.build]
62+
include = [
63+
"src/cf_ui/**/*.py",
64+
"src/cf_ui/templates/**",
65+
"src/cf_ui/static/**",
66+
]
67+
6168
[tool.pytest.ini_options]
6269
testpaths = ["tests"]
6370
pythonpath = ["src"]

tests/e2e/_django_e2e_server.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Run as a subprocess so it gets its own Python process and Django configuration,
55
isolated from the pytest process's Django settings.
66
"""
7+
78
import os
89
import sys
910
from pathlib import Path
@@ -22,12 +23,13 @@
2223
# Configure Django with cotton-enabled settings
2324
os.environ["DJANGO_SETTINGS_MODULE"] = "tests.e2e._e2e_django_settings"
2425

25-
import django
26+
import django # noqa: E402
2627

2728
django.setup()
2829

29-
from django.core.handlers.wsgi import WSGIHandler
30-
from wsgiref.simple_server import make_server
30+
from wsgiref.simple_server import make_server # noqa: E402
31+
32+
from django.core.handlers.wsgi import WSGIHandler # noqa: E402
3133

3234
httpd = make_server(HOST, PORT, WSGIHandler())
3335
httpd.serve_forever()

tests/e2e/_e2e_django_settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
It MUST NOT be imported by the main pytest process to avoid polluting
99
the shared Django settings used by unit and integration tests.
1010
"""
11+
1112
from pathlib import Path
1213

1314
from cf_ui import JINJA_TEMPLATES_DIR

tests/e2e/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
import sys
33
import threading
44
import time
5+
from collections.abc import Generator
56
from pathlib import Path
6-
from typing import Generator
77

88
import pytest
99
import uvicorn

tests/e2e/test_bulma_cotton.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import re
22

3-
import pytest
43
from playwright.sync_api import expect
54

65

tests/integration/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
need it. The session-scoped fixture below ensures ROOT_URLCONF is set for all
1818
integration tests regardless of which conftest configured Django first.
1919
"""
20+
2021
import os
2122

2223
import django

tests/integration/cotton_app/settings.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@
1111
"cf_ui.django.CfUiConfig",
1212
]
1313
DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}
14-
TEMPLATES = [{
15-
"BACKEND": "django.template.backends.django.DjangoTemplates",
16-
"DIRS": [BASE_DIR / "templates"],
17-
"APP_DIRS": True,
18-
"OPTIONS": {
19-
"context_processors": [],
20-
"libraries": {"cf_ui": "cf_ui.templatetags.cf_ui"},
21-
},
22-
}]
14+
TEMPLATES = [
15+
{
16+
"BACKEND": "django.template.backends.django.DjangoTemplates",
17+
"DIRS": [BASE_DIR / "templates"],
18+
"APP_DIRS": True,
19+
"OPTIONS": {
20+
"context_processors": [],
21+
"libraries": {"cf_ui": "cf_ui.templatetags.cf_ui"},
22+
},
23+
}
24+
]
2325
CF_UI_THEME = "bulma"
2426
ROOT_URLCONF = "tests.integration.cotton_app.urls"
2527
STATIC_URL = "/static/"

tests/integration/cotton_app/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.urls import path
2+
23
from tests.integration.cotton_app import views
34

45
urlpatterns = [

0 commit comments

Comments
 (0)