bcc-ui-theme / scripts /release.sh
Annie Voigt
Claude Opus 5
feat: bcc-ui-theme 0.1.0 β€” shared Gradio theme + stylesheet for the fleet
89e8390
Raw History Blame Contribute Delete
4.49 kB
#!/usr/bin/env bash
# Release bcc-ui-theme as a wheel on Hugging Face.
#
# Mirrors biodata-registry/scripts/release.sh, and for the same reasons:
#
# Why a wheel, not git: HF's git server cannot serve pip's partial clone
# (--filter=blob:none), so `pip install git+https://huggingface.co/...`
# fails on a Space build. A wheel over the resolve (HTTPS) URL installs.
#
# Why git-LFS and not `hf upload`: the HF API token is read-only and returns
# 403 on upload. The wheel ships as an LFS-tracked file committed at the repo
# root. Each wheel needs its OWN .gitattributes line β€” the entries are
# per-filename, not a *.whl glob β€” or a binary lands in git proper, silently.
# And the LFS OBJECT must be pushed BEFORE the ref, or the push is rejected
# with "LFS pointer pointed to a file that does not exist".
#
# Why one commit: the wheel ships with its own source, so a release commit
# can never declare a different version than the wheel it carries. That
# really happened in biodata-registry (83f95f9 carries 0.1.14 while its
# pyproject reads 0.1.13).
#
# Run after bumping `version` in pyproject.toml. Requires: uv, git-lfs.
set -euo pipefail
cd "$(dirname "$0")/.."
REPO="anne-voigt/bcc-ui-theme"
command -v uv >/dev/null || { echo "error: uv required (https://docs.astral.sh/uv/)" >&2; exit 1; }
git lfs version >/dev/null 2>&1 || {
echo "error: git-lfs required (brew install git-lfs && git lfs install)" >&2; exit 1; }
VERSION="$(grep -m1 '^version' pyproject.toml | sed 's/.*"\(.*\)".*/\1/')"
[ -n "$VERSION" ] || { echo "error: could not read version from pyproject.toml" >&2; exit 1; }
BASE="bcc_ui_theme-$VERSION-py3-none-any.whl"
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
echo "==> preflight (version $VERSION on branch $BRANCH)"
git diff --quiet && git diff --cached --quiet || {
echo "error: working tree has uncommitted changes β€” commit them before releasing." >&2
echo " the wheel must be reproducible from the commit that gets pushed." >&2
exit 1
}
[ "$BRANCH" = "main" ] || {
echo "error: releases are cut from main (on '$BRANCH'). Merge to main first." >&2
exit 1
}
# THE compatibility gate. A theme that constructs on one gradio version and not
# the other is the whole failure mode this package exists to prevent, so a
# release cannot skip it β€” there is no SKIP_ escape hatch on purpose.
echo "==> suite on BOTH pinned gradio versions (5.50.0 / 6.18.0)"
make test-both || {
echo "error: the suite is not green on both gradio versions β€” fix before releasing." >&2
exit 1
}
git fetch origin --quiet || true
if git cat-file -e "origin/main:$BASE" 2>/dev/null; then
echo "error: $BASE already exists on origin/main β€” bump 'version' in pyproject.toml." >&2
exit 1
fi
echo "==> building wheel"
rm -rf dist
uv build --wheel >/dev/null
[ -f "dist/$BASE" ] || { echo "error: expected dist/$BASE, got: $(ls dist/)" >&2; exit 1; }
SHA="$(shasum -a 256 "dist/$BASE" | cut -d' ' -f1)"
SIZE="$(wc -c < "dist/$BASE" | tr -d ' ')"
echo " dist/$BASE ($SIZE B, sha256 $SHA)"
echo "==> staging the wheel as a git-LFS file at the repo root"
cp "dist/$BASE" "$BASE"
if ! grep -qF "$BASE filter=lfs" .gitattributes 2>/dev/null; then
echo "$BASE filter=lfs diff=lfs merge=lfs -text" >> .gitattributes
echo " added the .gitattributes entry for $BASE"
fi
git add .gitattributes "$BASE"
# Verify it really staged as a pointer, not as a raw binary.
if ! git show ":$BASE" 2>/dev/null | head -1 | grep -q "version https://git-lfs"; then
echo "error: $BASE staged as a raw binary, not an LFS pointer." >&2
echo " check .gitattributes and that 'git lfs install' has been run." >&2
exit 1
fi
echo " ok β€” staged as an LFS pointer"
git commit -q -m "release: bcc-ui-theme $VERSION"
echo " release commit $(git rev-parse --short HEAD) (wheel + its own source)"
echo "==> uploading the LFS object BEFORE the ref (or the push is rejected)"
git lfs push origin main
git push origin main
COMMIT="$(git rev-parse HEAD)"
echo
echo "==> released. Pin line for each consumer's requirements.in / requirements.txt:"
echo
echo "bcc-ui-theme @ https://huggingface.co/$REPO/resolve/$COMMIT/$BASE"
echo
echo "Then, per consumer:"
echo " uv-compiled repos : uv pip compile requirements.in -o requirements.txt --python-version <3.13|3.11>"
echo " hand-pinned repos : edit requirements.txt directly (no .in exists)"
echo "See docs/ADOPTION.md for which repo is which, and adopt on dev Spaces first."