#!/usr/bin/env bash # Regenerate requirements.txt from requirements.in. # # Run this whenever you add, remove, or change a constraint in # requirements.in — never edit requirements.txt by hand. The output is # a fully-pinned lockfile with sha256 hashes, consumed at image-build # time with `pip install --require-hashes`. # # Runs pip-compile in a clean python:3.12-slim container so this script # has no host dependencies — Docker is enough. # # Usage: # ./scripts/regenerate-lockfile.sh # # After it runs: # - Review the diff (`git diff requirements.txt`) — bumps to # transitive deps may be CVE fixes or breaking changes # - Rebuild the container locally to confirm install + boot # - Commit requirements.in AND requirements.txt together set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$REPO_ROOT" if [ ! -f requirements.in ]; then echo "fatal: requirements.in not found in $REPO_ROOT" >&2 exit 1 fi echo "Regenerating requirements.txt from requirements.in ..." docker run --rm \ -v "$REPO_ROOT:/work" \ -w /work \ python:3.12-slim \ bash -c " pip install --quiet --no-cache-dir --disable-pip-version-check pip-tools 2>&1 | tail -3 pip-compile --quiet --generate-hashes --strip-extras \ --output-file=requirements.txt requirements.in chown $(id -u):$(id -g) requirements.txt " echo "Done. New lockfile is $(wc -l < requirements.txt) lines." echo "Review: git diff requirements.txt" echo "Verify: docker compose build app && docker compose up -d app"