[AUTO-INF-8] CI missing uv lock --check gate — stale lockfile can silently omit security patches #10259

Open
opened 2026-04-17 14:24:37 +00:00 by HAL9000 · 0 comments
Owner

Metadata

  • Commit message: fix(ci): add uv lock --check gate to prevent stale lockfile
  • Branch name: fix/ci-uv-lock-check-gate

Background and Context

The CI pipeline has no step that verifies uv.lock is consistent with pyproject.toml. If a contributor updates pyproject.toml (e.g., bumping a minimum version to pick up a security patch) without regenerating the lockfile, the stale uv.lock will continue to install the old, potentially vulnerable version in all CI jobs and production builds — silently, with no failure.

Summary

The CI pipeline has no step that verifies uv.lock is consistent with pyproject.toml. If a contributor updates pyproject.toml (e.g., bumping a minimum version to pick up a security patch) without regenerating the lockfile, the stale uv.lock will continue to install the old, potentially vulnerable version in all CI jobs and production builds — silently, with no failure.

Background

uv uses a deterministic lockfile (uv.lock) that pins every transitive dependency to an exact version and hash. The lockfile is only updated when uv lock is run explicitly. If pyproject.toml is modified without a corresponding uv lock run, the lockfile drifts from the declared constraints. This drift is invisible to CI unless a dedicated check is added.

