#!/usr/bin/env bash # Install a published app_skellington from a package index into a clean venv # for every supported Python, then run scripts/smoke_import.py against it. # # Usage: scripts/verify_index_release.sh VERSION [INDEX_URL] # INDEX_URL defaults to TestPyPI. Dependencies always come from PyPI, # because TestPyPI hosts junk uploads under real dependency names. set -euo pipefail version="${1:?usage: $0 VERSION [INDEX_URL]}" index="${2:-https://test.pypi.org/simple/}" here="$(cd "$(dirname "$0")" && pwd)" pythons=(3.8 3.9 3.10 3.11 3.12 3.13 3.14) # The package must come from $index and nowhere else. Otherwise a local # build could pass for the published release. --no-config ignores # uv.toml/pyproject settings; these variables would still redirect, so refuse. for var in UV_INDEX UV_INDEX_URL UV_DEFAULT_INDEX UV_EXTRA_INDEX_URL \ UV_FIND_LINKS UV_INDEX_STRATEGY UV_NO_INDEX PIP_INDEX_URL \ PIP_EXTRA_INDEX_URL PIP_FIND_LINKS; do if [ -n "${!var:-}" ]; then echo "refusing: $var is set and could redirect the install away from $index" >&2 exit 2 fi done work="$(mktemp -d)" trap 'rm -rf "$work"' EXIT for py in "${pythons[@]}"; do venv="$work/$py" uv venv -q --no-config --python "$py" "$venv" # Wheel only: an sdist fallback would fetch its build backend from $index # (TestPyPI). Not quiet, so the log shows what was installed. uv pip install --no-config --python "$venv" --no-cache --no-deps \ --only-binary :all: --index-url "$index" "app_skellington==$version" "$venv/bin/python" -c 'import importlib.metadata as m; print("\n".join(m.requires("app_skellington") or []))' \ > "$work/requirements.txt" uv pip install -q --no-config --python "$venv" -r "$work/requirements.txt" (cd / && "$venv/bin/python" "$here/smoke_import.py" "$version") done echo "verified app_skellington==$version from $index on: ${pythons[*]}"