Skip to content

Use package groups instead of separate requirements-lockfiles #777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 20, 2025
Merged
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
requirements*.txt linguist-generated=true
uv.lock linguist-generated=true
*.lockb binary diff=lockb
30 changes: 11 additions & 19 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,38 +42,30 @@ jobs:
python-version: '3.12'
# cache: 'pip'
- name: set up `uv`
run: pip install uv && uv pip list
- name: restore uv cache
uses: actions/cache/restore@v4
id: cache-uv-restore
uses: astral-sh/setup-uv@v5
with:
path: ~/.cache/uv
key: uv
version: "0.6.2"
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: install pip dependencies with uv
run: >
uv pip sync --system requirements.dev.txt
&& uv pip install --system . deps/wtforms-widgets
&& uv pip list --system
uv sync --locked --dev
&& uv pip install deps/wtforms-widgets
&& uv pip list
id: pip-install
- name: save uv cache
uses: actions/cache/save@v4
id: cache-uv-save
with:
path: ~/.cache/uv
key: uv
# now come the tests
- name: Execute ruff
run: ruff check --output-format=github .
run: uv run ruff check --output-format=github .
if: success() || steps.pip-install.conclusion == 'success'
- name: Execute mypy
run: ./scripts/run_mypy.sh
run: uv run ./scripts/run_mypy.sh
if: success() || steps.pip-install.conclusion == 'success'
# docs stuff
- name: Build sphinx docs
run: make SPHINXOPTS="-EN -w sphinx.log" -C doc html
run: uv run make SPHINXOPTS="-EN -w sphinx.log" -C doc html
if: success() || steps.pip-install.conclusion == 'success'
- name: Render sphinx warnings as annotations
run: python ./scripts/render_sphinx_log.py doc/sphinx.log
run: uv run python ./scripts/render_sphinx_log.py doc/sphinx.log
if: success() || steps.pip-install.conclusion == 'success'
- name: Publish sphinx docs as pages artifact
uses: actions/upload-pages-artifact@v3
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,6 @@ venv.bak/

manuf
celerybeat-schedule
# timestamp-based dependency tracking.
# used by some docker entrypoint hooks
.*.stamp
15 changes: 2 additions & 13 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,9 @@ repos:
hooks:
- id: ruff
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.4.7
rev: 0.6.2
hooks:
- id: pip-compile
name: "pip-compile: requirements.txt"
args: [pyproject.toml, --generate-hashes, --quiet, -o, requirements.txt]
files: ^(pyproject.toml|requirements.txt)$
- id: pip-compile
name: "pip-compile: requirements.dev.txt"
args: [pyproject.toml, --generate-hashes, --extra, dev, --quiet, -o, requirements.dev.txt]
files: ^(pyproject.toml|requirements.dev.txt)$
- id: pip-compile
name: "pip-compile: requirements.prod.txt"
args: [pyproject.toml, --generate-hashes, --extra, prod, --quiet, -o, requirements.prod.txt]
files: ^(pyproject.toml|requirements.prod.txt)$
- id: uv-lock
- repo: https://github.com/semgrep/pre-commit
rev: 'v1.70.0'
hooks:
Expand Down
2 changes: 1 addition & 1 deletion doc/guides/setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ you only need to do the following:
.. code:: shell

uv venv
uv pip sync requirements.dev.txt && uv pip install -e deps/wtforms-widgets -e '.[dev]'
uv sync --locked && uv pip install -e deps/wtforms-widgets

#. Run tests / Build docs / …
3 changes: 2 additions & 1 deletion doc/guides/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Reinstall the pip requirements

.. code:: sh

drc run --rm dev-app pip sync requirements.txt
drc run --rm dev-app uv sync --locked
drc run --rm dev-app uv pip install -e . deps/wtforms-widgets

I need to downgrade the schema
------------------------------
Expand Down
6 changes: 3 additions & 3 deletions docker/base.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ARG GID=1000
ENV LANG=C.UTF-8 DEBIAN_FRONTEND=noninteractive

COPY etc/apt /etc/apt
COPY --from=ghcr.io/astral-sh/uv:0.6.2 /uv /uvx /usr/local/bin/

# Install Debian packages
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
Expand All @@ -29,9 +30,8 @@ WORKDIR /opt/pycroft
# - Create app directory
ENV VIRTUAL_ENV=/opt/pycroft/venv
RUN --mount=type=cache,target=/opt/pycroft/.cache,uid=$UID,gid=$GID\
python3 -m venv /opt/pycroft/venv \
&& /opt/pycroft/venv/bin/pip install -U uv \
&& /opt/pycroft/venv/bin/uv pip install -U setuptools wheel \
uv venv /opt/pycroft/venv \
&& uv pip install pip \
&& mkdir /opt/pycroft/app /opt/pycroft/wheel

