Move build system from setuptools to uv, wire uv into CI/CD
Convert both pyproject.toml files to the uv_build backend and turn the repo into a proper uv workspace (plotstyle moved to src layout, since uv_build requires the module in its own subdirectory). Dev tooling moves from an optional-dependencies extra to a dependency-group, and plotstyle's matplotlib dependency is now its own rather than a gallery "plotting" extra. Gitea Actions workflows and the Dockerfile now use astral-sh/setup-uv, uv sync, uv run, uv build, and uv publish throughout instead of pip, build, and twine. Also fixes .dockerignore, which was excluding uv.lock, deploy/, and README.md and would have broken even the previous Dockerfile's COPY of deploy/entrypoint.sh. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,39 +8,38 @@ A Python package that generates responsive static HTML galleries from scientific
|
||||
|
||||
The repo also ships `plotstyle`, a standalone matplotlib styling toolkit (KIT corporate-design theme + building-block functions) for producing the PDF figures that feed into a `gallery` source directory. `gallery` never imports it — the only connection is the PDF files and `metadata.yaml` on disk. **See `plotstyle/CLAUDE.md` for full agent-facing usage docs, the API reference, and the metadata.yaml workflow.**
|
||||
|
||||
This repo is a **uv workspace** (root `pyproject.toml` has `[tool.uv.workspace] members = ["plotstyle"]`) and both projects build with uv's own `uv_build` backend — there is no setuptools anywhere in this repo. Use `uv`/`uv run` for everything; don't reach for `pip install` here.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Install the package (editable)
|
||||
pip install -e ".[dev]"
|
||||
|
||||
# Also install plotstyle's dependency (matplotlib) if working on plot-producing scripts
|
||||
pip install -e ".[dev,plotting]" # or: uv sync --extra dev --extra plotting
|
||||
# Install everything (gallery + plotstyle + dev tools) into the shared workspace venv
|
||||
uv sync --all-packages
|
||||
|
||||
# Run all tests
|
||||
pytest tests/
|
||||
uv run pytest tests/
|
||||
|
||||
# Run a single test file
|
||||
pytest tests/test_generate_gallery.py -v
|
||||
pytest tests/test_plotstyle.py -v
|
||||
uv run pytest tests/test_generate_gallery.py -v
|
||||
uv run pytest tests/test_plotstyle.py -v
|
||||
|
||||
# Run a single test by name
|
||||
pytest tests/test_generate_gallery.py::test_needs_update_missing_target -v
|
||||
uv run pytest tests/test_generate_gallery.py::test_needs_update_missing_target -v
|
||||
|
||||
# Generate gallery
|
||||
gallery generate --verbose
|
||||
uv run gallery generate --verbose
|
||||
|
||||
# Generate with a non-default config
|
||||
gallery --config config.yaml generate --verbose
|
||||
uv run gallery --config config.yaml generate --verbose
|
||||
|
||||
# Incremental update for one source only
|
||||
gallery generate --source /path/to/plots --verbose
|
||||
uv run gallery generate --source /path/to/plots --verbose
|
||||
|
||||
# Clean regeneration
|
||||
gallery generate --clean --verbose
|
||||
uv run gallery generate --clean --verbose
|
||||
|
||||
# Launch TUI
|
||||
gallery tui
|
||||
uv run gallery tui
|
||||
|
||||
# Serve output locally
|
||||
python -m http.server 8000 -d /web/kschmidt/public_html/
|
||||
@@ -49,10 +48,10 @@ python -m http.server 8000 -d /web/kschmidt/public_html/
|
||||
Code style: ruff (lint + format), `line-length = 120`. Type-checked with `ty`.
|
||||
|
||||
```bash
|
||||
ruff check gallery plotstyle tests
|
||||
ruff format gallery plotstyle tests
|
||||
ty check gallery plotstyle
|
||||
pip-audit --skip-editable
|
||||
uv run ruff check gallery plotstyle tests
|
||||
uv run ruff format gallery plotstyle tests
|
||||
uv run ty check gallery plotstyle
|
||||
uv run pip-audit --skip-editable
|
||||
```
|
||||
|
||||
**Before committing**, run the same checks CI (`.gitea/workflows/ci.yml`) runs and make sure they pass — `ruff check`, `ruff format --check`, `ty check`, `pip-audit`, and `pytest tests/`. Catching a failure locally is faster than waiting on the pipeline.
|
||||
@@ -90,7 +89,8 @@ generate() [api.py]
|
||||
| `gallery/assets/js/` | Vanilla JS modules loaded as ES modules; `GalleryApp` in `gallery-app.js` orchestrates all managers |
|
||||
| `gallery/assets/css/` | Modular CSS; `main.css` imports all others via `@import` |
|
||||
| `config.yaml` | Local deployment config (paths are machine-specific) |
|
||||
| `plotstyle/` | Standalone matplotlib styling toolkit for producing plots (see `plotstyle/CLAUDE.md`) — not imported by `gallery/` |
|
||||
| `plotstyle/` | Standalone matplotlib styling toolkit for producing plots (see `plotstyle/CLAUDE.md`) — not imported by `gallery/`; a separate uv workspace member with its own `pyproject.toml`, code under `plotstyle/src/plotstyle/` (src layout) |
|
||||
| `.gitea/workflows/publish-plotstyle.yml` | Builds and publishes `plotstyle` to the Gitea package registry on `plotstyle-v*` tags |
|
||||
| `examples/plotstyle_showcase.ipynb` | Rendered, runnable tour of every `plotstyle` function |
|
||||
|
||||
### Config File Format
|
||||
@@ -125,7 +125,9 @@ Fields are freeform YAML (no fixed schema); `title`, `description`, `plot_type`,
|
||||
|
||||
### Plot-Producing Companion (`plotstyle`)
|
||||
|
||||
`plotstyle` (top-level package, optional `plotting` extra) is how plots destined for a `gallery` source directory should be produced — a KIT corporate-design matplotlib theme plus building blocks (`new_figure`, `colorbar`, `style_legend`, `panel_label`, `savefig`). It has no code dependency on `gallery`; the two only meet on disk, via the PDFs and `metadata.yaml` files a `plotstyle` script writes into a `gallery` source directory. **Full usage docs, API reference, best practices, and the metadata.yaml workflow live in `plotstyle/CLAUDE.md`** — read that file before writing or reviewing any script that `import plotstyle`. `examples/plotstyle_showcase.ipynb` is a rendered, runnable tour of every function.
|
||||
`plotstyle` (a separate uv workspace member, see below) is how plots destined for a `gallery` source directory should be produced — a KIT corporate-design matplotlib theme plus building blocks (`new_figure`, `colorbar`, `style_legend`, `panel_label`, `savefig`). It has no code dependency on `gallery`; the two only meet on disk, via the PDFs and `metadata.yaml` files a `plotstyle` script writes into a `gallery` source directory. **Full usage docs, API reference, best practices, and the metadata.yaml workflow live in `plotstyle/CLAUDE.md`** — read that file before writing or reviewing any script that `import plotstyle`. `examples/plotstyle_showcase.ipynb` is a rendered, runnable tour of every function.
|
||||
|
||||
`plotstyle` has its own `plotstyle/pyproject.toml` (own `uv_build` project, code lives in `plotstyle/src/plotstyle/`) and is a member of this repo's uv workspace (`[tool.uv.workspace] members = ["plotstyle"]` in the root `pyproject.toml`) — `uv sync --all-packages` installs both `gallery` and `plotstyle` (and matplotlib) into one shared venv, which is why `import plotstyle` works from `tests/` and the example notebook without `gallery` ever depending on it. It's also independently publishable: pushing a tag matching `plotstyle-v*` (e.g. `plotstyle-v0.1.0`) runs `.gitea/workflows/publish-plotstyle.yml`, which runs `uv build --package plotstyle` and `uv publish` to this repo's Gitea package registry (`{server}/api/packages/{owner}/pypi`) using the workflow's auto-generated token. The tag's version suffix must match `plotstyle/pyproject.toml`'s `version` field or the workflow fails fast — bump that version before tagging a new release.
|
||||
|
||||
### Frontend (Static JS/CSS)
|
||||
|
||||
@@ -133,6 +135,6 @@ The frontend is vanilla ES modules — no build step. `assets/js/main.js` import
|
||||
|
||||
### Deployment
|
||||
|
||||
The project ships a `Dockerfile` plus `docker-compose.yml` (a `generator` service that runs `gallery generate` on an interval, and an `nginx`-based `web` service serving the output — see `deploy/entrypoint.sh` and `deploy/nginx.conf`). This suits a dedicated VM/server you fully control. CI (`.gitea/workflows/ci.yml`, run via Gitea Actions) runs `ruff check`, `ruff format --check`, `ty check`, `pip-audit`, and pytest on the default runner image with Python 3.11 via `actions/setup-python` — no container build/publish in CI. For local development the `.venv` (or `uv`) is sufficient.
|
||||
The project ships a `Dockerfile` plus `docker-compose.yml` (a `generator` service that runs `gallery generate` on an interval, and an `nginx`-based `web` service serving the output — see `deploy/entrypoint.sh` and `deploy/nginx.conf`). This suits a dedicated VM/server you fully control. The `Dockerfile` is a two-stage build: a builder stage copies in the official `ghcr.io/astral-sh/uv` binary and runs `uv build --package gallery` to produce a wheel, then the final stage `pip install`s just that wheel (no dev deps, no workspace/lockfile needed at runtime). CI (`.gitea/workflows/ci.yml`, run via Gitea Actions) uses `astral-sh/setup-uv` + `uv sync --all-packages` and runs every check (`ruff check`, `ruff format --check`, `ty check`, `pip-audit`, `pytest`) via `uv run` — no plain `pip`/`actions/setup-python` anywhere in CI. For local development, `uv sync --all-packages` is all you need.
|
||||
|
||||
On shared HPC login nodes without a Docker daemon (e.g. KIT ETP, where `public_html` is already auto-served) use a plain venv install plus a `systemd --user` timer instead — see `deploy/systemd/README.md`.
|
||||
|
||||
Reference in New Issue
Block a user