Skip to content

The next develop to main promotion also changes how the host installs and builds dependencies #545

Description

@willhea

What needs doing

Sibling to #400, which flagged that the launch target moves from server.app:app to
web.app:app and closed by asking whether anything else in the develop backlog also
assumes host-side configuration. This is the result of that check. Two further changes
land on the deployment host at the same promotion, and they surface at the same restart,
so they will present as one failure.

The deploy command is git pull && uv sync --no-dev && sudo systemctl restart deltatrack
(docs/web-compare.md:150).

1. uv sync gains a package build step it does not have today

origin/main's pyproject.toml has no [build-system] table, so uv sync treats the
repository as a virtual project: it installs dependencies and nothing else, and imports
resolve from the working directory.

origin/develop adds one (hatchling) alongside the src/ layout from #398. uv sync
will therefore build and install the deltatrack wheel on the host, which is a step
that has never run there. Locally the build succeeds; on the host it is unexercised.

2. The web server's dependencies move out of [project].dependencies

On main, fastapi, uvicorn[standard], python-multipart, httpx and python-dotenv
are all top-level dependencies. On develop they are dependency groups:

  • web: fastapi, uvicorn[standard], python-multipart, and slowapi (new)
  • fetch: httpx, python-dotenv

They are reachable only because develop also adds [tool.uv] default-groups = ["dev", "web", "fetch"]. That key does not exist on main, and it is now the only thing putting
a web server on the deployment host.

This part verified, and it passes. uv sync --no-dev --dry-run against current
develop (uv 0.12.1) uninstalls 38 packages, all of them from the dev group (pytest,
ruff, playwright, pre-commit and similar). fastapi, uvicorn, slowapi,
python-multipart, httpx and python-dotenv are absent from the uninstall list, so
--no-dev drops only dev and the other two default groups survive. On a current uv the
move is safe.

The residual risk is version-dependent rather than logical: default-groups is a
comparatively recent uv feature, and on a uv old enough not to honour it, uv sync --no-dev would install [project].dependencies only, which on develop is pypdfium2
and tomlkit. The host would come back with no web server at all rather than with a
subtly wrong one.

3. Version jumps on a live service, in the same restart

fastapi 0.115 to 0.140.13, uvicorn 0.32 to 0.51.0, pypdfium2 5.8 to 5.12.1, plus
slowapi as a new runtime dependency introducing per-IP rate limiting on /api/compare.

Why it matters

Same delayed-failure shape as #400. Nothing is wrong at merge time, because the running
service keeps serving from what it already imported. The failure needs a restart, and a
restart can arrive unattended. All of #400 and the above then surface together, so
diagnosis will find the ModuleNotFoundError from #400 first and may stop there while a
second cause is still present.

What to check, before or during the promotion

  • The host's uv --version, against the version that introduced default-groups support.
    This is the one that fails hardest and is cheapest to check.
  • That the hatchling build succeeds on the host, given its Python and network posture.
  • That the host's working directory still puts the repository root on sys.path.
    [tool.hatch.build.targets.wheel] packages = ["src/deltatrack"] means web/ is not
    in the installed wheel, so web.app:app still resolves from the checkout rather than
    from site-packages. This is the same working-directory assumption The next develop to main promotion breaks the site's uvicorn launch target #400 listed as
    unverified, and it remains unverified.

Verification

As with #400, the test suite cannot cover any of this: what changes is how a machine
outside the repository installs and launches the code. Confirm by restarting the service
and loading the site, not by editing configuration and assuming it took. A restart is the
condition that breaks it, so a restart is what proves it fixed.

Unverified

I have not inspected the host. Its uv version, Python version, working directory and
service definition are all unknown here. The deploy command above is quoted from
docs/web-compare.md, which points to a separate private runbook for production
specifics; the command actually in use may differ.

Refs #400 (the launch-target change, and the audit request this answers), #398 (the
installable-package change), #399 and #367 (the surface split).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions