Skip to content

Development

FastSMTP is a uv workspace with two packages: fastsmtp (server) and fastsmtp-cli (remote client).

# Install dev dependencies for both workspace packages
uv sync --all-packages --dev

# Run tests
uv run pytest

# Run tests with coverage
uv run pytest --cov=fastsmtp --cov-report=term-missing

# Lint and format
uv run ruff check .
uv run ruff format .

Migration tests

Most tests build their schema straight from the models with Base.metadata.create_all, so the Alembic chain never runs. fastsmtp/tests/test_migrations.py covers it separately: it applies the chain to a throwaway database, rolls it back to base and re-applies it, then diffs the result against Base.metadata and fails on any difference. A model change merged without its migration fails there instead of on deploy.

The chain is driven through fastsmtp db upgrade|downgrade in a child process, which is the only supported way to run it - the migrations ship inside the package and there is no alembic.ini for the Alembic CLI to read. The tests therefore exercise the documented upgrade path rather than a private one.

Those tests are marked migrations and always run in CI. Each one needs its own database and its own child process, so deselect them when that overhead is not worth it locally:

uv run pytest -m "not migrations"

Documentation

This site is built with Zensical. To work on it locally:

# Install docs dependencies
uv sync --group docs

# Live-preview at http://localhost:8000
uv run zensical serve

# Build the static site into site/
uv run zensical build --clean

The site is deployed to GitHub Pages automatically on every push to main by the Documentation workflow.

Releasing

Cutting a release (version bump, PR labels, publishing, schema checks, and image verification) is covered in Releasing.

License

AGPL-3.0 - see the LICENSE file for details.