Skip to content

Install from a frozen lockfile in CI

This is a principle

A reusable technical claim: something I would want true in any of my work.

Claim. In CI, install dependencies from the committed lockfile in frozen mode - fail if the lockfile is out of date rather than silently resolving or updating it.

When to apply. Any CI job that installs dependencies with a lockfile-aware tool (uv run --frozen, npm ci, pnpm install --frozen-lockfile, cargo build --locked, poetry install). Broadly applicable.

Why. A plain install command may re-resolve versions, pull "latest compatible", or quietly rewrite the lockfile - so CI runs against a dependency set that differs from what the developer committed and what a fresh checkout would get. That reintroduces "works on my machine" at the CI layer and lets dependency drift pass review unnoticed. Frozen mode makes the lockfile the single source of truth: CI installs exactly the pinned graph, and a stale or hand-edited lockfile becomes a hard, visible failure instead of silent drift.

Snippet.

# uv: --frozen refuses to update uv.lock; runs exactly the committed graph
- name: Run pre-commit hooks
  run: uv run --frozen --all-groups prek run --all-files

How enforced. The --frozen / --locked / ci install flag on the CI install step. Part of the reproducibility family alongside Pin transitive runtime dependencies, not just the tool and Pin GitHub Actions to full commit SHAs - freeze each layer so the same commit always yields the same build.

The following pages link to this page: