Implement the following plan:
Plan: Migrate from pip/venv/shiv to uv
Context
The project currently uses pip, venv, setuptools, and shiv for dependency management, virtual environments, building, and distribution. uv is a modern replacement (by Astral) that is 10-100x faster and unifies these tools. The goal is to migrate the entire development and CI workflow to uv, switch the build backend to uv_build, and continue using shiv (via uvx) for the zipapp distribution step since uv has no native equivalent yet.
Files to modify
pyproject.toml — switch build backend, move dev deps
scripts/developer-mode-setup.sh — simplify to use uv
scripts/build_shiv_package.sh — use uvx shiv instead of bare shiv
.envrc — point to .venv instead of venv
.gitignore — add .venv, uv.lock; keep venv for safety
tox.ini — add .venv to flake8 exclude list
.github/workflows/publish.yml — replace setup-python+pip with setup-uv
.github/workflows/test.yml — same
.github/workflows/test-deploy.yml — same
.github/workflows/test-webapp.yml — same
.github/workflows/test-deploy-k8s.yml — same
.github/workflows/lint.yml — switch to uv for flake8
New files
uv.lock — auto-generated by uv lock (committed to git)
.python-version — created by uv python pin 3.12
Files to delete
MANIFEST.in — not used by uv_build (only contains include LICENSE which pyproject.toml handles)
Steps
Step 1: Update pyproject.toml
- Change
[build-system] from setuptools to uv_build:
toml
[build-system]
requires = ["uv_build>=0.10.6,<0.11.0"]
build-backend = "uv_build"
- Move
flake8 and black from dependencies to a [dependency-groups] section:
toml
[dependency-groups]
dev = ["flake8", "black"]
- Remove the
[tool.setuptools.package-data] section (uv_build auto-includes files within the module directory; src/stack/data/ has an __init__.py and lives inside the package)
Step 2: Update scripts/developer-mode-setup.sh
Replace the multi-step venv/pip dance with:
#!/usr/bin/env bash
if [[ -n "$STACK_SCRIPT_DEBUG" ]]; then
set -x
fi
uv sync
Step 3: Update scripts/build_shiv_package.sh
Change shiv to uvx shiv:
mkdir -p ./package
version_string=$( ./scripts/create_build_tag_file.sh )
uvx shiv -c stack -o package/stack-${version_string} .
Step 4: Update .envrc
Change from . venv/bin/activate to . .venv/bin/activate (uv uses .venv by convention).
Step 5: Update .gitignore
Add .venv entry. The existing venv entry can remain. Also ensure uv.lock is NOT ignored (it should be committed).
Step 6: Update tox.ini
Add .venv to the flake8 exclude list (currently only excludes venv).
Step 7: Update all GitHub Actions workflows
For the 5 workflows that install Python + shiv (publish, test, test-deploy, test-webapp, test-deploy-k8s), replace:
- name: "Install Python"
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: "Install shiv"
run: pip install shiv
With:
- name: "Install uv"
uses: astral-sh/setup-uv@v4
with:
python-version: '3.12'
Remove any "Print Python version" steps or update them to uv python --version.
For lint.yml, replace the py-actions/flake8@v2 action with uv-based linting:
- name: "Install uv"
uses: astral-sh/setup-uv@v4
with:
python-version: '3.12'
- name: "Install dependencies"
run: uv sync
- name: "Run flake8"
run: uv run flake8 --config tox.ini
Step 8: Update scripts/lint.sh
Prefix black and flake8 commands with uv run so they execute within the uv-managed environment.
Step 9: Generate lock file and pin Python version
Run:
uv lock
uv python pin 3.12
Step 10: Delete MANIFEST.in
No longer needed — uv_build does not use it.
Verification
- Run
uv sync — should create .venv/ and install all deps
- Run
uv run stack version — should print the version
- Run
uv run flake8 --config tox.ini — linting should pass
- Run
./scripts/build_shiv_package.sh — should produce a working shiv zipapp in package/
- Execute the produced zipapp directly:
./package/stack-* version
- Run
./scripts/lint.sh — should work with uv run
If you need specific details from before exiting plan mode (like exact code snippets, error messages, or content you generated), read the full transcript at: /home/david/.claude/projects/-home-david-projects-bpi-stack/baff6896-b47d-428c-bfce-e2cc326a2773.jsonl