Contributing

Environment setup

We use uv for dependency management and build tooling. First, verify that uv is installed:

uv --version

If it’s not, install it:

curl -LsSf https://astral.sh/uv/install.sh | sh

Then clone the repository and install the project with all development dependencies:

git clone https://github.com/Arcadia-Science/glass-box-umap.git
cd glass-box-umap
uv sync --extra plotting --group dev --group docs

Important

It’s essential that you include the --extra and --group parameters.

This creates a virtual environment in .venv and installs all dependencies. The package itself is automatically installed in editable mode.

The easiest way to run code is to prefix commands with uv run (e.g., uv run <YOUR_COMMAND>). This executes the command inside the virtual environment automatically.

Alternatively, you can manually activate the virtual environment:

source .venv/bin/activate

Formatting and linting

To format the code:

make format

To run lint checks and type checking:

make lint

Pre-commit hooks

We use pre-commit to run formatting and lint checks before each commit. To install the hooks:

pre-commit install

To run the pre-commit checks manually:

make pre-commit

Testing

We use pytest for testing. Tests are in the glass_box_umap/tests/ subpackage. To run the tests:

make test

Managing dependencies

To add a new dependency:

uv add some-package

To add a development dependency:

uv add --group dev some-dev-package

To update a dependency:

uv lock --upgrade-package some-package

Whenever you add or update a dependency, uv will automatically update both pyproject.toml and uv.lock. Commit changes to both files.

Building documentation

We use Sphinx with the furo theme. First, install pandoc (required by nbsphinx).

# macOS
brew install pandoc

# Windows/Linux ???

Then build the docs:

make docs

Publishing to PyPI

Publishing requires API tokens for the test and production PyPI servers. Create a .env file by copying .env.copy and add your tokens.

We use semantic versioning (MAJOR.MINOR.PATCH). See semver.org for details.

Release process

  1. Update the version field in pyproject.toml

  2. Commit the change: git commit -am "Bump version to X.Y.Z"

  3. Create a git tag:

RELEASE_VERSION=0.1.0
git tag -a v${RELEASE_VERSION} -m "Release version ${RELEASE_VERSION}"
git push origin v${RELEASE_VERSION}

Make sure your local git repository is on main, up-to-date, and has no uncommitted changes before creating the tag.

  1. Build the package:

make build

Verify the version number in the output matches pyproject.toml and the git tag.

  1. Test publish to PyPI test server:

make build-and-test-publish
  1. Verify installation from test server:

pip install --index-url https://pypi.org/simple/ --extra-index-url https://test.pypi.org/simple/ glass-box-umap==${RELEASE_VERSION}
  1. Publish to production PyPI:

make build-and-publish
  1. Verify installation from production in a fresh, isolated environment:

pip install glass-box-umap==${RELEASE_VERSION}

Deleting a tag

If you need to delete a tag:

git tag -d v${RELEASE_VERSION}

If already pushed to GitHub:

git push origin :refs/tags/v${RELEASE_VERSION}