COPY --link . /
Expand Down
30 changes: 11 additions & 19 deletions docker/dev/container/hooks/init/10_venv
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,27 @@

set -euo pipefail
LOCKDIR=/opt/pycroft/venv
INFILE=uv.lock
STAMPFILE=.uv.stamp

. /container/common/locking.sh

function execute_hook() {
set -x
PIP="/opt/pycroft/venv/bin/uv pip"
UV="/opt/pycroft/venv/bin/uv"
PY="/opt/pycroft/venv/bin/python"
PIP="uv pip"

if [[ ! -f /opt/pycroft/venv/bin/activate ]]; then
echo "Creating virtual environment"
python3 -m venv /opt/pycroft/venv
fi

if $PY -c 'import importlib.util as u; exit(0 if u.find_spec("pycroft") is not None else 1)'; then
echo "Pip packages present, nothing to do"
cd /opt/pycroft/app
if [[ ! $INFILE -nt $STAMPFILE ]]; then
echo "Lockfile did not change since last run. Nothing to do."
return
fi

$PY -m ensurepip
$PY -m pip install uv
$PIP install wheel

echo "No pip packages found, installing requirements"
cd /opt/pycroft/app
$PIP install --upgrade uv
ls `$UV cache dir`
$PIP sync requirements.dev.txt
$PIP install -e '.[dev]' 'wtforms-widgets @ ./deps/wtforms-widgets'
ls "$(uv cache dir)" || true
uv venv "$VIRTUAL_ENV"
uv sync --active --locked
$PIP install -e . -e './deps/wtforms-widgets'
touch $STAMPFILE
}

[[ -d $LOCKDIR ]] || mkdir $LOCKDIR
Expand Down
7 changes: 4 additions & 3 deletions docker/prod.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ FROM pycroft-dev AS builder
WORKDIR /opt/pycroft/app

# Download or build wheels of requirements
COPY --chown=pycroft:pycroft requirements.prod.txt .
COPY --chown=pycroft:pycroft uv.lock pyproject.toml ./
COPY --chown=pycroft:pycroft ./deps ./deps
RUN /opt/pycroft/venv/bin/pip wheel --wheel-dir /opt/pycroft/wheel -r requirements.prod.txt \
RUN uv export --locked --no-emit-project --no-dev --group prod > requirements.prod.txt \
&& /opt/pycroft/venv/bin/pip wheel --wheel-dir /opt/pycroft/wheel -r requirements.prod.txt \
&& rm /opt/pycroft/wheel/wtforms_widgets*.whl \
&& /opt/pycroft/venv/bin/pip wheel --wheel-dir /opt/pycroft/wheel --no-deps ./deps/wtforms-widgets

Expand All @@ -27,7 +28,7 @@ FROM pycroft-base

# Install wheels from builder
RUN --mount=type=bind,from=builder,source=/opt/pycroft/wheel,target=/opt/pycroft/wheel \
/opt/pycroft/venv/bin/pip install /opt/pycroft/wheel/*.whl
uv pip install /opt/pycroft/wheel/*.whl

EXPOSE 5000

Expand Down
10 changes: 6 additions & 4 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ setup: _setup && build _schema-import schema-upgrade
@echo -e "{{ _a_by }}About to build all docker images. This may take a while.{{ _a_rst }}"
@echo "If you wish to skip this, run \`setup-no-build\` instead."

local-setup:
uv sync --locked
uv pip install -e . -e deps/wtforms-widgets

_setup:
git submodule init
git submodule update
Expand Down Expand Up @@ -133,11 +137,9 @@ schema-diff: (_up "dev-db") (alembic "diff")
# upgrade the (imported or created) schema to the current revision
schema-upgrade: (_up "dev-db") (alembic "upgrade" "head")

# extract `requirements` lockfiles from `pyproject.toml` dependency spec
# regenerate `uv.lock`
deps-compile:
uv pip compile pyproject.toml --generate-hashes -o requirements.txt
uv pip compile pyproject.toml --generate-hashes --extra dev -o requirements.dev.txt
uv pip compile pyproject.toml --generate-hashes --extra prod -o requirements.prod.txt
uv lock

_stop_all:
{{ drc }} --progress=quiet stop
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ dependencies = [
"wtforms-widgets", # note: use `pip install -e deps/wtforms-widgets` for development
]

[project.optional-dependencies]
[dependency-groups]
prod = [
"uwsgi ~= 2.0.21",
"uwsgitop ~= 0.11",
Expand Down
Loading