
Releases are built by the "Create Release Artifacts" workflow, not locally:
it runs the test suite against "uv.lock", builds wheel + sdist with the
hash-pinned build backend from "build-constraints.txt", attests the build
provenance, attaches the artifacts to the GitHub release and uploads them to
pypi via trusted publishing.

  1. optional: refresh the pinned dependencies
     $ just update-dependencies
     $ just update-build-constraints
     $ just update-prek-hooks
     $ just update-workflow-actions

  2. set the release version in "VERSION.txt" and commit it

  3. push the tag, which triggers the release workflow
     $ git tag "v$(cat VERSION.txt)"
     $ git push origin main "v$(cat VERSION.txt)"

  4. approve the deployment to the "pypi" environment in the workflow run,
     which releases the artifacts to pypi

  5. set the next development version in "VERSION.txt" and commit it

"just build" produces the same artifacts locally, e.g. to test the packaging.
