mjlab/RELEASING.md
Upstream Snapshot 32a241c28f
Some checks failed
nightly / Test against latest dependencies (py3.10) (push) Has been cancelled
nightly / Test against latest dependencies (py3.13) (push) Has been cancelled
tests / tests (3.13, locked) (push) Has been cancelled
tests / tests (3.13, unlocked) (push) Has been cancelled
tests / pyright (3.10) (push) Has been cancelled
tests / lint-format (push) Has been cancelled
tests / tests (3.10, locked) (push) Has been cancelled
tests / tests (3.11, locked) (push) Has been cancelled
tests / tests (3.12, locked) (push) Has been cancelled
tests / pyright (3.11) (push) Has been cancelled
tests / pyright (3.12) (push) Has been cancelled
tests / pyright (3.13) (push) Has been cancelled
tests / ty-check (3.10) (push) Has been cancelled
tests / ty-check (3.11) (push) Has been cancelled
tests / ty-check (3.12) (push) Has been cancelled
tests / ty-check (3.13) (push) Has been cancelled
tests / stubs (push) Has been cancelled
tests / smoke-test (push) Has been cancelled
Docker / check_paths (push) Has been cancelled
docs / build (push) Has been cancelled
Docker / build (push) Has been cancelled
Import upstream snapshot c19f713c415a699a79d71cd96aa13c3104a05047
Upstream: https://github.com/michaelgillett/mjlab
Upstream-Commit: c19f713c415a699a79d71cd96aa13c3104a05047
Upstream-Branch: main
2026-08-28 15:42:17 +08:00

1.7 KiB

Releasing

Pre-release checklist

  1. Bump version in pyproject.toml.
  2. Update version and date-released in CITATION.cff.
  3. Update the "Upcoming version (not yet released)" heading in docs/source/changelog.rst to the new version number and date.
  4. Commit the version bump, then create an annotated tag:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z

Build and verify

Clean previous build artifacts, then build:

rm -rf dist/
make build

This runs uv build to produce a wheel and sdist in dist/, then smoke-tests both artifacts in isolated environments.

Upload to TestPyPI first to catch packaging issues before the real release:

UV_PUBLISH_TOKEN=<your-testpypi-token> make publish-test

Then verify the upload works end-to-end. Use --index-strategy unsafe-best-match because TestPyPI won't have all dependencies and uv needs to fall back to real PyPI for them:

uvx --extra-index-url https://test.pypi.org/simple/ \
    --index-strategy unsafe-best-match \
    --from mjlab \
    demo

Note: TestPyPI requires a separate account and token from real PyPI. Generate one at https://test.pypi.org/manage/account/token/.

Publish to PyPI

UV_PUBLISH_TOKEN=<your-pypi-token> make publish

Generate a token at https://pypi.org/manage/account/token/.

Post-release

Verify the release installs and runs correctly. Use --refresh to bypass the uvx cache (which may still hold the TestPyPI version):

uvx --refresh --from mjlab demo

Releasing from a past tag

If the tag has already been created and HEAD has moved ahead, check out the tag before building:

git checkout vX.Y.Z
make build
make publish
git checkout main