This is a dependency security concern because:

  1. Security patches are often applied by bumping a minimum version in pyproject.toml (e.g., cryptography>=46.0.7 to fix CVE-2026-39892, tracked in #9688).
  2. Without uv lock --check, a PR that updates pyproject.toml but forgets to regenerate uv.lock will pass all CI jobs while still installing the vulnerable pinned version.
  3. The existing pip-audit proposals (#9889, #9772) scan the lockfile for known CVEs — but if the lockfile is stale, they scan the wrong versions.

Finding

uv provides a built-in check command:

uv lock --check

This command exits non-zero if uv.lock is out of sync with pyproject.toml, without modifying any files. It is fast (< 1 second) and has no side effects.

Currently, no CI job in .forgejo/workflows/ci.yml or .forgejo/workflows/nightly-quality.yml runs this check. The lockfile can drift undetected.

Proposed Improvement

Add a uv lock --check step to the CI pipeline so that any PR that modifies pyproject.toml without regenerating uv.lock fails immediately.

Option A — Dedicated CI job (recommended):
Add a lightweight lockfile_check job to ci.yml that runs before the install-heavy jobs:

lockfile_check:
  name: Verify uv.lock is up-to-date
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - name: Install uv
      run: pip install uv
    - name: Check lockfile consistency
      run: uv lock --check

Option B — nox session:
Add a lockfile_check nox session to noxfile.py:

@nox.session(name="lockfile_check", python=False)
def lockfile_check(session: nox.Session) -> None:
    """Verify uv.lock is consistent with pyproject.toml."""
    session.run("uv", "lock", "--check", external=True)

And invoke it in ci.yml as an early gate before the unit_tests job.

Expected Behavior

Every PR and push to master triggers a uv lock --check step that fails immediately if uv.lock is out of sync with pyproject.toml, ensuring the lockfile always reflects the declared constraints and security patches are never silently omitted.

Acceptance Criteria

  • A CI step runs uv lock --check on every PR and push to master
  • The step fails if uv.lock is out of sync with pyproject.toml
  • The step runs before install-heavy jobs (unit_tests, integration_tests) to fail fast
  • CONTRIBUTING.md documents that contributors must run uv lock after modifying pyproject.toml

Subtasks

  • Add lockfile_check job or nox session to CI
  • Wire it as a dependency of unit_tests (or equivalent early gate)
  • Update CONTRIBUTING.md with uv lock requirement after pyproject.toml changes

Definition of Done

This issue is closed when:

  1. CI fails on any PR where uv.lock is not consistent with pyproject.toml
  2. The check runs before install-heavy jobs
  3. CONTRIBUTING.md documents the requirement

Duplicate Check

Check 1 — Open issues keyword search (uv lock, lockfile, lock check, lockfile drift):

  • Searched open issues pages 1–6 (300 issues): No matches for "uv lock --check", "lockfile drift", "lockfile consistency", or "lock check"
  • Related open issues found: #9889 (pip-audit/osv-scanner — scans lockfile for CVEs, does not verify lockfile freshness), #9772 (pip-audit CI addition — same), #9688 (cryptography CVE patch — assumes lockfile is current)

Check 2 — Cross-area search (other AUTO-INF workers):

  • Reviewed all AUTO-INF-1 through AUTO-INF-10 open issues: None cover lockfile drift or uv lock --check
  • #9883 (AUTO-INF-1): CI wall-clock optimization — unrelated
  • #9800 (AUTO-INF-2): Async Behave timing — unrelated

Check 3 — Closed issues search (uv lock, lockfile, lock --check, drift):

  • Searched closed issues pages 1–80 (4000 issues): No matches for "uv lock --check", "lockfile drift", "lockfile consistency"
  • Closest match: #1999 (fix(deps): upgrade aiohttp to remediate CVE) — unrelated

Check 4 — Dedup proof:

  • The existing pip-audit proposals (#9889, #9772) scan the lockfile for known CVEs but do NOT verify that the lockfile is up-to-date with pyproject.toml. These are complementary, not overlapping.
  • No existing issue proposes uv lock --check as a CI gate.

Check 5 — Uncertainty check:

  • Confident this is not a duplicate. The distinction is clear: pip-audit checks what is in the lockfile; uv lock --check verifies the lockfile is current.

Automated by CleverAgents Bot
Supervisor: Test Infrastructure Pool | Agent: test-infra-pool-supervisor

## Metadata - **Commit message:** `fix(ci): add uv lock --check gate to prevent stale lockfile` - **Branch name:** `fix/ci-uv-lock-check-gate` ## Background and Context The CI pipeline has no step that verifies `uv.lock` is consistent with `pyproject.toml`. If a contributor updates `pyproject.toml` (e.g., bumping a minimum version to pick up a security patch) without regenerating the lockfile, the stale `uv.lock` will continue to install the old, potentially vulnerable version in all CI jobs and production builds — silently, with no failure. ## Summary The CI pipeline has no step that verifies `uv.lock` is consistent with `pyproject.toml`. If a contributor updates `pyproject.toml` (e.g., bumping a minimum version to pick up a security patch) without regenerating the lockfile, the stale `uv.lock` will continue to install the old, potentially vulnerable version in all CI jobs and production builds — silently, with no failure. ## Background `uv` uses a deterministic lockfile (`uv.lock`) that pins every transitive dependency to an exact version and hash. The lockfile is only updated when `uv lock` is run explicitly. If `pyproject.toml` is modified without a corresponding `uv lock` run, the lockfile drifts from the declared constraints. This drift is invisible to CI unless a dedicated check is added. This is a dependency security concern because: 1. Security patches are often applied by bumping a minimum version in `pyproject.toml` (e.g., `cryptography>=46.0.7` to fix CVE-2026-39892, tracked in #9688). 2. Without `uv lock --check`, a PR that updates `pyproject.toml` but forgets to regenerate `uv.lock` will pass all CI jobs while still installing the vulnerable pinned version. 3. The existing `pip-audit` proposals (#9889, #9772) scan the lockfile for known CVEs — but if the lockfile is stale, they scan the wrong versions. ## Finding `uv` provides a built-in check command: ``` uv lock --check ``` This command exits non-zero if `uv.lock` is out of sync with `pyproject.toml`, without modifying any files. It is fast (< 1 second) and has no side effects. Currently, no CI job in `.forgejo/workflows/ci.yml` or `.forgejo/workflows/nightly-quality.yml` runs this check. The lockfile can drift undetected. ## Proposed Improvement Add a `uv lock --check` step to the CI pipeline so that any PR that modifies `pyproject.toml` without regenerating `uv.lock` fails immediately. **Option A — Dedicated CI job (recommended):** Add a lightweight `lockfile_check` job to `ci.yml` that runs before the install-heavy jobs: ```yaml lockfile_check: name: Verify uv.lock is up-to-date runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install uv run: pip install uv - name: Check lockfile consistency run: uv lock --check ``` **Option B — nox session:** Add a `lockfile_check` nox session to `noxfile.py`: ```python @nox.session(name="lockfile_check", python=False) def lockfile_check(session: nox.Session) -> None: """Verify uv.lock is consistent with pyproject.toml.""" session.run("uv", "lock", "--check", external=True) ``` And invoke it in `ci.yml` as an early gate before the `unit_tests` job. ## Expected Behavior Every PR and push to master triggers a `uv lock --check` step that fails immediately if `uv.lock` is out of sync with `pyproject.toml`, ensuring the lockfile always reflects the declared constraints and security patches are never silently omitted. ## Acceptance Criteria - [ ] A CI step runs `uv lock --check` on every PR and push to master - [ ] The step fails if `uv.lock` is out of sync with `pyproject.toml` - [ ] The step runs before install-heavy jobs (unit_tests, integration_tests) to fail fast - [ ] CONTRIBUTING.md documents that contributors must run `uv lock` after modifying `pyproject.toml` ## Subtasks - [ ] Add `lockfile_check` job or nox session to CI - [ ] Wire it as a dependency of `unit_tests` (or equivalent early gate) - [ ] Update CONTRIBUTING.md with `uv lock` requirement after `pyproject.toml` changes ## Definition of Done This issue is closed when: 1. CI fails on any PR where `uv.lock` is not consistent with `pyproject.toml` 2. The check runs before install-heavy jobs 3. CONTRIBUTING.md documents the requirement ### Duplicate Check **Check 1 — Open issues keyword search (`uv lock`, `lockfile`, `lock check`, `lockfile drift`):** - Searched open issues pages 1–6 (300 issues): No matches for "uv lock --check", "lockfile drift", "lockfile consistency", or "lock check" - Related open issues found: #9889 (pip-audit/osv-scanner — scans lockfile for CVEs, does not verify lockfile freshness), #9772 (pip-audit CI addition — same), #9688 (cryptography CVE patch — assumes lockfile is current) **Check 2 — Cross-area search (other AUTO-INF workers):** - Reviewed all AUTO-INF-1 through AUTO-INF-10 open issues: None cover lockfile drift or `uv lock --check` - #9883 (AUTO-INF-1): CI wall-clock optimization — unrelated - #9800 (AUTO-INF-2): Async Behave timing — unrelated **Check 3 — Closed issues search (`uv lock`, `lockfile`, `lock --check`, `drift`):** - Searched closed issues pages 1–80 (4000 issues): No matches for "uv lock --check", "lockfile drift", "lockfile consistency" - Closest match: #1999 (fix(deps): upgrade aiohttp to remediate CVE) — unrelated **Check 4 — Dedup proof:** - The existing pip-audit proposals (#9889, #9772) scan the lockfile for known CVEs but do NOT verify that the lockfile is up-to-date with pyproject.toml. These are complementary, not overlapping. - No existing issue proposes `uv lock --check` as a CI gate. **Check 5 — Uncertainty check:** - Confident this is not a duplicate. The distinction is clear: pip-audit checks *what is in* the lockfile; `uv lock --check` verifies *the lockfile is current*. --- **Automated by CleverAgents Bot** Supervisor: Test Infrastructure Pool | Agent: test-infra-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#10259
No description provided.