Skip to content

Commit 28fc467

Browse files
authored
Adding unit tests and improving the github actions workflows (#21)
* feat(ci): add GitHub Actions workflows for CI, production, and test PyPI publishing with uv integration and update .gitignore and docs for development environment * ci: add matrix testing for multiple Python and Django versions and introduce Makefile for unified commands and improved CI workflows * ci: remove branch filter from push event to trigger CI on all branches
1 parent 6ec8441 commit 28fc467

22 files changed

Lines changed: 738 additions & 91 deletions

.github/workflows/ci.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
7+
jobs:
8+
test:
9+
name: Test (Python ${{ matrix.python-version }}, Django ${{ matrix.django-name }})
10+
runs-on: ubuntu-latest
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
include:
15+
- python-version: "3.11"
16+
django-name: "4.2"
17+
django-constraint: "django>=4.2,<4.3"
18+
- python-version: "3.11"
19+
django-name: "5.0"
20+
django-constraint: "django>=5.0,<5.1"
21+
- python-version: "3.11"
22+
django-name: "5.1"
23+
django-constraint: "django>=5.1,<5.2"
24+
- python-version: "3.11"
25+
django-name: "5.2"
26+
django-constraint: "django>=5.2,<5.3"
27+
- python-version: "3.12"
28+
django-name: "4.2"
29+
django-constraint: "django>=4.2,<4.3"
30+
- python-version: "3.12"
31+
django-name: "5.0"
32+
django-constraint: "django>=5.0,<5.1"
33+
- python-version: "3.12"
34+
django-name: "5.1"
35+
django-constraint: "django>=5.1,<5.2"
36+
- python-version: "3.12"
37+
django-name: "5.2"
38+
django-constraint: "django>=5.2,<5.3"
39+
- python-version: "3.13"
40+
django-name: "5.1"
41+
django-constraint: "django>=5.1,<5.2"
42+
- python-version: "3.13"
43+
django-name: "5.2"
44+
django-constraint: "django>=5.2,<5.3"
45+
- python-version: "3.14"
46+
django-name: "5.2"
47+
django-constraint: "django>=5.2,<5.3"
48+
steps:
49+
- uses: actions/checkout@v4
50+
- uses: actions/setup-python@v5
51+
with:
52+
python-version: "${{ matrix.python-version }}"
53+
- uses: astral-sh/setup-uv@v5
54+
- name: Run tests
55+
run: make test-django PYTHON=${{ matrix.python-version }} DJANGO_CONSTRAINT='${{ matrix.django-constraint }}'
56+
quality:
57+
name: Quality
58+
runs-on: ubuntu-latest
59+
steps:
60+
- uses: actions/checkout@v4
61+
- uses: actions/setup-python@v5
62+
with:
63+
python-version: "3.13"
64+
- uses: astral-sh/setup-uv@v5
65+
- name: Sync dependencies
66+
run: make sync
67+
- name: Run lint
68+
run: make lint
69+
- name: Build package
70+
run: make build

.github/workflows/production.yml

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,17 @@ on:
77
jobs:
88
release:
99
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
1012
steps:
11-
- uses: actions/checkout@v1
12-
- name: Set up Python
13-
uses: actions/setup-python@v1
14-
with:
15-
python-version: '3.x'
16-
- name: Install dependencies
17-
run: |
18-
python -m pip install --upgrade pip
19-
pip install setuptools wheel twine
20-
- name: Build and publish
21-
env:
22-
TWINE_USERNAME: __token__
23-
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
24-
run: |
25-
python setup.py sdist bdist_wheel
26-
twine upload dist/*
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-python@v5
15+
with:
16+
python-version: "3.13"
17+
- uses: astral-sh/setup-uv@v5
18+
- name: Build package
19+
run: uv build
20+
- name: Publish package
21+
env:
22+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
23+
run: uv publish --trusted-publishing never

.github/workflows/publish-to-test-pypi.yml

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,17 @@ on: push
66
jobs:
77
release:
88
runs-on: ubuntu-latest
9+
permissions:
10+
contents: read
911
steps:
10-
- uses: actions/checkout@v1
11-
- name: Set up Python
12-
uses: actions/setup-python@v1
13-
with:
14-
python-version: '3.x'
15-
- name: Install dependencies
16-
run: |
17-
python -m pip install --upgrade pip
18-
pip install setuptools wheel twine
19-
- name: Build and publish
20-
env:
21-
TWINE_USERNAME: __token__
22-
TWINE_PASSWORD: ${{ secrets.PYPI_TEST_TOKEN }}
23-
TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/
24-
run: |
25-
python setup.py sdist bdist_wheel
26-
twine upload dist/*
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-python@v5
14+
with:
15+
python-version: "3.13"
16+
- uses: astral-sh/setup-uv@v5
17+
- name: Build package
18+
run: uv build
19+
- name: Publish package
20+
env:
21+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TEST_TOKEN }}
22+
run: uv publish --publish-url https://test.pypi.org/legacy/ --check-url https://test.pypi.org/simple/ --trusted-publishing never

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ target/
8181
profile_default/
8282
ipython_config.py
8383

84-
# pyenv
85-
.python-version
8684

8785
# pipenv
8886
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
@@ -104,6 +102,7 @@ celerybeat.pid
104102
# Environments
105103
.env
106104
.venv
105+
.uv-cache/
107106
env/
108107
venv/
109108
ENV/

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

CONTRIBUTING.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Contributing
2+
3+
## Prerequisites
4+
5+
- `uv` installed locally
6+
- Python `3.13` available, as declared in `.python-version`
7+
8+
## Bootstrap
9+
10+
```bash
11+
make sync
12+
```
13+
14+
If your environment cannot write to the default uv cache location, prefix the commands with `UV_CACHE_DIR=.uv-cache`.
15+
16+
If you change dependencies in `pyproject.toml`, regenerate the lockfile with:
17+
18+
```bash
19+
make lock
20+
make sync
21+
```
22+
23+
## Daily commands
24+
25+
Run the unit tests:
26+
27+
```bash
28+
make test
29+
```
30+
31+
Run lint checks:
32+
33+
```bash
34+
make lint
35+
```
36+
37+
Build the package:
38+
39+
```bash
40+
make build
41+
```
42+
43+
Test against a specific Django branch:
44+
45+
```bash
46+
make test-django DJANGO_CONSTRAINT="django>=5.1,<5.2" PYTHON=3.13
47+
```
48+
49+
## Project layout
50+
51+
- `django_dbml/management/commands/dbml.py`: command that inspects Django model metadata and renders DBML
52+
- `django_dbml/utils.py`: helper utilities used by the generator
53+
- `tests/testapp/`: isolated Django app used to exercise the extension
54+
- `tests/test_command.py`: command-level tests
55+
- `tests/test_utils.py`: unit tests for helper behavior
56+
57+
## Release flow
58+
59+
The repository publishes from GitHub Actions using `uv build` and `uv publish`. Before releasing, run:
60+
61+
```bash
62+
make test
63+
make lint
64+
make build
65+
```
66+
67+
The detailed development guide lives in `docs/development.md`.

Makefile

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
SHELL := /bin/sh
2+
3+
UV ?= uv
4+
UV_CACHE_DIR ?= .uv-cache
5+
PYTHON ?=
6+
DJANGO_CONSTRAINT ?=
7+
8+
UV_ENV = UV_CACHE_DIR=$(UV_CACHE_DIR)
9+
10+
.PHONY: help sync lock test test-django lint build check ci
11+
12+
help:
13+
@printf '%s\n' \
14+
'make sync - sync the development environment from uv.lock' \
15+
'make lock - refresh uv.lock after dependency changes' \
16+
'make test - run the unit test suite with the locked environment' \
17+
'make test-django - run tests against a specific Django constraint' \
18+
' example: make test-django DJANGO_CONSTRAINT="django>=5.1,<5.2" PYTHON=3.13' \
19+
'make lint - run Ruff checks' \
20+
'make build - build wheel and sdist artifacts' \
21+
'make check - run lint and tests' \
22+
'make ci - run lint, tests, and build locally'
23+
24+
sync:
25+
$(UV_ENV) $(UV) sync --locked
26+
27+
lock:
28+
$(UV_ENV) $(UV) lock
29+
30+
test:
31+
$(UV_ENV) $(UV) run --locked pytest
32+
33+
test-django:
34+
@if [ -z "$(DJANGO_CONSTRAINT)" ]; then \
35+
printf '%s\n' 'DJANGO_CONSTRAINT is required. Example: make test-django DJANGO_CONSTRAINT="django>=5.1,<5.2" [PYTHON=3.13]'; \
36+
exit 2; \
37+
fi
38+
$(UV_ENV) $(UV) run --locked --isolated $(if $(PYTHON),--python $(PYTHON),) --with "$(DJANGO_CONSTRAINT)" pytest
39+
40+
lint:
41+
$(UV_ENV) $(UV) run --locked ruff check .
42+
43+
build:
44+
$(UV_ENV) $(UV) build
45+
46+
check: sync lint test
47+
48+
ci: sync lint test build

README.md

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,46 @@
22

33
This app can generate a DBML output for all installed models.
44

5-
## How to install and use?
5+
## Installation
66

7-
#### 1. Install the django-dbml package
8-
9-
```
7+
```bash
108
pip install django-dbml
119
```
1210

13-
#### 2. Put django_dbml on your django settings
11+
## Usage
12+
13+
Add `django_dbml` to `INSTALLED_APPS`:
1414

1515
```python
16-
'...',
17-
'django_dbml',
18-
'...',
16+
INSTALLED_APPS = [
17+
# ...
18+
"django_dbml",
19+
]
1920
```
2021

21-
#### 3. Run the command to generate a DBML schema based on your Django models
22+
Generate DBML from all installed models:
2223

2324
```bash
24-
$ python manage.py dbml
25+
python manage.py dbml
2526
```
2627

27-
To generate DBML for a subset of your models, specify one or more Django app
28-
names or models by app_label or app_label.ModelName. Related tables will still
28+
To generate DBML for a subset of your models, specify one or more Django app
29+
names or models by `app_label` or `app_label.ModelName`. Related tables will still
2930
be included in the DBML.
3031

32+
## Development
33+
34+
This repository is now managed with `uv`.
35+
36+
```bash
37+
make sync
38+
make test
39+
make lint
40+
make build
41+
```
42+
43+
Development instructions live in [CONTRIBUTING.md](CONTRIBUTING.md) and [docs/development.md](docs/development.md).
44+
3145
# Thanks
3246

3347
The initial code was based on https://github.com/hamedsj/DbmlForDjango project

0 commit comments

Comments
 (0)