fix(ci): install from uv.lock so CI stops resolving dependencies itself
CI & Build / Python lint (push) Successful in 3s
CI & Build / integration (push) Failing after 10s
CI & Build / Python tests (push) Failing after 16s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Build & push image (push) Has been skipped
CI & Build / Python lint (push) Successful in 3s
CI & Build / integration (push) Failing after 10s
CI & Build / Python tests (push) Failing after 16s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Build & push image (push) Has been skipped
Closes the reproducibility hole that turned `main` red an hour ago. CI ran `uv pip install -e ".[dev]"`, which resolves from the pyproject constraints and ignores uv.lock completely — so every dependency floated. uv.lock pinned mcp 1.27.2; CI installed the 2.0.0 published mid-session and the identical tree that passed on `dev` failed on `main`. Both Python lanes now run `uv sync --locked --extra dev`. `--locked` also fails when the lock is stale against pyproject, so a dependency change has to go through a deliberate `uv lock` instead of arriving on its own — which also restores the point of the Renovate dashboard-approval flow. Dropped the http-ece install and the setuptools/wheel step that existed only to support it: nothing in src/ or tests/ imports http_ece. It is a leftover from the web-push subsystem removed in the MCP-First pivot, and it was never in pyproject or uv.lock — CI was installing an unused package and carrying a --no-build-isolation workaround for it. Cache key moves from pyproject.toml to uv.lock, since the lock is now what determines the installed set. uv.lock's recorded root requirement updated to match the mcp cap. Edited by hand rather than regenerated: uv isn't installed on this workstation, the resolved mcp 1.27.2 already satisfies `<2`, so no re-resolution is needed — only the staleness check needed satisfying. The Dockerfile still resolves independently (`pip install .`, and it doesn't even copy uv.lock), so the shipped image is not yet covered. Following separately so a build break can't strand `main`. Refs #2194.
This commit is contained in:
+23
-19
@@ -126,20 +126,25 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
# Keyed on the LOCK, not pyproject: the lock is what determines the
|
||||
# installed set now, and a pyproject edit that doesn't change
|
||||
# resolution shouldn't throw the cache away.
|
||||
key: uv-${{ hashFiles('uv.lock') }}
|
||||
restore-keys: uv-
|
||||
|
||||
- name: Create virtual environment
|
||||
run: uv venv /opt/venv
|
||||
|
||||
- name: Install package with dev deps
|
||||
run: |
|
||||
# http-ece doesn't declare setuptools as a build dep, and uv
|
||||
# creates bare venvs without it. Install setuptools first so
|
||||
# --no-build-isolation can find it.
|
||||
uv pip install --python /opt/venv/bin/python setuptools wheel
|
||||
uv pip install --python /opt/venv/bin/python --no-build-isolation http-ece
|
||||
uv pip install --python /opt/venv/bin/python -e ".[dev]"
|
||||
# Installs exactly what uv.lock pins. `--locked` additionally FAILS if the
|
||||
# lock is stale against pyproject, so a dependency change has to go through
|
||||
# a deliberate `uv lock` — it can't drift in silently.
|
||||
#
|
||||
# This replaced `uv pip install -e ".[dev]"`, which resolved from the
|
||||
# pyproject constraints and ignored the lock entirely. Every dependency
|
||||
# floated: on 2026-07-28 mcp 2.0.0 shipped mid-session and turned `main`
|
||||
# red with no repo change (issue #2194). Green CI has to mean "these exact
|
||||
# versions passed", or it isn't evidence of anything.
|
||||
- name: Install locked dependencies
|
||||
env:
|
||||
UV_PROJECT_ENVIRONMENT: /opt/venv
|
||||
run: uv sync --locked --extra dev
|
||||
|
||||
- name: Run tests
|
||||
# Integration tests (real Postgres) run in the `integration` job below.
|
||||
@@ -179,13 +184,12 @@ jobs:
|
||||
--health-retries 10
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Create virtual environment
|
||||
run: uv venv /opt/venv
|
||||
- name: Install package with dev deps
|
||||
run: |
|
||||
uv pip install --python /opt/venv/bin/python setuptools wheel
|
||||
uv pip install --python /opt/venv/bin/python --no-build-isolation http-ece
|
||||
uv pip install --python /opt/venv/bin/python -e ".[dev]"
|
||||
# Same locked install as the unit lane — the two must agree on versions,
|
||||
# or "unit green, integration red" stops being a signal about the code.
|
||||
- name: Install locked dependencies
|
||||
env:
|
||||
UV_PROJECT_ENVIRONMENT: /opt/venv
|
||||
run: uv sync --locked --extra dev
|
||||
- name: Integration suite (resolve service IP, migrate, test)
|
||||
run: |
|
||||
set -eux
|
||||
|
||||
@@ -393,7 +393,7 @@ requires-dist = [
|
||||
{ name = "httpx", specifier = ">=0.27" },
|
||||
{ name = "hypercorn", specifier = ">=0.17" },
|
||||
{ name = "icalendar", specifier = ">=5.0" },
|
||||
{ name = "mcp", extras = ["cli"], specifier = ">=1.0" },
|
||||
{ name = "mcp", extras = ["cli"], specifier = ">=1.0,<2" },
|
||||
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" },
|
||||
{ name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.23" },
|
||||
{ name = "quart", specifier = ">=0.19" },
|
||||
|
||||
Reference in New Issue
Block a user