Contributing
July 1, 2026 ยท View on GitHub
We are happy to accept external contributions!ย ๐
First, let us know what you would like to contribute. Feel free to:
- report a bug or request a feature by filing an issue on our GitHub;
- send general queries to contact@opendp.org, or email security@opendp.org if it is related to security;
- ask any question on our Slack instance. Tumult Analytics maintainers are active on most of the public channels, the
lib-devandlib-supportchannels are a great place to start interacting with the development community.
Once you have agreement on the feature or bug, anyone can send us a Pull Request from a forked repo per Github's documentation. Ideally Pull Requests are linked to an issue so the maintainers can easily understand the problem being solved. We try to link all Pull Requests to issues ourselves, so creating and commenting on issues is an easy way to get involved.
Local development
Installation
We use uv for dependency management during development. To set up your environment, install uv by following its installation instructions, then install the prerequisites listed in the Tumult Analytics installation instructions, and finally install our dev dependencies by running uv sync from the root of this repository.
To minimize compatibility issues, doing development on the oldest supported Python minor version (currently 3.10) is strongly recommended.
If you are using uv to manage your Python installations, running uv sync without an existing virtual environment should automatically install and use an appropriate Python version.
Basic usage
You can then locally run our linters and tests by running:
make lint
make test
from the repository root directory.
Note that some operating systems, including macOS, include versions of make that are too old to run this project's Makefile correctly. macOS users should install a newer version of make using Homebrew.
Behind the scenes, these commands use the uv environment, and rely on nox for test automation. You can get a bit more fine-grained control and access additional tools by running nox commands directly (see this tutorial). You can find a list of available nox sessions using uv run nox --list, then run one of these sessions using e.g. uv run nox -s test-fast.
Testing
Our unit tests are run with pytest. You can run smaller subsets of tests by using pytest directly. For example, to check tests in a particular test file, run:
uv run pytest test/unit/a_test_file.py
You can also filter to specific tests or specific groups of tests using pytest filters. We tag all of our longest-running tests with the slow tag, so they can be skipped easily when you want faster feedback (though make sure they pass before you submit!):
uv run pytest -m "not slow"
Documentation
The documentation is built using Sphinx, and relies on autosummary to generate the API reference.
To build the documentation locally, run:
make docs
the generated HTML pages are available in the public directory.
Note that our API reference is manually organized, and does not follow the internal package structure. If you add a new public class or method to Tumult Analytics, add it to an autosummary directive in the relevant .rst file under doc/reference.
Continuous integration
We use GitHub Actions to automatically run some jobs under specific conditions.
The definition of these jobs can be found in .github/workflows.
To try it out a newly modified action before merging the PR, you can change the trigger to the definition file to execute whenever you push on your branch:
on:
push:
branch: your_username/your_branch
Cleanup
Running linters, tests, or building docs tends to generate a lot of files in the repository that you generally don't want to keep around. Simply run make clean to get rid of all those. This is particularly useful when working on the documentation; Sphinx tends to get confused by files generated in previous documentation builds.
Releasing
To release a new version of the library:
- Add a sentence under the "Unreleased" section of
CHANGELOG.rstto describe the changes at a high level. Merge this in a PR. - Once the changelog PR is in, run
git pullto make sure you have the latest version ofmainlocally, then runnox -s make-release -- VERSION, where VERSION is the new version of the library. This will create a release PR. - Merge that PR into
mainwithout squashing its commits (so the release commit ends up in the history ofmain).
If the release pipeline associated with the PR failed, and additional work needed to be merged before the release, revert the steps 2 and 3 as follows:
- Run
git branch -D release/VERSIONto remove the release branch locally. - Run
git push origin --delete release/VERSIONto remove the release branch on the remote repository. - Go to the list of tags of the repository, and delete the one that was just created.
- Run
git fetch origin "refs/tags/*:refs/tags/*" --pruneto remove the local reference to the now-deleted tag.
After this, you can re-create a new PR using step 2 above.
Final thoughts
We want to actively encourage contributions and help you merge your bug fixes or new features. Please don't hesitate to ask us for help on Slack if you encounter any difficulty during the process!