CI: fail when uv.lock drifts from pyproject.toml #92
No reviewers
Labels
No labels
area/ai
area/backend
area/frontend
area/infra
area/scheduler
area/wled
good-first-issue
priority/high
priority/low
priority/medium
type/bug
type/chore
type/ci-cd
type/docs
type/feature
type/qa
v1.0.0
v1.1.0
v1.2.0
v2.0.0
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/Iris-WLED!92
Loading…
Reference in a new issue
No description provided.
Delete branch "ci/verify-uv-lock"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes the gap that let #90's bug reach
main. Follow-up to #91.The gap
Nothing verified that the committed lockfile matched its source.
bc2284dchangedrequires-pythonto">=3.14"without regeneratinguv.lock, and all five jobs went green against a">=3.12"lock still carrying cp312 wheels. That's possible becauseci.ymlrunsuv sync --group devwithout--frozen: uv silently re-resolves and rewrites the lock in the workspace before anything reads it. The committed artifact was never exercised.It surfaced only because a local
git mergerefused to run on a dirtyuv.lock. That is not a detection mechanism.The fix
uv lock --checkinpython-lint.Placement is load-bearing — it runs before
uv sync. Afterwards it would always pass, against a file sync had just silently corrected.One job, not three. The lock is repo state, not per-job state, so checking it once is sufficient. This is the same role the existing
alembic checkjob plays for model/migration drift: guard a committed artifact against diverging from the source it derives from.Verified the guard actually bites
A check that prints a warning but exits 0 would be decorative, so I tested both directions by simulating the exact #90 mistake:
uv lock --checkrequires-pythondrifted from lockThe failure message also names the remedy directly:
And it passes on current
main(post-#91), so this does not land red.Considered and not done
Adding
--frozento the threeuv syncsteps would additionally guarantee CI installs exactly what is locked, rather than a re-resolved set. That is a stronger property, but it changes install behaviour in three places and would turn any lock staleness into three confusing failures instead of one clear one. With this check in place the lock is always current, sosyncre-resolving is a no-op. Worth revisiting if reproducibility of the installed set becomes a concern in its own right.